-
Notifications
You must be signed in to change notification settings - Fork 117
/
Read_Battery_Level.ino
163 lines (132 loc) · 3.64 KB
/
Read_Battery_Level.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
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
159
160
161
162
163
/**
* @file Read_Battery_Level.ino
* @author Bernd Giesecke (bernd.giesecke@rakwireless.com)
* @brief Read charging level from a battery connected to the RAK5005-O base board
* Setup and main loop
* @version 0.1
* @date 2020-08-21
*
* @copyright Copyright (c) 2020
*
* @note RAK4631 GPIO mapping to nRF52840 GPIO ports
RAK4631 <-> nRF52840
WB_IO1 <-> P0.17 (GPIO 17)
WB_IO2 <-> P1.02 (GPIO 34)
WB_IO3 <-> P0.21 (GPIO 21)
WB_IO4 <-> P0.04 (GPIO 4)
WB_IO5 <-> P0.09 (GPIO 9)
WB_IO6 <-> P0.10 (GPIO 10)
WB_SW1 <-> P0.01 (GPIO 1)
WB_A0 <-> P0.04/AIN2 (AnalogIn A2)
WB_A1 <-> P0.31/AIN7 (AnalogIn A7)
*/
#include <Arduino.h>
#include <bluefruit.h>
#define PIN_VBAT WB_A0
uint32_t vbat_pin = PIN_VBAT;
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12 - bit ADC resolution = 3000mV / 4096
#define VBAT_DIVIDER_COMP (1.73) // Compensation factor for the VBAT divider, depend on the board
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#include <bluefruit.h>
void ble_init();
extern bool g_bleUARTisConnected;
extern BLEUart g_bleUart;
char g_bleString[256] = {0};
void initDisplay(void);
void dispAddLine(char *line);
char g_dispText[256] = {0};
/**
* @brief Get RAW Battery Voltage
*/
float readVBAT(void)
{
float raw;
// Get the raw 12-bit, 0..3000mV ADC value
raw = analogRead(vbat_pin);
return raw * REAL_VBAT_MV_PER_LSB;
}
/**
* @brief Convert from raw mv to percentage
* @param mvolts
* RAW Battery Voltage
*/
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
}
/**
* @brief get LoRaWan Battery value
* @param mvolts
* Raw Battery Voltage
*/
uint8_t mvToLoRaWanBattVal(float mvolts)
{
if (mvolts < 3300)
return 0;
if (mvolts < 3600)
{
mvolts -= 3300;
return mvolts / 30 * 2.55;
}
mvolts -= 3600;
return (10 + (mvolts * 0.15F)) * 2.55;
}
void setup()
{
initDisplay();
Serial.begin(115200);
dispAddLine("Waiting for Serial");
time_t serialTimeout = millis();
while (!Serial)
{
delay(10); // for nrf52840 with native usb
if ((millis() - serialTimeout) > 5000)
{
break;
}
}
Serial.println("=====================================");
Serial.println("RAK4631 Battery test");
Serial.println("=====================================");
// Start BLE
dispAddLine("Init BLE");
ble_init();
// 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 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
snprintf(g_dispText, 255, "%.3fV \t %d%%", vbat_mv / 1000, vbat_per);
dispAddLine(g_dispText);
Serial.print("LIPO = ");
Serial.print(vbat_mv);
Serial.print(" mV (");
Serial.print(vbat_per);
Serial.print("%) LoRaWan Batt ");
Serial.println(mvToLoRaWanBattVal(vbat_mv));
if (g_bleUARTisConnected)
{
snprintf(g_bleString, 255, "%.0fmV %d%% %d/255\n", vbat_mv, vbat_per, mvToLoRaWanBattVal(vbat_mv));
g_bleUart.print(g_bleString);
}
delay(1000);
}