-
Notifications
You must be signed in to change notification settings - Fork 505
/
Copy pathadc_vbat.ino
86 lines (62 loc) · 2.24 KB
/
adc_vbat.ino
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
#include <Arduino.h>
#include <Adafruit_TinyUSB.h> // for Serial
#if defined ARDUINO_NRF52840_CIRCUITPLAY
#define PIN_VBAT A8 // this is just a mock read, we'll use the light sensor, so we can run the test
#endif
uint32_t vbat_pin = PIN_VBAT; // A7 for feather nRF52832, A6 for nRF52840
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
#ifdef NRF52840_XXAA
#define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT
#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider
#else
#define VBAT_DIVIDER (0.71275837F) // 2M + 0.806M voltage divider on VBAT = (2M / (0.806M + 2M))
#define VBAT_DIVIDER_COMP (1.403F) // Compensation factor for the VBAT divider
#endif
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
float readVBAT(void) {
float raw;
// Set the analog reference to 3.0V (default = 3.6V)
analogReference(AR_INTERNAL_3_0);
// Set the resolution to 12-bit (0..4095)
analogReadResolution(12); // Can be 8, 10, 12 or 14
// Let the ADC settle
delay(1);
// Get the raw 12-bit, 0..3000mV ADC value
raw = analogRead(vbat_pin);
// Set the ADC back to the default settings
analogReference(AR_DEFAULT);
analogReadResolution(10);
// Convert the raw value to compensated mv, taking the resistor-
// divider into account (providing the actual LIPO voltage)
// ADC range is 0..3000mV and resolution is 12-bit (0..4095)
return raw * REAL_VBAT_MV_PER_LSB;
}
uint8_t mvToPercent(float mvolts) {
if(mvolts<3300)
return 0;
if(mvolts <3600) {
mvolts -= 3300;
return mvolts/30;
}
mvolts -= 3600;
return 10 + (mvolts * 0.15F ); // thats mvolts /6.66666666
}
void setup() {
Serial.begin(115200);
while ( !Serial ) delay(10); // for nrf52840 with native usb
// Get a single ADC sample and throw it away
readVBAT();
}
void loop() {
// Get a raw ADC reading
float vbat_mv = readVBAT();
// Convert from raw mv to percentage (based on LIPO chemistry)
uint8_t vbat_per = mvToPercent(vbat_mv);
// Display the results
Serial.print("LIPO = ");
Serial.print(vbat_mv);
Serial.print(" mV (");
Serial.print(vbat_per);
Serial.println("%)");
delay(1000);
}