Får inte till temperaturläsning

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Lehto
Inlägg: 17
Blev medlem: 5 februari 2021, 15:55:24

Får inte till temperaturläsning

Inlägg av Lehto »

Tjenare.

Håller på med Arduino UNO och har köpt följande sensor:
https://www.turbozentrum.de/Oil-tempera ... -Zada-Tech

Det som är trevligt är att den redan är specad som ni kan se, men för att slippa visa temp i steg om 10*C så använder jag mig utav stainhart-hart ekvationen.
Dock tycker jag inte att temperaturen stämmer riktigt och undrar om det beror på "min" kod, eller om jag tänker fel på hur jag koppla det?
Infogar koden här:

Kod: Markera allt

// include the library code:
#include <LiquidCrystal.h>
#define coolantsensorDivider 1580   //defines the resistor value that is in series in the voltage divider
#define coolantsensorPin A1         //defines the analog pin of the input voltage from the voltage divider
#define NUMSAMPLES 5                //defines the number of samples to be taken for a smooth average

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
const int pressureInput = A0; //select the analog input pin for the pressure transducer
const int pressureZero = 102.4; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxBAR = 10.34213594; //bar value of transducer being used
//const int pressuretransducermaxPSI = 150; //psi value of transducer being used
const int baudRate = 9600; //constant integer to set the baud rate for serial monitor
const int sensorreadDelay = 250; //constant integer to set the sensor read delay in milliseconds

float pressureValue = 0; //variable to store the value coming from the pressure transducer

const float steinconstA = 0.00145540155933184000000;  //steinhart equation constant A, determined from wikipedia equations
const float steinconstB = 0.00024370391733452000000;  //steinhart equation constant B, determined from wikipedia equations
const float steinconstC = 0.00000017594920712227100;  //steinhart equation constant C, determined from wikipedia equations

int samples[NUMSAMPLES];                              //variable to store number of samples to be taken

void setup() {
  Serial.begin(baudRate); //initializes serial communication at set baud rate bits per second
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  //lcd.print("Oljetryck: ");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  pressureValue = analogRead(pressureInput); //reads value from input pin and assigns to variable
  pressureValue = ((pressureValue-pressureZero)*pressuretransducermaxBAR)/(pressureMax-pressureZero); //conversion equation to convert analog reading to psi
  pressureValue = (pressureValue/14.503773773); //to Bar
  Serial.print(pressureValue, 1); //prints value from previous line to serial
  Serial.println("bar"); //prints label to serial
  lcd.setCursor(0, 0); //sets cursor to column 0, row 0
  lcd.print("Oljetryck: "); //prints label
  lcd.print(pressureValue, 1); //prints pressure value to lcd screen, 1 digit on float
  lcd.print(" B"); //prints label after value
  lcd.print("   "); //to clear the display after large values or negatives
  delay(sensorreadDelay); //delay in milliseconds between read values

  uint8_t i;                                          //integer for loop
  float average;                                      //decimal for average
  
  for (i=0; i<NUMSAMPLES; i++) {                      
    samples[i] = analogRead(coolantsensorPin);        //takes samples at number defined with a short delay between samples
    delay(10);
  }

  average = 0;
  for (i=0; i< NUMSAMPLES; i++) {
    average += samples[i];                            //adds all number of samples together
  }
  average /= NUMSAMPLES;                              //divides by number of samples to output the average

  Serial.print("Average Analog Coolant Reading = ");
  Serial.println(average);                                        //analog value at analog pin into arduino
  average = (coolantsensorDivider*average)/(1023-average);        //conversion equation to read resistance from voltage divider
  Serial.print("Coolant Sensor Resistance = ");
  Serial.println(average);

  float steinhart;                              //steinhart equation to estimate temperature value at any resistance from curve of thermistor sensor
  steinhart = log(average);                     //lnR
  steinhart = pow(steinhart,3);                 //(lnR)^3
  steinhart *= steinconstC;                     //C*((lnR)^3)
  steinhart += (steinconstB*(log(average)));    //B*(lnR) + C*((lnR)^3)
  steinhart += steinconstA;                     //Complete equation, 1/T=A+BlnR+C(lnR)^3
  steinhart = 1.0/steinhart;                    //Inverse to isolate for T
  steinhart -= 273.15;                          //Conversion from kelvin to celcius

  Serial.print("Temperature = ");
  Serial.print(steinhart);                      //prints final temp in celcius
  Serial.println(" *C");
  lcd.setCursor(0, 1);
  lcd.print("Oljetemp :");
  lcd.print(steinhart, 1);
  lcd.print(" C");
  lcd.print("   "); //to clear the display after large values or negatives
  
  delay(1000);                                  //delay between readings
}
Har även skapat en spänningsdelare där av #define coolantsensorDivider 1580 och jag har då ett motstånd på 1580ohm. Är detta vettigt?
Fick tipset att mäta restistans på givaren vid rumstemperatur och fick då ut 1600ohm, och tipset jag fick är att använda samma resistans i första motståndet.
Och ja jag har även en tryckgivare inkopplad som körs mot samma Arduino UNO.

