forked from mbA2D/A2D_DAQ
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathA2D_DAQ.cpp
158 lines (123 loc) · 3.88 KB
/
A2D_DAQ.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* A2D Electronics 64 Channel Data Acquisition Module Library
* Written By: Micah Black
* Date: Jan 22, 2021
*
*
*
*
*/
#include <A2D_DAQ.h>
//constructor and initialization list
A2D_DAQ::A2D_DAQ(): io({TCA9539(RESET_PIN, INT_PIN, IO_EXP_I2C_ADDR_CH_0_15),
TCA9539(RESET_PIN, INT_PIN, IO_EXP_I2C_ADDR_CH_16_31),
TCA9539(RESET_PIN, INT_PIN, IO_EXP_I2C_ADDR_CH_32_47),
TCA9539(RESET_PIN, INT_PIN, IO_EXP_I2C_ADDR_CH_48_63)}),
mux(EN_PIN, S0_PIN, S1_PIN, S2_PIN, S3_PIN),
adc(ADC_I2C_ADDR)
{
_default_ch_config.channel_dir = A2D_DAQ_INPUT;
_default_ch_config.channel_default_state = A2D_DAQ_LOW;
_A2D_DAQ_read_delay_ms_default = 5;
_A2D_DAQ_read_delay_ms = _A2D_DAQ_read_delay_ms_default;
}
void A2D_DAQ::A2D_DAQ_init()
{
//start I2C communication
Wire.begin();
Wire.setClock(400000);
//set up ADC
adc.begin();
A2D_DAQ_reset();
}
void A2D_DAQ::A2D_DAQ_reset()
{
//LED
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
//set up all 4 IO Expanders
for(int i = 0; i < NUM_IO_EXP; i++)
io[i].TCA9539_init();
//muxes
mux.MUX4067_enable();
//adc
adc.setGain(GAIN_ONE);
//apply default configuration for pins
// - default will be all inputs according to private struct
for(int i = 0; i < NUM_CHANNELS; i++)
A2D_DAQ_config_channel(i, _default_ch_config);
//reset to the default read delay
_A2D_DAQ_read_delay_ms = _A2D_DAQ_read_delay_ms_default;
}
void A2D_DAQ::A2D_DAQ_set_led(bool state)
{
digitalWrite(LED_PIN, state);
}
int16_t A2D_DAQ::A2D_DAQ_get_analog(uint8_t channel)
{
//check valid channel
if (!_A2D_DAQ_valid_channel(channel)) return 0;
//check pin is configured to input using TCA9539 class registers
//won't wreck anyhting if its output, so no need to check
uint8_t io_channel_index = channel / 16;
uint8_t io_channel = channel % 16;
//set mux to correct pin
mux.MUX4067_set_pin(io_channel);
//delay to give small RC filter time to charge
delay(_A2D_DAQ_read_delay_ms);
//read correct ADC channel
return adc.readADC_SingleEnded(io_channel_index);
}
double A2D_DAQ::A2D_DAQ_get_analog_mv(uint8_t channel)
{
return A2D_DAQ_get_analog(channel)*125.0/1000.0;
}
bool A2D_DAQ::A2D_DAQ_get_dig_in(uint8_t channel)
{
//check valid channel
if (!_A2D_DAQ_valid_channel(channel)) return false;
//verify configured as input using TCA9539 class registers
//input resigter ALWAYS reflect the output state so
//we don't need to check
uint8_t io_channel_index = channel / 16;
uint8_t io_channel = channel % 16;
//read value from the input register
return io[io_channel_index].TCA9539_read_pin_val(io_channel);
}
void A2D_DAQ::A2D_DAQ_set_dig_out(uint8_t channel, bool output_val)
{
//check valid channel
if (!_A2D_DAQ_valid_channel(channel)) return;
//verify channel configured as output - TCA9539 class regs
uint8_t io_channel_index = channel / 16;
uint8_t io_channel = channel % 16;
if(!io[io_channel_index].TCA9539_check_pin_dir \
(io_channel, A2D_DAQ_OUTPUT)) return;
TCA9539_pin_val_t output;
output = (output_val == true ? TCA9539_PIN_OUT_HIGH : TCA9539_PIN_OUT_LOW);
//set the output
io[io_channel_index].TCA9539_set_pin_val(io_channel, output);
}
A2D_DAQ_channel_config A2D_DAQ::A2D_DAQ_get_default_config()
{
return _default_ch_config;
}
void A2D_DAQ::A2D_DAQ_set_read_delay_ms(uint16_t read_delay_ms)
{
_A2D_DAQ_read_delay_ms = read_delay_ms;
}
void A2D_DAQ::A2D_DAQ_config_channel(uint8_t channel, A2D_DAQ_channel_config config)
{
//check valid channel
if (!_A2D_DAQ_valid_channel(channel)) return;
//update channel configuration
//set output value on update
uint8_t io_channel_index = channel / 16;
uint8_t io_channel = channel % 16;
io[io_channel_index].TCA9539_set_pin_val(io_channel, config.channel_default_state);
//set channel to input/output
io[io_channel_index].TCA9539_set_dir(io_channel, config.channel_dir);
}
bool A2D_DAQ::_A2D_DAQ_valid_channel(uint8_t channel)
{
return (channel < NUM_CHANNELS);
}