Reading 12 volt battery using an esp32

Hello there i was hoping someone could advise me on if there is coding in Arduino to measure car 12 volt battery which can reach voltage levels of 15.0 or more , so far i have connected a voltage detection module to an esp32wifi on the 5 volt pin and the reading i am getting at the serial monitor is 5.24 .

so if there a code that needs to go into arduino to show me the correct voltage

thanks

You need to reduce the voltage that the Arduino checks. A voltage divider is a simple way to do this.

Vin = 15v, R1=20k, R2=10k ==> Vout = 5v.

Once you have reduced the voltage you can use analogRead() to check the voltage. This will return a value between (0 and 1023)... representing 0v and Vcc of the Arduino... and all the values in between.

With a bit of simple maths you can work out the voltage of the 12v battery.

I use the following code to read 12V battery V's with a ESP32.

#include <driver/adc.h>
#include <SimpleKalmanFilter.h>

void setup()
{
  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);// using GPIO 36 battery volts
}

void fReadBattery( void * parameter )
{
  float adcValue = 0.0f;
  const float r1 = 50500.0f; // R1 in ohm, 50K
  const float r2 = 10000.0f; // R2 in ohm, 10k potentiometer
  float Vbatt = 0.0f;
  int printCount = 0;
  float vRefScale = (3.3f / 4096.0f) * ((r1 + r2) / r2);
  uint64_t TimePastKalman  = esp_timer_get_time(); // used by the Kalman filter UpdateProcessNoise, time since last kalman calculation
  SimpleKalmanFilter KF_ADC_b( 1.0f, 1.0f, .01f );
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 1000; //delay for mS
  for (;;)
  {
    adc1_get_raw(ADC1_CHANNEL_0); //read and discard
    adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading
    KF_ADC_b.setProcessNoise( (esp_timer_get_time() - TimePastKalman) / 1000000.0f ); //get time, in microsecods, since last readings
    adcValue = KF_ADC_b.updateEstimate( adcValue ); // apply simple Kalman filter
    Vbatt = adcValue * vRefScale;
    xSemaphoreTake( sema_CalculatedVoltage, portMAX_DELAY );
    CalculatedVoltage = Vbatt;
    xSemaphoreGive( sema_CalculatedVoltage );
    
      printCount++;
      if ( printCount == 3 )
      {
      //log_i( "Vbatt %f", Vbatt );
      printCount = 0;
      }
    
    TimePastKalman = esp_timer_get_time(); // time of update complete
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    //log_i( "fReadBattery %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
}

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/dac.html

Voltage Divider Calculator <<< Use 10K for R2, 3.3V for the output V's.

@johnnyregs this is a question, the section you posted in is not for posting questions, it is for posting beginners tutorials. I have moved your post here. Please be more careful where you post in future.

thanks very much

1 Like

thanks for your help

Can you please check my coding as my serial monitor reading is not the same as my voltmeter

What coding?

Post your coding in code tags.

Post your schematic.

Post images of your project.

Hi, @johnnyregs

Please read the post at the start of any forum , entitled "How to use this Forum".

This will help with advice on how to present your code and problems.

Thanks... Tom.. :smiley: :+1: :coffee: :australia:

to get the exact same reading, there are two methodes: 1- adjust the value of the devider... If you use a potentiometer, you can turn it so that the value reads the same.
2- adjust the factor in your code:
const float r1 = 50500.0f;
const float r2 = 10000.0f;
change one (or both) values, regardless of the values in your devider)
float vRefScale = (3.3f / 4096.0f) * ((r1 + r2) / r2);
or change one of the values here.. say if you change 4096 to 4200 it will read a lower(?) value..

This coding, cross post has been reported;
https://forum.arduino.cc/t/code-help-with-my-battery-readings-with-an-esp32/990992/6

Tom... :smiley: :coffee: :australia: :+1:

Hello everyone please can you take a look at this coding which is reading two 12 volt car batteries as the end readings showing on the serial monitor are not as accurate as the voltage reading i am getting from my voltmeter , thanks

#include <WiFi.h>
#include "ThingSpeak.h"

#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

float adc_voltage = 0.0;
float adc_voltage1 = 0.0;
float R1 = 30000.0;
float R2 = 7500.0;
float ref_voltage = 17.0;
float adc_value = 0;

WiFiClient client;