Kan det vara så att UNO inte klarar av att leverera 5V till både tryck och tempgivare + LCD display?
Vore det bättre att mata tempgivaren med 3,3V? Vad behöver jag ändra i koden isf?
Jag kan inte så mycket själv och har mest kollat på exempel online så kanske är koden jag klippt ihop helt åt pipan?

Har även testat att köra med ett 9V batteri bara för att vara säker att Arduinon får tillräckligt med in-spänning

Tacksam för hjälp, och saknas någon info tvekan inte att fråga.
svanted
Inlägg: 5084
Blev medlem: 30 augusti 2010, 21:20:38
Ort: Umeå

Re: Får inte till temperaturläsning

Inlägg av svanted »

average = (coolantsensorDivider*average)/(1023-average); //conversion equation to read resistance from voltage divider

är fel, vet inte vad den räknar ut?
Användarvisningsbild
pi314
Inlägg: 5829
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Får inte till temperaturläsning

Inlägg av pi314 »

Lehto skrev: 17 juli 2023, 01:34:56 Tjenare.

...

Tacksam för hjälp, och saknas någon info tvekan inte att fråga.
Hur exakt har du kopplat ihop temperaturgivaren, motstånden och Arduinoingången?
Rita gärna ett enkelt schema.

Var har du hittat konstanterna i Steinhart-ekvationerna för din givare?
Kanske har jag räknat fel, men för mig ser dom inte ut att stämma för din givare.

Får du rätt värde, vid en viss temperatur, från utskriften "Coolant Sensor Resistance = "?

/Pi
Användarvisningsbild
4kTRB
Inlägg: 18402
Blev medlem: 16 augusti 2009, 19:04:48

Re: Får inte till temperaturläsning

Inlägg av 4kTRB »

Ta fram kurvan för resistansändringen och ta fram en kurvanpassad formel.
Användarvisningsbild
pi314
Inlägg: 5829
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Får inte till temperaturläsning

Inlägg av pi314 »

4kTRB:

De är det som Steinhart-ekvationen, som Lehto använder i programmet gör.

Men, om du menar att det kan göras enklare, så håller jag med.

Så här ser sambandet mellan T och R ut, grafiskt.
23-07-17_T_R.png
Om man inte ser upp kan man få dålig noggrannhet runt 100°C. Även om Lehto inte berättat vad han ska använda temperaturinformationen till, så gissar jag att han vill ha skaplig noggrannhet runt 100°C.

Så här ser sambandet mellan T och ln(R) ut grafliskt.
230717_T-ln(R).png
Om man tar kurvan med T och ln(R) och anpassar ett andragradspolynom till den så tror jag att det gott och väl blir nära nog. Även om Steinhart-ekvationen i teorin ska kunna ge bättre noggrannhet så tvivlar jag på att det blir bättre i praktiken. Med tanke på alla inblandade felkällor. Om sedan konstanterna i Steinhart-ekvationen inte är exakta för den aktuella givaren (det aktuella exemplaret) så ger det också ett sämre resultat.

