1- # define VBAT_PIN (A7)
1+
22#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)
310#define VBAT_DIVIDER (0 .71275837F ) // 2M + 0.806M voltage divider on VBAT = (2M / (0.806M + 2M))
411#define VBAT_DIVIDER_COMP (1 .403F ) // Compensation factor for the VBAT divider
12+ #endif
513
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;
819
920 // Set the analog reference to 3.0V (default = 3.6V)
1021 analogReference (AR_INTERNAL_3_0);
@@ -22,38 +33,23 @@ int readVBAT(void) {
2233 analogReference (AR_DEFAULT);
2334 analogReadResolution (10 );
2435
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;
2640}
2741
2842uint8_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
5753}
5854
5955void setup () {
@@ -66,23 +62,13 @@ void setup() {
6662
6763void loop () {
6864 // Get a raw ADC reading
69- int vbat_raw = readVBAT ();
65+ float vbat_mv = readVBAT ();
7066
7167 // 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);
7969
8070 // 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+
8672 Serial.print (" LIPO = " );
8773 Serial.print (vbat_mv);
8874 Serial.print (" mV (" );
0 commit comments