TGS 2602 Kalibrierung-Fehler im Code

Hi,

ich bin neu in der Arduino-Programmierung und möchte ein VOC-Sensorgerät entwickeln. Dafür habe ich ein TGS 2602 von figaro gekauft.
Um diesen Sensor zu Kalibrieren habe ich unter bestimmten Aceton Konzentration die Spannungs- bzw Widerstandswerte ermittelt und in einer Tabelle eingetragen. siehe Anhang.

Anschließend wollte ich diese Werte für die Kalibrierung benutzen. Die verschiedenen R- und ppmWerte werden in Array eingetragen. Um die Zwischenwerten zu berechnen, habe ich die Formal für die Interpolation genutzt.

Der erste Wert, die ich bekomme ist richtig, aber danach funktioniert einfach nichts mehr. Die PPM-Konzentration steigt ab, wenn der Widerstandswert absteigt. (So soll es nicht sein).
Wo liegt das Problem? Welches Fehler habe ich gemacht?

Ich würde mich freuen wenn ihr mir hilft.

#include <LiquidCrystal.h>
 
// initialize the library with the numbers of the interface pins
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 const int gasSensor = A0;
 

 

void setup() {
   // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  
    // definition der Funktion interpolationfloat 
//float interpol(float rsArray[], float ppmAray[], int N, float RSWert);
 }