/Pi
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
pi314
Inlägg: 5829
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Får inte till temperaturläsning

Inlägg av pi314 »

Lehto:

Om mina slutsatser baserade på tidigare inlägg är korrekta så handlar det om en B230-motor.

Då antar jag att noggrannheten i den övre delen av termstorns temperaturintervall är viktigast. Kanske runt 60-90°C?

/Pi
Lehto
Inlägg: 17
Blev medlem: 5 februari 2021, 15:55:24

Re: Får inte till temperaturläsning

Inlägg av Lehto »

pi314 skrev: 17 juli 2023, 08:51:43
Lehto skrev: 17 juli 2023, 01:34:56 Tjenare.

...

Tacksam för hjälp, och saknas någon info tvekan inte att fråga.
Hur exakt har du kopplat ihop temperaturgivaren, motstånden och Arduinoingången?
Rita gärna ett enkelt schema.

Var har du hittat konstanterna i Steinhart-ekvationerna för din givare?
Kanske har jag räknat fel, men för mig ser dom inte ut att stämma för din givare.

Får du rätt värde, vid en viss temperatur, från utskriften "Coolant Sensor Resistance = "?

/Pi
Hejsan,

tack för ditt engagemang och hjälp! Det är som du säger en oljetemperaturgivare, ska ha det till min motor Volvo 850. Vet inte exakt var tempen kommer ligga men generellt så är det väl i det högre spannet som är av intresse.
Bilen körs enbart sommartid och jag vet ju redan när jag startar den att oljan är typ 20-30 grader så de är ju ointressant, utan är mer att veta när oljan blivit varm och att den inte blir för varm. Så kanske 70-120*C

Här är ett schema på hur jag kopplat det på min "breadboard", hoppas den går att förstå:


Jag har även använt ett excel sheet som jag hitta online för att få till steinhart-hart ekvationen, där jag fyllt i värden för min givare:
https://docs.google.com/spreadsheets/d/ ... ue&sd=true

Därav så tror jag mig ha fått ut rätt värden, också när jag kollar på lite online clacs så verkar dem bekräfta det.

Måste kolla vad jag får för värde vid utskriften.
Lehto
Inlägg: 17
Blev medlem: 5 februari 2021, 15:55:24

Re: Får inte till temperaturläsning

Inlägg av Lehto »

svanted skrev: 17 juli 2023, 06:47:20 average = (coolantsensorDivider*average)/(1023-average); //conversion equation to read resistance from voltage divider

är fel, vet inte vad den räknar ut?
Intressant att du nämner just denna kodrad, då det är den jag själv är lite förbryllad över också.
Du säger att den är fel, hur kan du se det?

Jag läser in 5 analoga värden från PIN A1 som givaren är kopplad på, delar det värdet på 5 och stoppar i average.
Sedan görs uträkningen enligt ovan för att få ut resistansen.

Det som jag är osäker om är hur jag vet att sensorn har 1023 värden? Eller borde det vara 1024?
Vem är det som bestämmer spannet, är det givaren eller Arduinon?
Användarvisningsbild
pi314
Inlägg: 5829
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Får inte till temperaturläsning

Inlägg av pi314 »

Jag har inte tittat på ditt ark för att beräkna konstanterna i Steinhart-ekvationen ännu.
Jag började med att göra en beräkning av vad vi bör få in på A1 på Arduinon och vad det blir när det A/D-omvandlats. Det är resultatet av A/D-omvandlingen, ett heltal mellan 0 och 1023 (eller egentligen 25 och 791 i ditt fall) som ska räknas om till ett R.
TRV (med 1580)Efter A/D
053903,867791
1033503,398695
2022202,921598
3013762,327476
409151,834375
506601,473301
604741,154236
703400,885181
802510,685140
901860,527108
1001390,40483
1101100,32567
120840,25252
130640,19540
140510,15632
150400,12325
I det här kodavsnittet:

