Arduino Uno mit 2 NTC Oberflächenfühlern und Nextion Touch-Display

Hallo zusammen.

Ich bin hier ganz neu im Forum und auch was Mikrocontroller betrifft ganz neu. Bin mir auch nicht sicher ob dies der richtige Platz für diesen Beitrag ist.

Dies ist mein erstes Projekt mit dem ich mich auseinander gesetzt habe. Die Idee dazu entstand bei der Arbeit (Ich arbeite in Messtechnik). Ich denke jeder der etwas mit Messtechnik zu tun hat, weiß das präzise Messgeräte, entschuldigt den Ausdruck, schweinemässig teuer sind. :o Da meine Ansprüche an Genauigkeit in diesem Projekt nicht im Vordergrund standen, sondern eher die Funktion und der Spaß an der Sache, habe ich versucht mir ein Temperaturmessgerät zu bauen mit zwei NTC-Oberflächentemperaturfühlern.

Ich habe versucht etwas zu finden (Dr. Google lässt grüßen) das schon ungefähr mit dem Vorhaben zusammen passt, habe jedoch nichts passendes gefunden. Nur einzelne Sketch-Schnippsel die mal da und mal dort gepasst haben. Mein Sketch ist also nur ein zusammengestückeltes Werk aus mehreren Schnippseln von diversen anderen Autoren, die von mir an mein Projekt angepasst und kommentiert wuden. Vieleicht hat jemand einmal ähnliche Anforderungen und kann dies hier verwenden. :slight_smile:

Meine verwendeten Komponenten sind:

ITEAD Nextion LCD-Touchdisplay NX3224T028_011:
(Dieses Display habe ich in erster Linie gewählt weil es über die serielle Schnittstelle die Daten vom Arduino-Board bekommt und somit nur den RX und TX Pin belegt (evtl noch +5V und einen GND, kann aber auch über einen Micro-USB Stecker getrennt vom Arduino-board mit Strom versorgt werden) und weil es sehr viele weitere Möglichkeiten zur Verwendung und zum Design gibt.)
Nextion 2,8" Touch-Display

2x 10k NTC-Oberflächenfühler:
NTC-Oberflächenfühler

Arduino UNO Rev.3:
Arduino UNO Rev. 3

2x 10k Widerstand (0,1% - 5ppm/°C):
10k Widerstand

Diverse Kabel und Kleinteile

Untenstehend findet Ihr den Sketch für dieses Projekt und im Anhang den Schaltungsaufbau.
Die Werte im Programmcode für die Widerstände sind nicht die tatsächlichen Werte der Widerstände, sondern nur die Nominalwerte der Widerstände und die Steinhart-Hart Koeffizienten habe ich ebenfalls mit den Standardwiderstandswerten aus dem allgemeinen Datenblatt der Sensoren berechnet.
(Bin aktuell nicht in der Lage diese selbst zu ermitteln, da ich gerade Urlaub habe und mir die Geräte zur Messung hier nicht zur Verfügung stehen.)
Die Steinhart-Hart Koeffizienten habe ich mittels eines Online Thermistor-Calculators berechnet.
SRS Thermistor calculator

Wenn jemand Fehler findet schreibt bitte Kommentare. Wenn jemand Verbesserungsvorschläge und Anregungen hat lasst es mich Wissen. :smiley:

// Welcher Fühler wird an welchem Analogeingang am Arduino Board angeschlossen.

#define REF_FUEHLER A0  // Referenzfühler
#define MESSFUEHLER A1  // Messfühler

// Wie viele Einzelmessungen werden gemacht.
// Mehr Messungen erhöhen die Genauigkeit, benötigen aber mehr Zeit.
// Im Beispiel werden 25 Einzelmessungen vorgenommen.

#define EINZELMESSUNGEN 25  // Das verändern der Zahl ändert auch die Anzahl der Einzelmessungen.

