AnalogRead not working properly on 3.3v board (Temp sensor library)

Hi guys, im a bit stuck and need a fresh pair of eyes to check this out.

I have created my own version of an NTC temperature sensor library with lookup table matching my sensor.
Everything is working fine on my UNO, however when I try to run the code on my ESP32 i dont get correct readings. I assume its either a problem with the higher resolution or the lower voltage.

The original lib also has the same problem, even though the owner of the original lib has made accomodations for ESP32 boards.

The readings are way out, basically stuck at 127 degrees. If i force 10 bit resolution it gets better, but still way too high.

Im stuck, and not sure exactly what I missed.

Here is the repo:

Another small note, when running this code on my UNO I noticed I have to set the analog pin high in void setup in order to get an accurate reading, otherwise the readings are about 6-7 degrees too high, not sure if its related in any way, but something I would also like to adress.

Thanks

of course the transformation from a digital-bitvalue depends on two things:

reference-voltage that the adc can measure
and the bit-resolution.
So if the library has the bit-resolution or the reference-voltage hardcoded the results will be wrong.

I don't have all these numbers for different cases in my head. I would have to take a sheet of paper and a pen to analyse and calculate it:

analog-voltage = Reference-Voltage / maxADC-Value * measuredADC-Value

As an example:
reference-voltage = 3.3V
Bitresolution 10 bit = maxADC-value = 2^10 - 1 = 1023

connect ADC-input to a voltage of exact half the reference-voltage
reference-voltage 3.3V measured-ADC 1.65V (which is 3.3V / 2)

this will equal to half of the ADC-max-value 1023 / 2 = 512
analog-voltage = Reference-Voltage / maxADC-Value * measuredADC-Value
1.65V = 3.3 / 1024 * 512

So if you add two parameters reference-voltage and bit-resolution to your begin-function or the constructor
it can be easily adapted.

If you would like to use integer-math then you should do the calculation-sequence in an order
that keeps the numbers high
unsigned longs can hold numbers up to 2^32 -1 = 4.294.967.295 range of 1*10^9

so multiplying the reference-voltage 3.3 with 10 millions 33_000_000 dividing by 1023
33_000_000 / 1023 = 32258.064 Integer 32_258

multiply with measured ADC-value 512

32_580 * 512 = 16516096 which is the voltage of 1.65V scaled up by the initial factor of 10 millions 1.65V

16_516_096 / 10_000_000 = 1.6516096

best regards Stefan

Hi, thanks for the reply.

Here is whats going on in the lib

float TS_NTC_103::getTemp(int reading){//input a bitrade value from analog input
	float Vin = 0;
	Vin = reading*_vRef/_RESO;	//find voltage in the input
	float r = (Vin / (_vRef - Vin) * rRef); //calculate the resistance
	//find between resistance in the table
	int i = 0;
	while(resistance[i]<r)i++;	
	//find m and b value of y=mx+b ==>	
	float m = (temp_C[i]-temp_C[i-1])/(resistance[i]-resistance[i-1]);// m = (y1-y2)/(x1-x2)	
	float b = temp_C[i-1]-(m*resistance[i-1]);//find b = y1 - m*x1*/
	float temp = m*r+b; //y=mx+b
	return temp;

I have changed the following to match my ESP32

class TS_NTC_103 {
private:
	//lookup table
	const float resistance[39];
	const int16_t temp_C[39];
	float _vRef = 3.3;
	int _RESO = 4095;

Still showing about 127 degrees c (sensor responds to temperature)

Something isnt quite right with the code, just cant figure out what

Just an update, I was using pin 2 on the ESP32uno, I switched to pin 36 and everything works on the THERMISTOR lib, however using my lib im reding about 10 degrees too high.

Any ideas? Have i messed up the code somewhere? Or does it look like a hardware issue?

I still haven't finished develop my glas-sphere to present solutions.
So the very best idea I can up with is:

post as many details as you can to enable others to analyse

best regards Stefan

	//find m and b value of y=mx+b ==>	
	float m = (temp_C[i]-temp_C[i-1])/(resistance[i]-resistance[i-1]);// m = (y1-y2)/(x1-x2)	
	float b = temp_C[i-1]-(m*resistance[i-1]);//find b = y1 - m*x1*/
	float temp = m*r+b; //y=mx+b

This seems to be assuming that the mapping from resistance to temperature is linear. It isn't for any thermistor I know of. Most libraries use the Steinhart-Hart equation. There are calculators online for calculating the equation constants for your thermistor give three pairs of temperature/resistance.

Just an update, I was using pin 2 on the ESP32uno, I switched to pin 36 and everything works on the THERMISTOR lib,

FYI, please also have a look at

  1. HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)
  2. Can't use analogRead in ESP_WiFiManager Library

johnwasser:

	//find m and b value of y=mx+b ==>	
float m = (temp_C[i]-temp_C[i-1])/(resistance[i]-resistance[i-1]);// m = (y1-y2)/(x1-x2)	
float b = temp_C[i-1]-(m*resistance[i-1]);//find b = y1 - m*x1*/
float temp = m*r+b; //y=mx+b


This seems to be assuming that the mapping from resistance to temperature is linear. It isn't for any thermistor I know of. Most libraries use the Steinhart-Hart equation. There are calculators online for calculating the equation constants for your thermistor give three pairs of temperature/resistance.

But the specific resistances at varying temperatures are defined in the lookup table?

mickymik:
But the specific resistances at varying temperatures are defined in the lookup table?

Ah! I didn't notice that before doing the linear interpolation is was doing a search. My mistake.