Kod: Markera allt

Serial.print("Average Analog Coolant Reading = ");
  Serial.println(average);                                        //analog value at analog pin into arduino
  average = (coolantsensorDivider*average)/(1023-average);        //conversion equation to read resistance from voltage divider
  Serial.print("Coolant Sensor Resistance = ");
  Serial.println(average);

Ser det ut som om du räknar om A/D-värdet till ett värde på R?

Heltalet som kommer från A/D bör bli v = 1023 * R / (R + 1580)

Eller: R * v + 1580 * v = 1023 * R => R = 1580*v/(1023-v)

Din beräkning är rätt, såvitt jag kan se. Att det är rätt bör vara enkelt för dig att kolla, genom att kolla utskriften från kodraderna ovan. Jämför med tabellen ovan.

/Pi
svanted
Inlägg: 5084
Blev medlem: 30 augusti 2010, 21:20:38
Ort: Umeå

Re: Får inte till temperaturläsning

Inlägg av svanted »

det är ju helt rätt, fel av mig...
ställer mig i skamvrån...
Användarvisningsbild
Glenn
Inlägg: 33835
Blev medlem: 24 februari 2006, 12:01:56
Ort: Norr om Sthlm
Kontakt:

Re: Får inte till temperaturläsning

Inlägg av Glenn »

Nu hanske du har tillräcklig beräkningskapacitet i din MCU, men kan du inte bara lägga en tabell istället för att slippa räkna hela tiden ? det blir ju max 1024 värden du behöver slå upp, och troligen inte ens det..
Lehto
Inlägg: 17
Blev medlem: 5 februari 2021, 15:55:24

Re: Får inte till temperaturläsning

Inlägg av Lehto »

pi314 skrev: 17 juli 2023, 12:52:05 Jag har inte tittat på ditt ark för att beräkna konstanterna i Steinhart-ekvationen ännu.
Jag började med att göra en beräkning av vad vi bör få in på A1 på Arduinon och vad det blir när det A/D-omvandlats. Det är resultatet av A/D-omvandlingen, ett heltal mellan 0 och 1023 (eller egentligen 25 och 791 i ditt fall) som ska räknas om till ett R.
TRV (med 1580)Efter A/D
053903,867791
1033503,398695
2022202,921598
3013762,327476
409151,834375
506601,473301
604741,154236
703400,885181
802510,685140
901860,527108
1001390,40483
1101100,32567
120840,25252
130640,19540
140510,15632
150400,12325
I det här kodavsnittet:

Kod: Markera allt

Serial.print("Average Analog Coolant Reading = ");
  Serial.println(average);                                        //analog value at analog pin into arduino
  average = (coolantsensorDivider*average)/(1023-average);        //conversion equation to read resistance from voltage divider
  Serial.print("Coolant Sensor Resistance = ");
  Serial.println(average);

Ser det ut som om du räknar om A/D-värdet till ett värde på R?

Heltalet som kommer från A/D bör bli v = 1023 * R / (R + 1580)

Eller: R * v + 1580 * v = 1023 * R => R = 1580*v/(1023-v)

Din beräkning är rätt, såvitt jag kan se. Att det är rätt bör vara enkelt för dig att kolla, genom att kolla utskriften från kodraderna ovan. Jämför med tabellen ovan.

/Pi
Jag gjorde en liten förändring som verkade ge mig bättre värden, såg att Arduinon har 2st GND "slots", tidigare hade jag bara en GND dragen till "breadboarden" men nu drog jag en till från andra GND slotten också till "breadboarden" och nu får jag lite bättre värden iaf.

Utskrifterna jag får är följande:
Average Analog Coolant Reading = 512.80
Coolant Sensor Resistance = 1588.05
Temperature = 27.87 *C