unsigned long myChannelNumber = 1714718;
const char * myWriteAPIKey = "9U3QMIMX97S6QCUE";

// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;

unsigned long lastTime1 = 0;
unsigned long timerDelay1 = 30000;

#include "BluetoothSerial.h"

int fl=0;
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run make menuconfig to and enable it
#endif
String ssid="BTBHub6-36JX"; // your network SSID (name)
String password="FUqJi7uU7AJE";

char* ssid1="Raheem";
char* password1="kolachi";
BluetoothSerial SerialBT;

void setup() {
Serial.begin(9600); //Initialize serial
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client);
SerialBT.begin("Boat"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
pinMode(33,OUTPUT);
pinMode(32,OUTPUT);
delay(5000);

//blue();
}

void blue(){
Serial.println("Enter wifi Name");
ab:
digitalWrite(33,HIGH);
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
ssid =SerialBT.readString();
Serial.print(ssid);

}
else {
goto ab;
}

Serial.println("Enter password");
ac:
digitalWrite(33,LOW);
digitalWrite(32,HIGH);
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
password =SerialBT.readString();
Serial.print(password);
fl=1;
}
else {
goto ac;
}

}

void battery1(){
update1:
adc_value = analogRead(35);
Serial.print("b1");
Serial.println(adc_value); // lets assume
adc_voltage = (adc_value * ref_voltage) / 4096.0;

Serial.println(adc_voltage);
if ((millis() - lastTime) > timerDelay) {

// Connect or reconnect to WiFi
if(WiFi.status() != WL_CONNECTED){
  digitalWrite(33,HIGH);
  digitalWrite(32,HIGH);
  Serial.print("Attempting to connect");
  while(WiFi.status() != WL_CONNECTED){
    WiFi.begin(ssid.c_str(), password.c_str()); 
    delay(5000);
    if(WiFi.status() != WL_CONNECTED){
      Serial.println("Enter correct wifi and pass");
      //blue();
    }
  } 
  Serial.println("\nConnected.");
}
delay(1000);
int x = ThingSpeak.writeField(myChannelNumber, 1,adc_voltage, myWriteAPIKey);


if(x == 200){
  digitalWrite(33,LOW);
  digitalWrite(32,LOW);
  Serial.println("Channel update successful.");
}
else{
  Serial.println("Problem updating channel. HTTP error code " + String(x));
  goto update1;
}
lastTime = millis();

}

}

void battery2(){
update2:

adc_value = analogRead(34);
Serial.print("b2");
Serial.println(adc_value);
adc_voltage1 = (adc_value * ref_voltage) / 4096.0;
Serial.println(adc_voltage1);
if ((millis() - lastTime1) > timerDelay1) {

// Connect or reconnect to WiFi
if(WiFi.status() != WL_CONNECTED){
  Serial.print("Attempting to connect");
  while(WiFi.status() != WL_CONNECTED){
    WiFi.begin(ssid.c_str(), password.c_str());  
    delay(5000);  
     if(WiFi.status() != WL_CONNECTED){
      Serial.println("Enter correct wifi and pass");
     // blue();
    }   
  } 
  Serial.println("\nConnected.");
}
delay(1000);
int z = ThingSpeak.writeField(myChannelNumber, 2,adc_voltage1, myWriteAPIKey);


if(z == 200){
  digitalWrite(33,LOW);
  digitalWrite(32,LOW);
  Serial.println("Channel 2 update successful.");
}
else{
  Serial.println("Problem updating channel 2. HTTP error code " + String(z));
  goto update2;
}
lastTime1 = millis();

}
}

void loop() {
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
char fl =SerialBT.read();
delay(5000);
if (fl=='2'){
blue();
}

}
battery1();
delay(1000);
battery2();
delay(1000);
}

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

ok no problem will my post still be live

I do not know what you mean by this

The easiest way to add the code tags is to right click in the IDE and select "Copy for Forum". This will copy the code to the clipboard and add the code tags. Start a new reply here and paste the code, complete with code tags

should i delete the post and start again

Hi, @johnnyregs
No, just put your code in a new post in this thread.
Can you please post a circuit diagram too?

Tom... :smiley: :+1: :coffee:

NO - follow the advice given

You could add code tags to your original post but don't let's complicate things. Just post it again in code tags

Hi,
Is this associated with this;

Tom... :smiley: :+1: :coffee: :australia: