1
- # define VBAT_PIN (A7)
1
+
2
2
#define VBAT_MV_PER_LSB (0 .73242188F ) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
3
+
4
+ #ifdef NRF52840_XXAA // if this is for nrf52840
5
+ #define VBAT_PIN (A6)
6
+ #define VBAT_DIVIDER (0 .5F ) // 150K + 150K voltage divider on VBAT
7
+ #define VBAT_DIVIDER_COMP (2 .0F ) // Compensation factor for the VBAT divider
8
+ #else
9
+ #define VBAT_PIN (A7)
3
10
#define VBAT_DIVIDER (0 .71275837F ) // 2M + 0.806M voltage divider on VBAT = (2M / (0.806M + 2M))
4
11
#define VBAT_DIVIDER_COMP (1 .403F ) // Compensation factor for the VBAT divider
12
+ #endif
5
13
6
- int readVBAT (void ) {
7
- int raw;
14
+ #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
15
+
16
+
17
+ float readVBAT (void ) {
18
+ float raw;
8
19
9
20
// Set the analog reference to 3.0V (default = 3.6V)
10
21
analogReference (AR_INTERNAL_3_0);
@@ -22,38 +33,23 @@ int readVBAT(void) {
22
33
analogReference (AR_DEFAULT);
23
34
analogReadResolution (10 );
24
35
25
- return raw;
36
+ // Convert the raw value to compensated mv, taking the resistor-
37
+ // divider into account (providing the actual LIPO voltage)
38
+ // ADC range is 0..3000mV and resolution is 12-bit (0..4095)
39
+ return raw * REAL_VBAT_MV_PER_LSB;
26
40
}
27
41
28
42
uint8_t mvToPercent (float mvolts) {
29
- uint8_t battery_level;
30
-
31
- if (mvolts >= 3000 )
32
- {
33
- battery_level = 100 ;
34
- }
35
- else if (mvolts > 2900 )
36
- {
37
- battery_level = 100 - ((3000 - mvolts) * 58 ) / 100 ;
38
- }
39
- else if (mvolts > 2740 )
40
- {
41
- battery_level = 42 - ((2900 - mvolts) * 24 ) / 160 ;
42
- }
43
- else if (mvolts > 2440 )
44
- {
45
- battery_level = 18 - ((2740 - mvolts) * 12 ) / 300 ;
46
- }
47
- else if (mvolts > 2100 )
48
- {
49
- battery_level = 6 - ((2440 - mvolts) * 6 ) / 340 ;
50
- }
51
- else
52
- {
53
- battery_level = 0 ;
54
- }
55
-
56
- return battery_level;
43
+ if (mvolts<3300 )
44
+ return 0 ;
45
+
46
+ if (mvolts <3600 ) {
47
+ mvolts -= 3300 ;
48
+ return mvolts/30 ;
49
+ }
50
+
51
+ mvolts -= 3600 ;
52
+ return 10 + (mvolts * 0 .15F ); // thats mvolts /6.66666666
57
53
}
58
54
59
55
void setup () {
@@ -66,23 +62,13 @@ void setup() {
66
62
67
63
void loop () {
68
64
// Get a raw ADC reading
69
- int vbat_raw = readVBAT ();
65
+ float vbat_mv = readVBAT ();
70
66
71
67
// Convert from raw mv to percentage (based on LIPO chemistry)
72
- uint8_t vbat_per = mvToPercent (vbat_raw * VBAT_MV_PER_LSB);
73
-
74
- // Convert the raw value to compensated mv, taking the resistor-
75
- // divider into account (providing the actual LIPO voltage)
76
- // ADC range is 0..3000mV and resolution is 12-bit (0..4095),
77
- // VBAT voltage divider is 2M + 0.806M, which needs to be added back
78
- float vbat_mv = (float )vbat_raw * VBAT_MV_PER_LSB * VBAT_DIVIDER_COMP;
68
+ uint8_t vbat_per = mvToPercent (vbat_mv);
79
69
80
70
// Display the results
81
- Serial.print (" ADC = " );
82
- Serial.print (vbat_raw * VBAT_MV_PER_LSB);
83
- Serial.print (" mV (" );
84
- Serial.print (vbat_raw);
85
- Serial.print (" ) " );
71
+
86
72
Serial.print (" LIPO = " );
87
73
Serial.print (vbat_mv);
88
74
Serial.print (" mV (" );
0 commit comments