Och min grilltermometer säger 24.6*C (och är rätt säker att jag inte har en inomhustemperatur på nästan 28*C, då litar jag mer på grilltermometern då ~24*C är ungefärlig temperatur här hemma.
svanted
Inlägg: 5084
Blev medlem: 30 augusti 2010, 21:20:38
Ort: Umeå

Re: Får inte till temperaturläsning

Inlägg av svanted »

mät spänningen över sensorn och räkna fram resistansen, och jämför med det värde som den skriver ut:
så vet du om det är matematiken eller elektroniken som är fel.
Användarvisningsbild
pi314
Inlägg: 5829
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: Får inte till temperaturläsning

Inlägg av pi314 »

Lehto:

Det låter ju som det där värdet är lite högt. Å andra sidan är det i ett temperaturområde som inte är det viktigaste.
Kanske ca 3°C fel i rumstemperatur inte är så farligt? Kanske går det att kalibrera så att felet blir mindre?
Har du allt i labbet eller sitter något i bilen?
Hur exakt är motståndet på 1580 ohm?

Om du har temperaturgivaren i labbet kan du ju testa att stoppa den i kokande vatten och se vilka värden du får då.

En liten överslags "felkalkyl" vid 100°C...

Då bör du få 139 ohm i sensorn.
Om 5 volt är exakt 5 volt och motståndet är exakt 1580 ohm och om givaren är exakt så bör det då vara 5 * 139 / (139+1580) = 0,4043 volt in på A2. Under förutsättning att det då är exakt 139,0 ohm i givaren. Kan du mäta hur bra motståndet är och hur exakt givaren är?

Så här ser upplösningen ut runt 100°C:
TV(A1)efter A/D
99°C0,41785
100°C0,40483
101°C0,39781
Vi ser att A/D-ns upplösning motsvarar ca 0,5°C runt 100°C. Lägg ihop alla felkällor så är det nog svårt att få bättre noggrannhet än ett par grader.

Vi måste ha med oss att det finns ett antal felkällor här. 5-volt, motståndet, NTC-motståndet, brus, störningar och A/D-omvandlaren. Alla felkällor bidrar till att du inte får ett exakt värde, men om du kan kalibrerar så kan du nog komma ganska nära.

Om du vill komma närmare ett exakt värde med kalibrering så skulle jag rekommendera att kalibrera i programvaran. Kanske räcker det med en kalibreringspunkt, t.ex. 100°C, kokande vatten?

Några fler funderingar.
– Kanske kan du få ett bättre värde genom att medelvärdesbilda fler A/D-omvandlingar? T.ex. 25 i stället för 5.
– Steinhart-ekvationen, om parametrarna är rätt, är nog det bästa du kan använda för omräkningen från R till T.
– Övriga felkällor, som fel i termistorn, resistansen, brus/störningar, jordfel, 5-volt, m.m. bör man nog titta på.
– I bilen ska du nog ha en skärmad kabel mellan temperaturgivaren och Arduinon. Det finns mycket som kan störa där.

/Pi
Lehto
Inlägg: 17
Blev medlem: 5 februari 2021, 15:55:24

Re: Får inte till temperaturläsning

Inlägg av Lehto »

Tja,

jag börjar nästan tro att det är min breadboard som är kass eller dålig kvalitet på kablarna, vickar jag lite på +5v i breadboarden så rör sig tempen väldigt mycket.
Kanske bara måste realisera detta och göra ordentlig permanent montering så kanske det blir bra!

Iom att detta är mitt första projekt så har jag väldigt dålig koll på vad det finns för grejer, nu kanske ni som hållt på ett tag inte kör med Arduino UNO?
Men hur gör man på bästa sätt för att permanenta en lösning? Jag skulle helst vilja löda på kablarna på kortet så man vet det sitter liksom men UNOn har ju PIN hål...
Vet ni något bra å prisvärt case för UNOn också? Vart handlar ni era prylar och tillbehör?

Några tips på skärmadkabel?

Hittade även den här manicken som verkar perfekt för mig då bilen ligger nånstans mellan 13-15v och arduinon klarar max 12v:
https://pchbutik.se/sv/volt-dc-dc/226-j ... m2596.html
Skriv svar