// Die Steinhart-Hart Koeffizienten
// Die benötigten Widerstandswerte können dem Datenblatt des NTC-Thermistors entnommen werden,
// oder mit Hilfe eines geeigneten Multimeters und Temperaturmessgerätes  selbst bestimmt werden.
// Multimeter und Temperaturmessgerät sollten für genaue Messungen einen entsprechenden Genauigkeitsgrad haben.
// Berechnet mit Hilfe des NTC-Kalkulators von SRS. - https://www.thinksrs.com/downloads/programs/therm%20calc/ntccalibrator/ntccalculator.html

#define A_1 1.130480394e-03   // A-Koeffizient des Referenzfühlers
#define B_1 2.338982432e-04   // B-Koeffizient des Referenzfühlers
#define C_1 0.8863706422e-07  // C-Koeffizient des Referenzfühlers
#define A_2 1.130480394e-03   // A-Koeffizient des Messfühlers
#define B_2 2.338982432e-04   // B-Koeffizient des Messfühlers
#define C_2 0.8863706422e-07  // C-Koeffizient des Messfühlers

// Der Widerstandswert der Festwiderstände

#define FESTWIDERSTAND_1 10000  // Widerstandswert des Serienfestwiderstandes des Referenzfühlers
#define FESTWIDERSTAND_2 10000  // Widerstandswert des Serienfestwiderstandes des Messfühlers

 
uint16_t SUM_EM_1[EINZELMESSUNGEN];
uint16_t SUM_EM_2[EINZELMESSUNGEN];

// Da Ich in meiner Testschaltung die NTC-Fühler über den 3,3 Volt Ausgang des Arduino Boards speise
// und diesen Ausgang mit dem Pin "AREF" verbunden habe, muss die Referenzspannung des Boards auf "EXTERN" gesetzt werden.
// Den 3,3 Volt Ausgang nutze ich wegen der stabileren Ausgangsspannung.
// Es wird dadurch die Genauigkeit etwas verbessert.

void setup(void) {
  Serial.begin(9600);
  analogReference(EXTERNAL);
}

void loop(void) {
  uint8_t i;
  float DURCHSCHNITT_1;
  float DURCHSCHNITT_2;
  float R2_1, lnR2_1, R2_2, lnR2_2;
  float TEMP_1, TEMP_2;
  
// Hier werden die Einzelmessungen des Referenzfühlers vorgenommen.
// Zwischen den Messungen gibt es eine Wartezeit von 10 Millisekunden.
  
  for (i=0; i< EINZELMESSUNGEN; i++) {
   SUM_EM_1[i] = analogRead(REF_FUEHLER);
   delay(10);
  }

// Hier werden die Einzelmessungen des Messfühlers vorgenommen.
// Zwischen den Messungen gibt es eine Wartezeit von 10 Millisekunden.
    
  for (i=0; i< EINZELMESSUNGEN; i++) {
   SUM_EM_2[i] = analogRead(MESSFUEHLER);
   delay(10);
  }
 
// Berechnung des Durchschnittswertes aller Einzelmessungen des Referenzfühlers.
  
  DURCHSCHNITT_1 = 0;
  for (i=0; i< EINZELMESSUNGEN; i++) {
     DURCHSCHNITT_1 += SUM_EM_1[i];
  }
  DURCHSCHNITT_1 /= EINZELMESSUNGEN;

// Berechnung des Durchschnittswertes aller Einzelmessungen des Messfühlers.
    
  DURCHSCHNITT_2 = 0;
  for (i=0; i< EINZELMESSUNGEN; i++) {
     DURCHSCHNITT_2 += SUM_EM_2[i];
  }
  DURCHSCHNITT_2 /= EINZELMESSUNGEN;

// Berechnung der Temperatur des Referenzfühlers mittels der Steinhart-Hart Gleichung.
// https://de.wikipedia.org/wiki/Steinhart-Hart-Gleichung
  
  R2_1 = FESTWIDERSTAND_1* (1023.0 / (float)DURCHSCHNITT_1 - 1.0);
  lnR2_1 = log(R2_1);
  TEMP_1 = (1.0 / (A_1 + B_1*lnR2_1 + C_1*lnR2_1*lnR2_1*lnR2_1));  // Steinhart-Hart Gleichung. T  = 1 / {A + B[ln(R)] + C[ln(R)]^3}
  TEMP_1 =  TEMP_1 - 273.15;

// Die Ausgabe der Temperatur des Referenzfühlers erfolgt auf ein Display das über die serielle Schnittstelle
// angeschlossen ist. Beim Display handelt es sich um ein 2,8 Zoll Touch-Display 
// von ITEAD (Nextion NX3224T028_011) - https://www.amazon.de/Unikel-Nextion-LCD-Display-Touch-Panel-ESP8266/dp/B008RU8WAK/ref=sr_1_4?s=computers&ie=UTF8&qid=1533386892&sr=1-4&keywords=Nextion

  Serial.print("refTemp.txt=");  // In dieser Zeile wird das Zieltextfeld am Display angesprochen
  Serial.print("\"");
  Serial.print(TEMP_1);          // Hier wird der Temperaturwert des Referenzfühlers vom Arduino an das Display gesendet
  Serial.print("\"");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

// Berechnung der Temperatur des Messfühlers mittels der Steinhart-Hart Gleichung.
// https://de.wikipedia.org/wiki/Steinhart-Hart-Gleichung
  
  R2_2 = FESTWIDERSTAND_2* (1023.0 / (float)DURCHSCHNITT_2 - 1.0);
  lnR2_2 = log(R2_2);
  TEMP_2 = (1.0 / (A_2 + B_2*lnR2_2 + C_2*lnR2_2*lnR2_2*lnR2_2));  // Steinhart-Hart Gleichung. T  = 1 / {A + B[ln(R)] + C[ln(R)]^3}
  TEMP_2 =  TEMP_2 - 273.15;

// Die Ausgabe der Temperatur des Messfühlers erfolgt auf ein Display das über die serielle Schnittstelle
// angeschlossen ist. Beim Display handelt es sich um ein 2,8 Zoll Touch-Display 
// von ITEAD (Nextion NX3224T028_011) - https://www.amazon.de/Unikel-Nextion-LCD-Display-Touch-Panel-ESP8266/dp/B008RU8WAK/ref=sr_1_4?s=computers&ie=UTF8&qid=1533386892&sr=1-4&keywords=Nextion

  Serial.print("messTemp.txt=");  // In dieser Zeile wird das Zieltextfeld am Display angesprochen
  Serial.print("\"");
  Serial.print(TEMP_2);           // Hier wird der Temperaturwert des Messfühlers vom Arduino an das Display gesendet
  Serial.print("\"");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

// Nach 5 Sekunden Wartezeit wird eine neue Messung der Temperaturen vorgenommen.

  delay(5000);
}

Die Pins D0 und D1 (TX/RX) werden auch für die Programmierung des UNO und zur seriellen Kommunikation benutzt. Ein Nutzung dieser Pins für andere Zwecke - Kommunikation mit dem Nextion - ist daher nicht zu empfehlen.
Da wäre SoftSerial auf anderen Port (Du hast ja noch genug frei) die bessere Lösung.

Gruß Tommy

Danke dir für den Vorschlag. Wurde direkt so umgesetzt und behebt das lästige Problem dass ich das Display beim Übertragen eines Sketches an das Board immer abstecken musste.

Für alle weiteren Interessierten:

Im Anhang befindet sich das auf den Sketch angepasste neue Schaltbild und der Sketch wurde folgenermaßen angepasst.

Allem voran wurden diese beiden Zeilen eingefügt:

#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(2, 3);  // Pin 2 ist der RX-Pin, Pin 3 ist der TX-Pin

Der Teil wo die Verbindung initialisiert wird:

void setup(void) {
  Serial.begin(9600);
  SoftSerial.begin(9600);
  analogReference(EXTERNAL);
}

Der Teil wo die Daten an das Display übertragen werden, wurde folgendermaßen angepasst:

SoftSerial.print("refTemp.txt=");  // In dieser Zeile wird das Zieltextfeld am Display angesprochen
  SoftSerial.print("\"");
  SoftSerial.print(TEMP_1);          // Hier wird der Temperaturwert des Referenzfühlers vom Arduino an das Display gesendet
  SoftSerial.print("\"");
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
SoftSerial.print("messTemp.txt=");  // In dieser Zeile wird das Zieltextfeld am Display angesprochen
  SoftSerial.print("\"");
  SoftSerial.print(TEMP_2);           // Hier wird der Temperaturwert des Messfühlers vom Arduino an das Display gesendet
  SoftSerial.print("\"");
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);

Hier nochmals der gesamte Sketch:

#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(2, 3);  // Pin 2 ist der RX-Pin, Pin 3 ist der TX-Pin

// Welcher Fühler wird an welchem Analogeingang am Arduino Board angeschlossen.

#define REF_FUEHLER A0  // Referenzfühler
#define MESSFUEHLER A1  // Messfühler

// Wie viele Einzelmessungen werden gemacht.
// Mehr Messungen erhöhen die Genauigkeit, benötigen aber mehr Zeit.
// Im Beispiel werden 25 Einzelmessungen vorgenommen.

#define EINZELMESSUNGEN 25  // Das verändern der Zahl ändert auch die Anzahl der Einzelmessungen.

// Die Steinhart-Hart Koeffizienten
// Die benötigten Widerstandswerte können dem Datenblatt des NTC-Thermistors entnommen werden,
// oder mit Hilfe eines geeigneten Multimeters und Temperaturmessgerätes  selbst bestimmt werden.
// Multimeter und Temperaturmessgerät sollten für genaue Messungen einen entsprechenden Genauigkeitsgrad haben.
// Berechnet mit Hilfe des NTC-Kalkulators von SRS. - https://www.thinksrs.com/downloads/programs/therm%20calc/ntccalibrator/ntccalculator.html

#define A_1 1.130480394e-03   // A-Koeffizient des Referenzfühlers
#define B_1 2.338982432e-04   // B-Koeffizient des Referenzfühlers
#define C_1 0.8863706422e-07  // C-Koeffizient des Referenzfühlers
#define A_2 1.130480394e-03   // A-Koeffizient des Messfühlers
#define B_2 2.338982432e-04   // B-Koeffizient des Messfühlers
#define C_2 0.8863706422e-07  // C-Koeffizient des Messfühlers

// Der Widerstandswert der Festwiderstände

#define FESTWIDERSTAND_1 10000  // Widerstandswert des Serienfestwiderstandes des Referenzfühlers
#define FESTWIDERSTAND_2 10000  // Widerstandswert des Serienfestwiderstandes des Messfühlers

 
uint16_t SUM_EM_1[EINZELMESSUNGEN];
uint16_t SUM_EM_2[EINZELMESSUNGEN];

// Da Ich in meiner Testschaltung die NTC-Fühler über den 3,3 Volt Ausgang des Arduino Boards speise
// und diesen Ausgang mit dem Pin "AREF" verbunden habe, muss die Referenzspannung des Boards auf "EXTERN" gesetzt werden.
// Den 3,3 Volt Ausgang nutze ich wegen der stabileren Ausgangsspannung.
// Es wird dadurch die Genauigkeit etwas verbessert.
  
void setup(void) {
  Serial.begin(9600);
  SoftSerial.begin(9600);
  analogReference(EXTERNAL);
}

void loop(void) {
  uint8_t i;
  float DURCHSCHNITT_1;
  float DURCHSCHNITT_2;
  float R2_1, lnR2_1, R2_2, lnR2_2;
  float TEMP_1, TEMP_2;
  
// Hier werden die Einzelmessungen des Referenzfühlers vorgenommen.
// Zwischen den Messungen gibt es eine Wartezeit von 10 Millisekunden.
  
  for (i=0; i< EINZELMESSUNGEN; i++) {
   SUM_EM_1[i] = analogRead(REF_FUEHLER);
   delay(10);
  }

// Hier werden die Einzelmessungen des Messfühlers vorgenommen.
// Zwischen den Messungen gibt es eine Wartezeit von 10 Millisekunden.
    
  for (i=0; i< EINZELMESSUNGEN; i++) {
   SUM_EM_2[i] = analogRead(MESSFUEHLER);
   delay(10);
  }
 
// Berechnung des Durchschnittswertes aller Einzelmessungen des Referenzfühlers.
  
  DURCHSCHNITT_1 = 0;
  for (i=0; i< EINZELMESSUNGEN; i++) {
     DURCHSCHNITT_1 += SUM_EM_1[i];
  }
  DURCHSCHNITT_1 /= EINZELMESSUNGEN;

// Berechnung des Durchschnittswertes aller Einzelmessungen des Messfühlers.
    
  DURCHSCHNITT_2 = 0;
  for (i=0; i< EINZELMESSUNGEN; i++) {
     DURCHSCHNITT_2 += SUM_EM_2[i];
  }
  DURCHSCHNITT_2 /= EINZELMESSUNGEN;

// Berechnung der Temperatur des Referenzfühlers mittels der Steinhart-Hart Gleichung.
// https://de.wikipedia.org/wiki/Steinhart-Hart-Gleichung
  
  R2_1 = FESTWIDERSTAND_1* (1023.0 / (float)DURCHSCHNITT_1 - 1.0);
  lnR2_1 = log(R2_1);
  TEMP_1 = (1.0 / (A_1 + B_1*lnR2_1 + C_1*lnR2_1*lnR2_1*lnR2_1));  // Steinhart-Hart Gleichung. T  = 1 / {A + B[ln(R)] + C[ln(R)]^3}
  TEMP_1 =  TEMP_1 - 273.15;

// Die Ausgabe der Temperatur des Referenzfühlers erfolgt auf ein Display das über die serielle Schnittstelle
// angeschlossen ist. Beim Display handelt es sich um ein 2,8 Zoll Touch-Display 
// von ITEAD (Nextion NX3224T028_011) - https://www.amazon.de/Unikel-Nextion-LCD-Display-Touch-Panel-ESP8266/dp/B008RU8WAK/ref=sr_1_4?s=computers&ie=UTF8&qid=1533386892&sr=1-4&keywords=Nextion

  SoftSerial.print("refTemp.txt=");  // In dieser Zeile wird das Zieltextfeld am Display angesprochen
  SoftSerial.print("\"");            // Anstell von "\"" kann auch 0x22 verwendet werden
  SoftSerial.print(TEMP_1);          // Hier wird der Temperaturwert des Referenzfühlers vom Arduino an das Display gesendet
  SoftSerial.print("\"");            // Anstell von "\"" kann auch 0x22 verwendet werden
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);

// Der nachfolgende Teil sendet die Daten zusätzlich über den seriellen Port.
//Wenn dieser Teil benötigt wird muss die Auskommentierung vor den betreffenden Zeilen entfernt werden.

  // Serial.print("Stufenendmaß:  ");
  // Serial.print(TEMP_1);          // Hier wird der Temperaturwert des Referenzfühlers vom Arduino an den Seriellen Port gesendet.
  // Serial.println(" °C");

// Berechnung der Temperatur des Messfühlers mittels der Steinhart-Hart Gleichung.
// https://de.wikipedia.org/wiki/Steinhart-Hart-Gleichung
  
  R2_2 = FESTWIDERSTAND_2* (1023.0 / (float)DURCHSCHNITT_2 - 1.0);
  lnR2_2 = log(R2_2);
  TEMP_2 = (1.0 / (A_2 + B_2*lnR2_2 + C_2*lnR2_2*lnR2_2*lnR2_2));  // Steinhart-Hart Gleichung. T  = 1 / {A + B[ln(R)] + C[ln(R)]^3}
  TEMP_2 =  TEMP_2 - 273.15;

// Die Ausgabe der Temperatur des Messfühlers erfolgt auf ein Display das über die serielle Schnittstelle
// angeschlossen ist. Beim Display handelt es sich um ein 2,8 Zoll Touch-Display 
// von ITEAD (Nextion NX3224T028_011) - https://www.amazon.de/Unikel-Nextion-LCD-Display-Touch-Panel-ESP8266/dp/B008RU8WAK/ref=sr_1_4?s=computers&ie=UTF8&qid=1533386892&sr=1-4&keywords=Nextion

  SoftSerial.print("messTemp.txt=");  // In dieser Zeile wird das Zieltextfeld am Display angesprochen
  SoftSerial.print("\"");             // Anstell von "\"" kann auch 0x22 verwendet werden
  SoftSerial.print(TEMP_2);           // Hier wird der Temperaturwert des Messfühlers vom Arduino an das Display gesendet
  SoftSerial.print("\"");             // Anstell von "\"" kann auch 0x22 verwendet werden
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);

// Der nachfolgende Teil sendet die Daten zusätzlich über den seriellen Port.
//Wenn dieser Teil benötigt wird muss die Auskommentierung vor den betreffenden Zeilen entfernt werden.

  // Serial.print("Prüfgerät:     ");
  // Serial.print(TEMP_2);          // Hier wird der Temperaturwert des Messfühlers vom Arduino an den seriellen Port gesendet.
  // Serial.println(" °C");
  // Serial.println();
  

// Nach 5 Sekunden Wartezeit wird eine neue Messung der Temperaturen vorgenommen.

  delay(5000);
}

Winzige Anmerkung (etwas OT)

Widerstand nicht Wiederstand, sonst tut es beim Lesen weh :wink:

Und eine Frage zur Schaltung:
Warum verwendest du 3,3 Volt für die NTC als Spannung ?

Schönen Sonntag zusammen.

Widerstand nicht Wiederstand, sonst tut es beim Lesen weh :wink:

Danke Moko! :grinning:

@HotSystems

Die 3,3 Volt habe ich einerseits deshalb genommen, weil ich in einigen Beiträgen gelesen habe, dass diese, vom Board gelieferte Spannung, stabiler ist.
Andererseits habe ich sie genommen, weil ich den 5 Volt Ausgang für die Speisung des Displays verwende.

Abgesehen davon fühle ich mich dabei wohler, wenn Sensoren und andere Verbraucher getrennt voneinander versorgt werden und nicht alles am selben Pin hängt.

Schönen Sonntag noch! :smiley:

Die 3,3V Spannung für die Messung eines Spannungsteilers zu nehmen kann die falsche Entscheidung sein.

Wenn Du den Spannungsteiler mit 3,3V betreibst, die Referenzspannng des ADC aber auf den standartmäßig eingestellten 5V bleibt verfälscht jeder Spannungseinbruch auf den 5V das Meßergebnis. Wenn Du den Spannungsteiler auf 5V anschließt, heben sich die Spannungsschwankungen in der Versorgungsspannung auf.

Eine 2. Lösung wäre Du verwendest die 3,3V als Referenzspannung

Grüße Uwe

Hallo Uwe,

Die 3,3 V verwende ich bereits als Referenzspannung. :slight_smile:

Ich denke ich habe das im Schaltaufbau (siehe Anhang) und im Sketch so richtig gemacht, oder? ???
Bin aber gerne für andere Lösungen offen. :slight_smile:

void setup(void) {
  Serial.begin(9600);
  SoftSerial.begin(9600);
  analogReference(EXTERNAL);
}

Ok, so mißt Du richtig.
Grüße Uwe