Car Voltage Monitoring with Arduino/esp32

Hello,

I plan to use the ADC of my esp32 with Arduino IDE to measure the voltages of a car batterie. Those are in my case typically between 8 and 15 Volts.
Due to the limited resolution of the built-in ADC of the ESP, I think it would make sense to somehow transfer only the 8-15 interval to 0-3.3 of the esp, instead of the whole 0-15 interval.

I know that I generally need a voltage divider for the purpose of mapping the higher battery voltage to the lower ESP one. My problem is figuring out how to add that offset of 8V to the system...

And in case it would be recommendable, do I need any electronic parts to protect my esp from way possible overload currents or something like that?

The ESP32 has a 12bit AtoD thingie.

Bypassing the Arduino analog thingies and using the ESP32 ADC API is the first start in getting stable AtoD readings from an ESP32

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

Here is one of my codes, an edit of the AudioAnalyzer library, using the ESP32 ADC API.

/*
AudioAnalyzer.cpp - Library for audio spectrum analyzer.
Created by Lauren Pan,Dec 5, 2012.
E-Mail: Lauren.pan@dfrobot.com

Version 1.3

Log:
2012.12.05
Improve the code to make it compatible with the Arduino IDE 1.0 or later

2010.11.06
Add optional analog pin
*/
#include <driver/adc.h> // added the esp32 adc api
#include "AudioAnalyzer.h"
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

/**************************** Init Analyzer connecter Pin ****************************/
Analyzer::Analyzer(void)
{
	_StrobePin = 4;
	_RSTPin = 5;
	_DCPin = 0;
}

Analyzer::Analyzer(int StrobePin,int RstPin,int AnalogPin)
{
	_StrobePin = StrobePin;
	_RSTPin = RstPin;
	_DCPin = AnalogPin;
 // set up A:D channels
  adc1_config_width(ADC_WIDTH_12Bit); // esp32 api adc setup
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); // esp32 GPIO36
}

void Analyzer::Init()
{
	pinMode(_StrobePin,OUTPUT);
	pinMode(_RSTPin,OUTPUT);
	RstModule();
}
/**************************** Reset analyzer module ****************************/
void Analyzer::RstModule()
{
	digitalWrite(_StrobePin,LOW);
	digitalWrite(_RSTPin,HIGH);
	digitalWrite(_StrobePin,HIGH);
	digitalWrite(_StrobePin,LOW);
	digitalWrite(_RSTPin,LOW);
	delayMicroseconds(72);  
}

/**************************** Read DC out value ****************************/
void Analyzer::ReadFreq(int *value)
{
	static boolean RstState = false;
	if(!RstState)
	{
		_TimepointSt = millis();
		RstState = true;
	}
	else
	{
		_TimepointNow = millis();
		if(_TimepointNow - _TimepointSt > 3000)
		{
			RstModule();
			RstState = false;
			//Serial.println("Rst");
		}
	}

	for(byte band = 0;band<Maxband;band++)
	{
		delayMicroseconds(10);
    
		// value[band] = analogRead(_DCPin);
value[band] = adc1_get_raw(ADC1_CHANNEL_0); //using the esp32 api to get a reading
    
		
		delayMicroseconds(50);
		digitalWrite(_StrobePin,HIGH);
		delayMicroseconds(18);
		digitalWrite(_StrobePin,LOW);
	}  
}

Here is a link to a voltage divider math thingie http://www.ohmslawcalculator.com/voltage-divider-calculator

My suggestion is to use a voltage source of 30V, for the car battery, R2 at 10K, and output voltage of 3.3.

Oi! Almost forgot.

Use ESP32 PortB for your AtoD thingies.

PortA or 0 are the first 32 GPIOs and PortB or 1 are the next set of GPIO pins up from PortA. PortB are input only pins and are 'tuned' for AtoD inputs.

Due to the limited resolution of the built-in ADC of the ESP, I think it would make sense to somehow transfer only the 8-15 interval to 0-3.3 of the esp, instead of the whole 0-15 interval.

That shouldn't be necessary. With 12-bits (and 15V = 4095) you'll get better than 5mV resolution which should be more than enough. In a running car the noise/instability will be greater than 5mV. An offset circuit could end-up adding more error than that!

And if you are below 8V, don't you want to know what the voltage is?

And in case it would be recommendable, do I need any electronic parts to protect my esp from way possible overload currents or something like that?

Yes, it would be a good idea to add a [u]over-voltage protection circuit[/u].

Thanks for all the replies. I use the Arduino IDE which got ESP32 support so codewise its pretty simple I guess.

Regarding the Voltage divider, is there any advantage in using a cascaded one with 2 or more layers in comparison with a single layer one? At the moment I am using a 130K resistor for R1 and a potentiometer which is set to about 36k.

Also thanks for the link with the pin protection. I will build that in :smiley: