NTC temperatuur sensor uitlezen ESP32

Hallo,

Ik heb een probleem om mijn temperatuur sensor uit te kunnen lezen op mijn ESP32.
Ik lees een ntc sensor uit via mijn ADC pin. Middels de steinhart methode heb ik het een en ander ingesteld. De sensor moet van 0 tot 250 uit kunnen lezen.
Alle daarbij behorende weerstanden (stappen van 5 graden) heb ik zorgvuldig gemeten met daadwerkelijk die temperatuur.

Dit heeft goed gewerkt op een Atmega328 alleen nu dus verder met een ESP32.

Heeft iemand hier ervaring mee?

Tot 130 graden gaat het goed echter dan gaat hij enorm schommelen. (aantal graden).

ESP32_ntc_test.ino (3.9 KB)

Is het een lineaire of niet lineaire NTC?

Je kunt je sketch tussen drie backslash-single-quotes zetten.

```
Je sketch
```

De ADC van de ESP32 is nu eenmaal slecht. Al je werk om die tabel te maken en de getallen er uit te destileren gaat daarmee verloren. Bij een ESP32 wordt vaak een externe ADC gebruikt.

Hier staat die inmiddels bekende overdrachtsgrafiek (onder het kopje " ADC is Non-linear"): https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/

Heb je bij 25 °C een weerstand van 84 kΩ gemeten ? Ik weet niet of er een 84k NTC bestaat. Als ik andere getallen uit je tabel op die website invul, dan komt er soms uit dat het een 75k NTC is. Dat lijkt me logischer.
Kies de waarde van de weerstand hetzelfde als die van de NTC bij dat aantal graden.
Stel je wilt de meeste nauwkeurigheid bij 100 °C, dan kies je ongeveer 7k voor de weerstand.

niet lineair

Ja dat had ik al begrepen maar dan nog zou het redelijk moeten lukken toch? Ik heb het idee dat er iets niet goed gaat.

Ik heb net nog een keer goed gemeten en ik meet 93K bij 25 graden om precies te zijn.

Ik wil de temperatuur van 0 tot 180 gebruiken ongeveer. bij 50 graden moet hij het meest accuraat zijn.
Toen ik hem op een Uno had draaien had ik over de gehele band geen afwijking of onnauwkeurigheid.
Wellicht doe ik iets fout in de code?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//float SteinhartHart_rFood, SteinhartHart_rDome;
float Steinhart_rFood, Steinhart_rDome;

LiquidCrystal_I2C lcd(0x27, 16, 2);

int adcFood;
int adcDome;
int rFood;
int rDome;

// Measured values of the "bb-22" temp probe
const float measured_T[] =
{0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250};
const float measured_R[] =
{270E+3, 205E+3, 165E+3, 134E+3, 105E+3, 84E+3, 67.7E+3, 53E+3, 43E+3, 36.8E+3, 31.1E+3, 25.4E+3, 19, 7E+3, 16.2E+3, 12.7E+3, 11.2E+3, 10.2E+3, 9E+3, 8E+3, 7.2E+03, 6.7E+03, 4.55E+03, 4.2E+03, 3.6E+03, 3.15E+03, 2.75E+3, 2.41E+3, 2.12E+3, 1.85E+3, 1.62E+3, 1.43E+3, 1.26E+3, 1.1E+3, 980, 880, 780, 700, 615, 550, 495, 450, 405, 370, 330, 300, 275, 250, 230, 215, 200, 185};

// Using: http://www.thinksrs.com/downloads/programs/Therm%20Calc/NTCCalibrator/NTCcalculator.htm
const float A = 0.9382E-3;
const float B = 1.804E-4;
const float C = 2.2348E-7;
const float beta = 3874.89; // This is the 'beta', not the 'B'.

// The resistance at 25 degrees is also taken from that thinksrs page.
const float ntc_nominal_T = 25.0;
const float ntc_nominal_R = 91312.23; // It is probably a 210k NTC resistor

// Pins
const int probeFoodPin = 33;
const int probeDomePin = 34;

// Values for the series resistor to 5V
const float series_resistor = 22E+3; // 22k



void setup()
{
  Serial.begin(115200);


  lcd.begin();
  lcd.setCursor(5, 0);
  lcd.print("Hello");
  Serial.println("Hello" );
  delay(2000);
  lcd.setCursor(5, 1);
  lcd.print("World");
  Serial.println("World" );
  delay(3000);
  lcd.clear();

  for (int i = 0; i < sizeof(measured_T) / sizeof(float); i++)
  {
    // Calculate what the ADC value would be with this resistor value.
    // Simulate the ADC, by rounding to lower integer with floor().
    float adc = floor(measured_R[i] / (measured_R[i] + series_resistor) * 4095.0);

    // Calculate the resistance value of the NTC thermistor
    float r = series_resistor / ((4096.0 / (adc + 0.5)) - 1.0);
  }

}




void loop()
{
  // Calculate the resistance value of the NTC thermistor
  float adcFood = getADC(probeFoodPin);
  float adcDome = getADC(probeDomePin);

  rFood = series_resistor / ((4096.0 / (adcFood + 0.5)) - 1.0);
  rDome = series_resistor / ((4096.0 / (adcDome + 0.5)) - 1.0);

  delay(75);


  lcd.setCursor(4, 0);
  lcd.print("   ");
  lcd.setCursor(5, 0);
  lcd.print("\337C");
  lcd.setCursor(14, 0);
  lcd.print("\337C");
  lcd.setCursor(4, 1);
  lcd.print("  ");
  lcd.setCursor(5, 1);
  lcd.print("\337C");
  lcd.setCursor(15, 1);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("23");
  lcd.print("  ");

  Serial.print("Food: ");
  Serial.println(adcFood);
  Serial.print("Dome: ");
  Serial.println(adcDome);

  if (adcFood < 10.0 || adcFood > 3900.0)
  { //4021
    lcd.setCursor(9, 0);
    lcd.print("---");
    lcd.print("  ");
  }
  else
  {
    lcd.setCursor(9, 0);
    lcd.print(SteinhartHart(rFood), 1);
    lcd.print(" ");
  }

  if (adcDome < 10.0 || adcDome > 3900.0)
  { //4021
    lcd.setCursor(0, 0);
    lcd.print("---");
    lcd.print(" ");
  }
  else
  {
    lcd.setCursor(0, 0);
    lcd.print(SteinhartHart(rDome), 0);
    lcd.print("  ");
  }



}

float getADC(int pin)
{
  // About 60 samples fit into a unsigned int.
  // Therefor the 'n' should be not above 60.
  int n = 20; // maximum 60
  unsigned int total = 0;
  for (int i = 0; i < n; i++)
  {
    total += analogRead(pin);
  }
  float adc = (float)total / (float)n;
  return (adc);
}

float SteinhartHart(float r)
{
  float t1 = log(r);
  float t2 = C * t1 * t1 * t1;
  float t3 = A + (B * log(r)) + t2;
  return ((1.0 / t3) - 273.15) - 4.0;
}

De Arduino Uno heeft een hele goede 10-bit ADC. In de praktijk blijkt hij zelfs nog beter te zijn. Het blijft natuurlijk een 10-bit ADC, maar hij is vanaf 0V al perfect en heel lineair.

Ik zie geen probleem in de code. Je laat de ruwe adcFood en adcDome zien in de seriële monitor. Zie je daar iets vreemds aan ? Als die in de buurt van 100 of 4000 komen, dan is het resultaat niet meer te vertrouwen.

Je kunt dit proberen met een paar verschillende weerstanden in de plaats van de NTC. Dan weet je het snel genoeg.

De NTC+weerstand dienen gevoed te worden vanaf de 3.3V pin, niet vanaf de 5V pin. Heb je dat ?

Op basis van je andere metingen en hoe de curve past, lijkt mij een NTC van 75k voor de hand liggen. Je meet nu 93k. Zit er ergens een slecht contact, of is er ergens water in gekomen ? Kun je nog eens met de Uno meten ? Des te langer ik er over nadenk, des te meer het lijkt op een probleem bij de NTC zelf, bijvoorbeeld een onstabiele waarde bij kokend water.

Hallo Koepel, Bedankt voor je snelle antwoorden. Dat waardeer ik enorm!

Ik heb het met meerdere ntc's geprobeerd. het zijn van die voedsel probe's.
Ik voed hem met 3.3V en dat is hij ook perfect!
Wel gebruik ik een 22k Weerstand in het project is dat een probleem?

Ik meet bij 88 graden een waarde van 1080 (ADC)
En bij 13 graden een waarde van 3490

Ik heb even voor de zekerheid met een andere temperatuurmeter ernaast de boel even goed nagekeken. Zaten her en der wel wat verschilletjes.

Dit is de nieuwe code:

// Measured values of the "bb-22" temp probe
const float measured_T[] =
{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250};
const float measured_R[] =//nieuw vandaag
{300E+3, 213E+3, 130E+3, 83.1E+3, 45.2E+3, 38.5E+3, 26.3E+3, 18.8E+3, 13.81E+3, 9.61E+3, 6.71E+3, 5.00E+03, 3.78E+03, 2.92E+03, 2.25E+03, 1.75E+03, 1.39E+03, 1.11E+03, 887, 715, 585, 476, 400, 330, 275, 230};

const float A = 0.7804E-3;//0.9382E-3;
const float B = 2.0332E-4;//1.804E-4;
const float C = 1.5769E-7;//2.2348E-7;
const float beta = 3873.37; //3874.89; // This is the 'beta', not the 'B'.

// The resistance at 25 degrees is also taken from that thinksrs page.
const float ntc_nominal_T = 25.0;
const float ntc_nominal_R = 91354.85;//84935.34

En nog gaat hij vanaf 140 graden gekke sprongen doen terwijl mijn temperatuur stabiel blijft.
De sensor aan de ESP32 loopt van 150 graden gewoon op richting de 250 terwijl mijn temperatuur stabiel blijft. Ik snap er niks van.

Als ik de ruwe ADC waardes uitlees dan krijg ik dit te zien bij verschillende temperaturen:
(Deze temperaturen had ik zo even snel al klaar staan.)
17 graden = adc 3230
90 graden = adc 912
100 graden = adc 720
110 graden = adc 577
120 graden = adc 452
130 graden = adc 360
140 graden = adc 282

De meest voor de hand liggende conclusie is dat de ADC van de ESP32 raar is :crazy_face:

Ik heb wel ergens een ESP32 liggen, maar helaas heb ik op dit moment geen tijd om het zelf te testen. Iedereen weet dat de ADC van de ESP32 niet goed is. Er werd zelfs over gedacht om binnen de analogRead() een correctie aan te brengen om er nog iets van te maken.

Dat is mooi balen dan :thinking:
Ik heb een project ermee opgezet en alles gereed. Nu kwam ik met uitgebreider testen erachter dat hij boven de 140 graden zo vreemd ging doen.

Opzich niet zo'n heel groot probleem maar tot die 140 deed hij gewoon hetzelfde als op een Uno dus nooit naar gekeken.
Ik zou eigenlijk wel temperaturen van boven die 140 willen kunnen meten.

Dan raad ik je aan om een externe module (klik !) te proberen.
Ik wijs naar die fabrikant omdat die erg goed zijn in ondersteunen van hun oplossingen, maar ongetwijfeld kun je hetzelfde resultaat ook via een Chinese webshop op de kop tikken.
Kijk ook even verder op die pagina, wellicht staat daar een ander/goedkoper product gemeld dat ook aan jouw wensen zou kunnen voldoen.

Ik heb het op kunnen lossen door in de grafiek de 250 graden te veranderen naar 180. Maar de weerstand heb ik laten staan. Vraag me niet hoe maar nu klopt hij precies met een geijkte meter ernaast.

Dus ik zat er helemaal naast ? Ik wist niet dat die formule zo instabiel was. Gelukkig werkt het nu :smiley:

Misschien dat je met een afronding van de 'float' te maken kreeg. De ESP32 heeft natuurlijk ook 'double'. Misschien is het een combinatie van dingen.

Nou dat weet ik dus niet koepel.

Jouw formule werkt op alle andere chips perfect die ik tot nu toe getest heb.

Ik weet dat een esp32 een adc heeft van 0 - 4095.
Ik heb bij een temperatuur van 17 graden een waarde van 3230. Ik krijg problemen bij ongeveer 150 graden (afwijkingen).
Daar heb ik een adc waarde van rond de 200.

Hoe kan ik dit aanpassen? Want ik heb het idee dat ik gewoon buiten mijn bereik zit van mijn waarde...

Het meest nauwkeurig en de beste resolutie krijg je als de weerstand dezelfde waarde heeft als de NTC, dus als de analog ingang een spanning zo ongeveer in het midden heeft.

Bij 200°C heeft de NTC 300 Ω ? Dan kun je eens proberen met een weerstand van 300 of 330 Ω en in je sketch de 'series_resistor' aanpassen.

Misschien wordt het dan onstabiel bij 25°C :face_with_raised_eyebrow:

Dat is een veel te groot bereik voor een thermistor.
En een te hoge temperatuur voor een halfgeleider sensor.

Een platinum RTD (PT100/PT1000) met digitale interface is de beste oplossing.
Leo..

De Sensor is juist geschikt voor 0 -250 graden die ik gebruik.