ATM/lib/AD5593R/AD5593R.h

207 lines
7.2 KiB
C
Raw Normal View History

2023-08-07 12:34:14 +00:00
/*
This library is for the AD5593R by analog instruments please refer to the datasheet
https://www.analog.com/media/en/technical-documentation/data-sheets/AD5593R.pdf
The AD5593R is a powerful 12-bit configurable DAC/ADC/GPIO chip connected through an I2C bus.
The chip also has an additional addressing pin dubbed a0, which will change the device's effectively
I2C address, by connecting this pin and specifying its location in the class construction it is possible to
connect several AD5593Rs on the same I2C bus and independently control them.
To enable the ADC/DAC functionality of the chip a reference voltage MUST be set, as all set voltages
must fall into the range 0-Vref, or 0-2xVref if set_(ADC/DAC)_max_2x_Vref is called. If these functions
return negative values please read their description as the cause will be reported by its value.
GPIO capabilities have not yet been added.
Lukas Janavicius, 2019
For contact information, projects, or more about me, please visit my GitHub or website linked below.
Janavicius.org
https://github.com/LukasJanavicius
*/
//////Definitions and imports//////
// To enable debugging please place the following before the library import,
// and be sure to use Serial.begin() in the setup.
// AD5593R_DEBUG
#pragma once
2023-08-21 09:26:23 +00:00
// comment this line to disable debugging
// #define AD5593R_DEBUG
2023-08-07 12:34:14 +00:00
#ifdef AD5593R_DEBUG
2023-08-21 09:26:23 +00:00
#define AD5593R_PRINT(...) Serial.print(__VA_ARGS__)
#define AD5593R_PRINTLN(...) Serial.println(__VA_ARGS__)
2023-08-07 12:34:14 +00:00
#else
#define AD5593R_PRINT(...)
#define AD5593R_PRINTLN(...)
#endif
#ifndef AD5593R_h
#define AD5593R_h
#endif
#include <Arduino.h>
//////Classes//////
2023-08-21 09:26:23 +00:00
class AD5593R
{
2023-08-07 12:34:14 +00:00
public:
// This configuration structure contains arrays of booleans,
// each array follows the form [channel0,...,channel7]
// where a 1 indicates the channel should be configured as the name implies
// for example an array ADCs[8] = {1,1,0,0,0,0,0,0} will configure channels 0 and 1 as ADCs.
// a declaration of this structure should be defined in your code, and passed into configure().
// You should not double assign pins, as only the first declaration will be assigned.
2023-08-21 09:26:23 +00:00
struct configuration
{
bool ADCs[8]; // ADC pins
bool DACs[8]; // DAC pins
bool GPIs[8]; // input pins
bool GPOs[8]; // output pins
2023-08-07 12:34:14 +00:00
};
configuration config;
// This structure contains arrays of
2023-08-21 09:26:23 +00:00
struct Read_write_values
{
2023-08-07 12:34:14 +00:00
float ADCs[8];
float DACs[8];
bool GPI_reads[8];
bool GPO_writes[8];
};
Read_write_values values;
// constructor for the class, a0 is the digital pin connected to the AD5593R
// if no pin is specified it is assumed only one AD5593R is connected
AD5593R(int a0 = -1, int I2C_SDA = 34, int I2C_SCL = 35);
// enables the internal reference voltage of 2.5 V
void enable_internal_Vref();
// disables the internal reference voltage of 2.5 V
void disable_internal_Vref();
// sets the maximum ADC input to 2x Vref
void set_ADC_max_2x_Vref();
// sets the maximum ADC input to 1x Vref
void set_ADC_max_1x_Vref();
// sets the maximum DAC output to 2x Vref
void set_DAC_max_2x_Vref();
// sets the maximum DAC output to 2x Vref
void set_DAC_max_1x_Vref();
// If you use an external reference voltage you should call this function. Failure to set the reference voltage,
// or enable the internal reference will mean that any DAC/ADC function call will result in an error!
void set_Vref(float Vref);
2023-08-21 09:26:23 +00:00
// configures the selected channel as a DAC
2023-08-07 12:34:14 +00:00
void configure_DAC(byte channel);
2023-08-21 09:26:23 +00:00
void configure_DACs(bool *channels);
2023-08-07 12:34:14 +00:00
// Sets the output voltage value of a given channel, returns 1 if the write is completed
// if the function returns -1 if the specified channel is not an DAC,
// if no reference voltage is specified a -2 will be returned,
// and if the voltage exceeds the maximum allowable voltage a -3 will be returned.
int write_DAC(byte channel, float voltage);
2023-08-21 09:26:23 +00:00
void write_DACs(float *voltages);
2023-08-07 12:34:14 +00:00
2023-08-21 09:26:23 +00:00
// configures the selected channel as a ADC
2023-08-07 12:34:14 +00:00
void configure_ADC(byte channel);
2023-08-21 09:26:23 +00:00
void configure_ADCs(bool *channels);
2023-08-07 12:34:14 +00:00
// Reads the voltage value of a given ADC channel, returns the Voltage if the write is completed
// if the function returns -1 if the specified channel is not an ADC,
// and if no reference voltage is specified a -2 will be returned.
2023-08-21 09:26:23 +00:00
float read_ADC(byte channel, int averages = 1);
2023-08-07 12:34:14 +00:00
2023-08-21 09:26:23 +00:00
float *read_ADCs();
2023-08-07 12:34:14 +00:00
void configure_GPI(byte channel);
2023-08-21 09:26:23 +00:00
void configure_GPIs(bool *channels);
2023-08-07 12:34:14 +00:00
void configure_GPO(byte channel);
2023-08-21 09:26:23 +00:00
void configure_GPOs(bool *channels);
2023-08-07 12:34:14 +00:00
2023-08-21 09:26:23 +00:00
bool *read_GPIs();
void write_GPOs(bool *pin_states);
2023-08-07 12:34:14 +00:00
/*
// By passing in the configuration structure this function assigns the functionality
// to each pin, as described in the configuration. As stated above, you should not
// assign multiple functionalities to a single pin. In this event the function will return
// -1 and print an error if debug is enabled. A 1 will be returned if the configuration is successful
int configure_pins(*configuration config);
//call this function in
void update(DAC_Writes[8],ADC_Reads[8]);
// performs a software reset, generally a good idea to call in the setup
void reset();
// Reads the set value of a given DAC channel, -1 will be returned if
float read_DAC(int channel);
//This follows the same functionality as read_ADC(), but instead of reading from a single channel
//the configuration is passed in, so that all of the ADCs are read.
// In order to extract the values read you should pass in your Read_write_values struct.
float read_DACs(int channels[8], *Read_write_values output);
//power down a specific channel, if none is specified all channels are powered down.
void power_down(int channel = -1);
*/
private:
// checks if the given channel is configured as an ADC
// returns 1 if the channel is configured, 0 if the channel is not
bool is_ADC(int channel);
// checks if the given channel is configured as a DAC
// returns 1 if the channel is configured, 0 if the channel is not
bool is_DAC(int channel);
// pointers for configuring the control registers, refer to the data sheet for functionality
// These structures are adapted from
// https://github.com/MikroElektronika/HEXIWEAR/blob/master/SW/Click%20Examples%20mikroC/examples/ADAC/library/__ADAC_Driver.h
int _num_of_channels = 8;
int _a0;
2023-08-21 09:26:23 +00:00
// general purpose control register data Bytes
2023-08-07 12:34:14 +00:00
byte _GPRC_msbs;
byte _GPRC_lsbs;
// power control register data bytes;
byte _PCR_msbs;
byte _PCR_lsbs;
byte _DAC_config;
byte _ADC_config;
byte _GPI_config;
byte _GPO_config;
2023-08-21 09:26:23 +00:00
// default address of the AD5593R, multiple devices are handled by setting the desired device's a0 to LOW
// by default the a0 pin will be pulled high, effectively changing its address. For more information on the addressing please
// refer to the data sheet in the introduction
2023-08-07 12:34:14 +00:00
byte _i2c_address = 0x10;
2023-08-21 09:26:23 +00:00
// Value of the reference voltage, if none is specified then all ADC/DAC functions will throw errors
2023-08-07 12:34:14 +00:00
float _Vref = -1;
2023-08-21 09:26:23 +00:00
// flag for 2xVref mode
2023-08-07 12:34:14 +00:00
bool _ADC_2x_mode = 0;
2023-08-21 09:26:23 +00:00
// flag for 2xVref mode
2023-08-07 12:34:14 +00:00
bool _DAC_2x_mode = 0;
float _ADC_max = -1;
float _DAC_max = -1;
};