void loop() {
 
  // Kalibrierungsarray der Länge N = 17
float Rs [17] = {57.84260516,  2.2,  1.606,  1.178596714,  0.944910617,  0.865628395,  0.764262648,  0.687566798,  0.626992561,  0.567101091,  0.544815465,  0.496850952,  0.474860336,  0.474860336,  0.442046642,  0.423905489,  0.402219139};
 float ppmValue [17] = {0,  5,  10,  15,  20,  24,  28.25,  32.5,  37.75,  43.25,  48.75,  53.25,  57.75,  62.50,  67.50,  75.5,  77.5};
   


 // Lese den Wert von dem Sensor ab
  int value = analogRead (gasSensor);
   
 
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  
  lcd.setCursor(0, 1);
  float volt = (value/1023.0)*5.0 ;    // Rechne die von ADC ausgegebenen Werten in Volt um
  float Rs1 = 10*(5-volt)/volt;        //Rechne den Widerstandswert

  if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
  if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
  if (value < 10) lcd.print(" ");
  lcd.print ("Rs: ");
  lcd.print (Rs1);
  
  delay (100);
  
 

 
    
   
if (Rs1 >= Rs [0])
{
    float ppm = ppmValue [0];
  // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
     lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    lcd.print ("ppm: ");
    lcd.print (ppm);  
    delay(100);    // gib 10 Werte pro Sekunde
} 
  // Interpolation: ppm [0;5]
 
  if ( Rs[1] < Rs1 < Rs[0]){

    float ppm = ppmValue [0] + ((-Rs1 + Rs [0])/(Rs[0] - Rs [1] ))*(ppmValue [1] - ppmValue[0]);
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    lcd.print ("ppm: ");
    lcd.print (ppm);  
    delay(100);    // gib 10 Werte pro Sekunde
}
// Interpolation: ppm [5;10]
  else if ( Rs[2] < Rs1 < Rs[1]){
   
   float ppm = ppmValue [1] + ((-Rs1 + Rs [1])/(Rs[1] - Rs [2] ))*(ppmValue [2] - ppmValue[1]);
    
    // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  } 
  
  // Interpolation: ppm [10;15]
  else if ( Rs[2] < Rs1 < Rs[3]){
   
    float ppm = ppmValue [2] + ((-Rs1 + Rs [2])/(Rs[2] - Rs [3] ))*(ppmValue [3] - ppmValue[2]);
    
    // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
    // Interpolation: ppm [15;24]
  else  if ( Rs[3] < Rs1 < Rs[4]){
   
 float ppm = ppmValue [3] + ((-Rs1 + Rs [3])/(Rs[3] - Rs [4] ))*(ppmValue [4] - ppmValue[3]);
   // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
  
  // Interpolation: ppm [24;28.25]
  
 else if ( Rs[4] < Rs1 < Rs[5]){
   
   float ppm = ppmValue [4] + ((-Rs1 + Rs [4])/(Rs[4] - Rs [5] ))*(ppmValue [5] - ppmValue[4]);
  // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
  
   // Interpolation: ppm [28.25;32.5]
   else  if ( Rs[6] < Rs1 < Rs[6]){
   
  float  ppm = ppmValue [5] + ((-Rs1 + Rs [5])/(Rs[5] - Rs [6] ))*(ppmValue [6] - ppmValue[5]);
     // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
   }
  // Interpolation: ppm [32.5;37.75]
else  if ( Rs[7] < Rs1 < Rs[6]){
   
  float  ppm = ppmValue [6] + ((-Rs1 + Rs [6])/(Rs[6] - Rs [7] ))*(ppmValue [7] - ppmValue[6]);
     // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
  
  // Interpolation: ppm [37.75;43.25]
  else  if ( Rs[8] < Rs1 < Rs[7]){
   
  float  ppm = ppmValue [7] + ((-Rs1 + Rs [7])/(Rs[7] - Rs [8] ))*(ppmValue [8] - ppmValue[7]);
     // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
  
  // Interpolation: ppm [43.25;48.75]
  else if ( Rs[9] < Rs1 < Rs[8]){
   
   float ppm = ppmValue [8] + ((-Rs1 + Rs [8])/(Rs[8] - Rs [9] ))*(ppmValue [9] - ppmValue[8]);
     // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
   // Interpolation: ppm [48.75;53.25]
  else  if ( Rs[10] < Rs1 < Rs[9]){
   
  float  ppm = ppmValue [9] + ((-Rs1 + Rs [9])/(Rs[9] - Rs [10] ))*(ppmValue [10] - ppmValue[9]); // set the cursor to column 0, line 0
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor (0,0);
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
    //PPM Ausgabe
    lcd.print ("ppm: ");
    lcd.print (ppm); 
    delay(100);    // gib 10 Werte pro Sekunde
  }
  
 // Interpolation: ppm [53.25;57.75]
...

}

Acetone-rawValue_with_graph (Automatisch gespeichert).xlsx (20.6 KB)

Ich bin mir ziemlich sicher, dass Du von dieser Anweisung:

  else  if ( Rs[3] < Rs1 < Rs[4]){

etwas anderes erwartest, als sie wirklich macht. Der erste Vergleich liefert einen Boolean-Wert zurück, dieser wird dann mit dem letzen Wert verglichen, was aber wahrscheinlich nicht Deine Absicht war.

Besser:

 else if (Rs[3] < Rs1 && Rs1 < Rs[4]) {

Im Übrigen hast Du vergessen, im Post Links zur von Dir verwendeten Hardware einzufügen. Du kannst nicht davon ausgehen, dass wir alle die Datenblätter dazu gleich vorrätig haben.

Hi Pylon,

Danke für deine schnelle Antwort und probiere es gleich.

P.S: Ich benutze Arduino Uno

Das hier solltest du unbedingt in eine Funktion auslagern:

  if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
  if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
  if (value < 10) lcd.print(" ");

Der Funktion übergibst du dann "value" als Parameter. Dadurch musst du das nicht ständig hinschreiben.

Hi Pylon,

es hat funktioniert.
Danke!!!

Hi Serenifly,

kann ich die Funktion so schreiben?

 // Funktion value
  
  void printvalue (float value)
  {
    
    if (value < 1000) lcd.print(" "); //falls Werte über 1000 möglich sind
    if (value < 100) lcd.print(" "); //falls Werte über 100 möglich sind
    if (value < 10) lcd.print(" ");
    
  return value;
  }

danke für deine Antwort

kann ich die Funktion so schreiben?

  1. eine void Funktion liefert nichts zurück.
  2. printValue sollte doch eigentlich ( ihrem Namen nach ) den Wert ausgeben.
    Hast du das vergessen, oder
    Willst du sie als lcd.print(printvalue(x)); verwenden ? ( dann musst du sie als float statt void deklarieren )