Skip to content

Commit 7fe2161

Browse files
committed
fix some error
1 parent 78332f8 commit 7fe2161

File tree

2 files changed

+411
-0
lines changed

2 files changed

+411
-0
lines changed
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
#include "voltmeter.h"
2+
#include "Wire.h"
3+
4+
void Voltmeter::i2cBegin() {
5+
// Wire.begin();
6+
}
7+
8+
bool Voltmeter::i2cReadBytes(uint8_t addr, uint8_t reg_addr, uint8_t* buff, uint16_t len) {
9+
Wire.beginTransmission(addr);
10+
Wire.write(reg_addr);
11+
uint8_t i = 0;
12+
if (Wire.endTransmission(false) == 0 && Wire.requestFrom(addr, (uint8_t)len)) {
13+
while (Wire.available()) {
14+
buff[i++] = Wire.read();
15+
}
16+
return true;
17+
}
18+
19+
return false;
20+
}
21+
22+
bool Voltmeter::i2cWriteBytes(uint8_t addr, uint8_t reg_addr, uint8_t* buff, uint16_t len) {
23+
bool function_result = false;
24+
25+
Wire.beginTransmission(addr);
26+
Wire.write(reg_addr);
27+
for(int i = 0; i < len; i++) {
28+
Wire.write(*(buff+i));
29+
}
30+
function_result = (Wire.endTransmission() == 0);
31+
return function_result;
32+
}
33+
34+
bool Voltmeter::i2cReadU16(uint8_t addr, uint8_t reg_addr, uint16_t* value) {
35+
uint8_t read_buf[2] = {0x00, 0x00};
36+
bool result = i2cReadBytes(addr, reg_addr, read_buf, 2);
37+
*value = (read_buf[0] << 8) | read_buf[1];
38+
return result;
39+
}
40+
41+
bool Voltmeter::i2cWriteU16(uint8_t addr, uint8_t reg_addr, uint16_t value) {
42+
uint8_t write_buf[2];
43+
write_buf[0] = value >> 8;
44+
write_buf[1] = value & 0xff;
45+
return i2cWriteBytes(addr, reg_addr, write_buf, 2);
46+
}
47+
48+
float Voltmeter::getResolution(voltmeterGain_t gain) {
49+
switch (gain) {
50+
case PAG_6144:
51+
return ADS1115_MV_6144 / VOLTMETER_PRESSURE_COEFFICIENT;
52+
case PAG_4096:
53+
return ADS1115_MV_4096 / VOLTMETER_PRESSURE_COEFFICIENT;
54+
case PAG_2048:
55+
return ADS1115_MV_2048 / VOLTMETER_PRESSURE_COEFFICIENT;
56+
case PAG_1024:
57+
return ADS1115_MV_1024 / VOLTMETER_PRESSURE_COEFFICIENT;
58+
case PAG_512:
59+
return ADS1115_MV_512 / VOLTMETER_PRESSURE_COEFFICIENT;
60+
case PAG_256:
61+
return ADS1115_MV_256 / VOLTMETER_PRESSURE_COEFFICIENT;
62+
default:
63+
return ADS1115_MV_256 / VOLTMETER_PRESSURE_COEFFICIENT;
64+
};
65+
}
66+
67+
uint8_t Voltmeter::getPGAEEEPROMAddr(voltmeterGain_t gain) {
68+
switch (gain) {
69+
case PAG_6144:
70+
return VOLTMETER_PAG_6144_CAL_ADDR;
71+
case PAG_4096:
72+
return VOLTMETER_PAG_4096_CAL_ADDR;
73+
case PAG_2048:
74+
return VOLTMETER_PAG_2048_CAL_ADDR;
75+
case PAG_1024:
76+
return VOLTMETER_PAG_1024_CAL_ADDR;
77+
case PAG_512:
78+
return VOLTMETER_PAG_512_CAL_ADDR;
79+
case PAG_256:
80+
return VOLTMETER_PAG_256_CAL_ADDR;
81+
default:
82+
return 0x00;
83+
};
84+
}
85+
86+
uint16_t Voltmeter::getCoverTime(voltmeterRate_t rate) {
87+
switch (rate) {
88+
case RATE_8:
89+
return 1000 / 8;
90+
case RATE_16:
91+
return 1000 / 16;
92+
case RATE_32:
93+
return 1000 / 32;
94+
case RATE_64:
95+
return 1000 / 64;
96+
case RATE_128:
97+
return 1000 / 128;
98+
case RATE_250:
99+
return 1000 / 250;
100+
case RATE_475:
101+
return 1000 / 475;
102+
case RATE_860:
103+
return 1000 / 860;
104+
default:
105+
return 1000 / 128;
106+
};
107+
}
108+
109+
Voltmeter::Voltmeter(uint8_t ads1115_addr, uint8_t eeprom_addr) {
110+
_ads1115_addr = ads1115_addr;
111+
_eeprom_addr = eeprom_addr;
112+
_gain = PAG_2048;
113+
_mode = SINGLESHOT;
114+
_rate = RATE_128;
115+
calibration_factor = 1;
116+
adc_raw = 0;
117+
resolution = getResolution(_gain);
118+
cover_time = getCoverTime(_rate);
119+
}
120+
121+
void Voltmeter::setGain(voltmeterGain_t gain) {
122+
uint16_t reg_value = 0;
123+
bool result = i2cReadU16(_ads1115_addr, ADS1115_RA_CONFIG, &reg_value);
124+
125+
if (result == false) {
126+
return;
127+
}
128+
129+
reg_value &= ~(0b0111 << 9);
130+
reg_value |= gain << 9;
131+
132+
result = i2cWriteU16(_ads1115_addr, ADS1115_RA_CONFIG, reg_value);
133+
134+
if (result) {
135+
_gain = gain;
136+
resolution = getResolution(gain);
137+
int16_t hope = 1;
138+
int16_t actual = 1;
139+
if (readCalibrationFromEEPROM(gain, &hope, &actual)) {
140+
calibration_factor = (double)hope / actual;
141+
}
142+
}
143+
}
144+
145+
void Voltmeter::setRate(voltmeterRate_t rate) {
146+
uint16_t reg_value = 0;
147+
bool result = i2cReadU16(_ads1115_addr, ADS1115_RA_CONFIG, &reg_value);
148+
if (result == false) {
149+
return;
150+
}
151+
152+
reg_value &= ~(0b0111 << 5);
153+
reg_value |= rate << 5;
154+
155+
result = i2cWriteU16(_ads1115_addr, ADS1115_RA_CONFIG, reg_value);
156+
157+
if (result) {
158+
_rate = rate;
159+
cover_time = getCoverTime(_rate);
160+
}
161+
162+
return;
163+
}
164+
165+
void Voltmeter::setMode(voltmeterMode_t mode) {
166+
uint16_t reg_value = 0;
167+
bool result = i2cReadU16(_ads1115_addr, ADS1115_RA_CONFIG, &reg_value);
168+
if (result == false) {
169+
return;
170+
}
171+
172+
reg_value &= ~(0b0001 << 8);
173+
reg_value |= mode << 8;
174+
175+
result = i2cWriteU16(_ads1115_addr, ADS1115_RA_CONFIG, reg_value);
176+
if (result) {
177+
_mode = mode;
178+
}
179+
180+
return;
181+
}
182+
183+
bool Voltmeter::isInConversion() {
184+
uint16_t value = 0x00;
185+
i2cReadU16(_ads1115_addr, ADS1115_RA_CONFIG, &value);
186+
187+
return (value & (1 << 15)) ? false : true;
188+
}
189+
190+
void Voltmeter::startSingleConversion() {
191+
uint16_t reg_value = 0;
192+
bool result = i2cReadU16(_ads1115_addr, ADS1115_RA_CONFIG, &reg_value);
193+
194+
if (result == false) {
195+
return;
196+
}
197+
198+
reg_value &= ~(0b0001 << 15);
199+
reg_value |= 0x01 << 15;
200+
201+
i2cWriteU16(_ads1115_addr, ADS1115_RA_CONFIG, reg_value);
202+
}
203+
204+
float Voltmeter::getVoltage(bool calibration) {
205+
if (calibration) {
206+
return resolution * calibration_factor * getConversion() * VOLTMETER_MEASURING_DIR;
207+
} else {
208+
return resolution * getConversion() * VOLTMETER_MEASURING_DIR;
209+
}
210+
}
211+
212+
int16_t Voltmeter::getAdcRaw() {
213+
uint16_t value = 0x00;
214+
i2cReadU16(_ads1115_addr, ADS1115_RA_CONVERSION, &value);
215+
adc_raw = value;
216+
return value;
217+
}
218+
219+
int16_t Voltmeter::getConversion(uint16_t timeout) {
220+
if (_mode == SINGLESHOT) {
221+
startSingleConversion();
222+
delay(cover_time);
223+
uint64_t time = millis() + timeout;
224+
while (time > millis() && isInConversion());
225+
}
226+
227+
return getAdcRaw();
228+
}
229+
230+
bool Voltmeter::EEPORMWrite(uint8_t address, uint8_t* buff, uint8_t len) {
231+
return i2cWriteBytes(_eeprom_addr, address, buff, len);
232+
}
233+
234+
bool Voltmeter::EEPORMRead(uint8_t address, uint8_t* buff, uint8_t len) {
235+
return i2cReadBytes(_eeprom_addr, address, buff, len);
236+
}
237+
238+
bool Voltmeter::saveCalibration2EEPROM(voltmeterGain_t gain, int16_t hope, int16_t actual) {
239+
if (hope == 0 || actual == 0) {
240+
return false;
241+
}
242+
243+
uint8_t buff[8];
244+
memset(buff, 0, 8);
245+
buff[0] = gain;
246+
buff[1] = hope >> 8;
247+
buff[2] = hope & 0xFF;
248+
249+
buff[3] = actual >> 8;
250+
buff[4] = actual & 0xFF;
251+
252+
for (uint8_t i = 0; i < 5; i++) {
253+
buff[5] ^= buff[i];
254+
}
255+
256+
uint8_t addr = getPGAEEEPROMAddr(gain);
257+
return EEPORMWrite(addr, buff, 8);
258+
}
259+
260+
bool Voltmeter::readCalibrationFromEEPROM(voltmeterGain_t gain, int16_t* hope, int16_t* actual) {
261+
uint8_t addr = getPGAEEEPROMAddr(gain);
262+
uint8_t buff[8];
263+
memset(buff, 0, 8);
264+
265+
*hope = 1;
266+
*actual = 1;
267+
268+
bool result = EEPORMRead(addr, buff, 8);
269+
270+
if (result == false) {
271+
return false;
272+
}
273+
274+
uint8_t xor_result = 0x00;
275+
for (uint8_t i = 0; i < 5; i++) {
276+
xor_result ^= buff[i];
277+
}
278+
279+
if (xor_result != buff[5]) {
280+
return false;
281+
}
282+
283+
*hope = (buff[1] << 8) | buff[2];
284+
*actual = (buff[3] << 8) | buff[4];
285+
return true;
286+
}

0 commit comments

Comments
 (0)