I need to monitor battery voltage to check weather my charging system is working correctly or not. But to do that i have get up and walk with my multimeter towards the battery and i have to take these reading in night.
I placed my battery in a corner where there is very little light. So I added a transistor switch which can be controlled using Bluetooth to turn on the led light. Which provides enough light to act as a night light.
The ESP32 also has an ADC built into it. Which is very poor in terms of accuracy. It gets you the idea that there is something to work with but it does not give very precise reading like a multimeter.
Also, the ESP32 ADC is non-linear. The ADC also has an attenuation feature. Which by default is set to 11db. which gives us a workable range of up to 3.3V. But there are flat-out regions which need to be taken into account if you want to measure anything from this ADC. There is a 0 – 0.2V region in which the value read is constant, and there is a 2.9V to 3.3V region which also gives you constant reading values.
Resolution is 12-bit by default.
To measure a large voltage using this device. I made a voltage divider.
Battery +ve———/\/\/ R1 \/\/\/ ———— Vout —————— /\/\/\/\/ R2 \/\/\/\/ ———-GND
R1 = 10 kilo Ohm
R2 = 1 kilo Ohm
Which gives me a dividing factor of 11.
So if 11 V is available at the battery anode. Then the V out is 1V.
Normally the lead acid battery voltage goes from 10V(fully discharged) to 14.6V(Maximum charge) to 15V(Over Charged)
The ADC values are converted to battery voltage using the following equation
( (analogValue * (3.3/4096 ) ) * ((9820+985)/985) ) + 3.3
#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
char var1;
int analogValue;
uint8_t i;
int avg_adc;
void setup()
{
Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
Serial.println("pair it with bluetooth!");
pinMode(2, OUTPUT);
}
void loop()
{
/*
* UART
*/
if (Serial.available()) {
SerialBT.write(Serial.read());
}
/*
* Bluetooth serial
*/
if (SerialBT.available()) {
var1 = SerialBT.read();
Serial.write(var1);
}
if (var1 == '9')
{
digitalWrite(2,HIGH);
}
else if(var1 == '1')
{
digitalWrite(2,LOW);
}
avg_adc = 0;
for(i =0 ; i< 100; i++)
{
avg_adc += analogRead(34);
}
analogValue = avg_adc / 100;
SerialBT.printf("ADC = %d\n",analogValue);
SerialBT.printf("volt = %f\n", ( (analogValue * (3.3/4096 ) ) * ((9820+985)/985) ) + 3.3 ) ;
delay(1000);
}
Since the ADC is not accurate it goes all over the place. To dampen its effect on the reading I am averaging 100 readings of ADC.
avg_adc = 0;
for(i =0 ; i< 100; i++)
{
avg_adc += analogRead(34);
}
analogValue = avg_adc / 100;
TIP3055 BJT is used as a low-side switch. R1 gives a base current of 330uA(=3.3/10000) which gets multiplied by the beta or hFE 70 of transistor to get a collector current of 0.023A or 23mA.
Leave a Reply