Der Arduino ist für kleine Aufgaben wie die Temperaturüberwachung mit einer Tastersteuerung, Relais & LCD-Anzeige bestens geeignet, denn die Komponenten sind recht günstig und der Benefit ist hoch. Zusätzlich lernt man dabei noch etwas über Mikrocontroller & Programmierung. Was du alles dafür benötigst und wie du dieses Projekt aufbaust & programmierst, erfährst du hier.
Im Beitrag Arduino UNO R3 mit DS18B20 Sensor & Relais hatte ich dir bereits eine ähnliche kleine Schaltung zum Thema Temperaturüberwachung gezeigt. Hier möchte ich einen Schritt weiter gehen und den Schwellwert per Taster ändern & auf einer LCD-Anzeige darstellen lassen.
Benötigte Ressourcen für dieses Projekt
Für den Aufbau der Schaltung benötigen wir:
- einen Arduino UNO R3*,
- ein USB-Datenkabel*,
- ein Relais*,
- einen Temperatursensor DS18B20*,
- ein LCD-Display mit I2C Schnittstelle*,
- zwei Printtaster*,
- ein 400 Pin Breadboard*,
- diverse Breadboardkabel*
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Aufbau der Schaltung
Bauen wir nun die Schaltung wie folgt auf:
Funktionsweise der Schaltung
Im nachfolgenden YouTube Video erläutere ich dir die Schaltung und zeige dir die Funktionsweise.
Programm der Temperaturüberwachung für den Arduino UNO R3
Das Programm habe ich dir bereits ausführlich, Schrit-für-Schritt im obigen YouTube-Video erläutert. Hier möchte ich dir dieses gerne zum Download anbieten.
//Bibliothek zum entprellen eines Tasters #include <Bounce2.h> //Bibliotheken um mit dem LCD-Display zu //kommunizieren #include <Wire.h> #include <LiquidCrystal_I2C.h> //Bibliothek um den Temperatursensor //DS18B20 auszulesen #include <OneWire.h> #include <DS18B20_INT.h> //Das Relais ist am digitalen Pin D4 angeschlossen. #define relais 4 //Der Temperatursensor DS18B20 ist am digitalen Pin D3 //angeschlossen. #define ds18b20 3 //Taster "select" am digitalen Pin D12 angeschlossen. #define tasterSelect 12 //Taster "hoch" am digitalen Pin D5 angeschlossen. #define tasterHoch 5 //Taster "runter" am digitalen Pin D2 angeschlossen. #define tasterRunter 2 //OneWire Instanz und Objektinitialisierung für den Sensor. OneWire oneWire(ds18b20); DS18B20_INT sensor(&oneWire); //minimale Temperatur int minTemp = 0; //maximale Temperatur int maxTemp = 0; //aktuelle Temperatur int currentTemp = 0; //Bounce2 Objekte für die Taster Bounce btnSelect = Bounce(); Bounce btnUp = Bounce(); Bounce btnDown = Bounce(); //Intervall für das entprellen der Taster const int BTN_INTERVALL = 25; //Auswahl //0 - min. Temperatur //1 - max. Temperatur //2 - aktuelle Temperatur int auswahl = 0; // Initialisieren des LCD Displays mit der I2C Adresse 0x27 LiquidCrystal_I2C lcd(0x27, 20, 2); //Intervall in welcher der Sensor gelesen werden soll const int INTERVALL = 2000; //Feld zum speichern des Zeitstempels der letzten Aktualisierung. long lastUpdate = 0L; void setup() { //der Pin des Relais als Ausgang definieren pinMode(relais, OUTPUT); //beginn der Kommunikation mit dem Sensor DS18B20 sensor.begin(); //beginn der Kommunikation mit dem LCD-Display lcd.init(); lcd.backlight(); //Initialisieren der Taster //die Taster sind über den internen 10 kOhm Widerstand verbunden btnSelect.attach(tasterSelect, INPUT_PULLUP); btnSelect.interval(BTN_INTERVALL); btnUp.attach(tasterHoch, INPUT_PULLUP); btnUp.interval(BTN_INTERVALL); btnDown.attach(tasterRunter, INPUT_PULLUP); btnDown.interval(BTN_INTERVALL); } //Schreibt eine Zeile auf dem Display void printTextAt(int lineNumber, int column, String text) { lcd.setCursor(column, lineNumber); lcd.print(text); } //Beschreibt das Display mit Text in abhängigkeit mit der //aktuellen Auswahl. void writeLcdDisplay() { lcd.clear(); if (auswahl < 2) { printTextAt(0, 0, auswahl == 0 ? ">" : " "); printTextAt(1, 0, auswahl == 1 ? ">" : " "); printTextAt(0, 1, "min. Temp.:" + String(minTemp, DEC)); printTextAt(1, 1, "max. Temp.:" + String(maxTemp, DEC)); } else { printTextAt(0, 0, " max. Temp.:" + String(maxTemp, DEC)); printTextAt(1, 0, ">akt. Temp.:" + String(currentTemp, DEC)); } } void loop() { //aktualisieren der Taster btnSelect.update(); btnUp.update(); btnDown.update(); //Wenn der Taster "select" gedrückt wurde, dann... if (btnSelect.fell()) { if (auswahl < 2) { auswahl += 1; } else { auswahl = 0; } writeLcdDisplay(); } //Wenn der Taster "hoch" gedrückt wurde, dann... if (btnUp.fell()) { if (auswahl == 0) { minTemp += 1; } else if (auswahl == 1) { maxTemp += 1; } writeLcdDisplay(); } //Wenn der Taster "runter" gedrückt wurde, dann... if (btnDown.fell()) { if (auswahl == 0) { minTemp -= 1; } else if (auswahl == 1) { maxTemp -= 1; } writeLcdDisplay(); } //Wenn der Zeitpunkt der letzten Ausführung plus dem Wert //des INTERVALLs kleiner als die aktuellen Millisekunden sind, dann... if ((lastUpdate + INTERVALL) < millis()) { //anfordern der Temperaturwerte sensor.requestTemperatures(); //auslesen der Temperatur in Grad Celsius currentTemp = sensor.getTempC(); //überschreiben des Wertes für die letzte Ausführung lastUpdate = millis(); //nur wenn die Auswahl auf 2 steht dann soll das LCD-Display aktualisiert werden //(Auswahl 2 zeigt die aktuelle Temperatur an) if (auswahl == 2) { writeLcdDisplay(); } //Wenn die gelesene Temperatur kleiner / gleich als der Wert der Konstante MIN_TEMP ist, //dann soll das Relais aktiviert werden. if (currentTemp <= minTemp) { digitalWrite(relais, LOW); Serial.println("min"); } else if (currentTemp >= maxTemp) { //Ist der gelesene Wert jedoch größer / gleich als der Wert der Konstante MAX_TEMP so //soll das Relais deaktiviert werden. digitalWrite(relais, HIGH); Serial.println("max"); } } }
Speichern der Schwellwerte im internen Speicher des Arduinos
Wenn der Mikrocontroller die Spannung verliert oder mit der Reset-Taste neu gestartet wird, werden alle Variablen zurückgesetzt. Das bedeutet in unserem Fall, dass die beiden Schwellwerte (minTemp & maxTemp) auf null gesetzt werden. Um nun nicht jedes Mal die Werte manuell eintragen zu müssen, speichern wir diese in den internen, nicht flüchtigen Speicher des Arduinos.
Wie du diesen Speicher beschreibst, hatte ich dir ebenso bereits im Beitrag Arduino UNO – I2C EEPROM beschreiben & lesen am 256 KB Baustein erläutert.
Wir werden also zwei zusätzliche Funktionen implementieren, welche den internen Speicher beschreiben, und wieder lesen.
//Bibliothek zum speichern & lesen von Daten //aus dem internen Speicher #include <EEPROM.h> void writeToEEPROM(int adresse, int wert) { EEPROM.write(adresse, wert >> 8); EEPROM.write(adresse + 1, wert & 0xFF); } int readFromEEPROM(int adresse) { return (EEPROM.read(adresse) << 8) + EEPROM.read(adresse + 1); }
Als Quelle für diesen Abschnitt habe ich mich aus dem Beitrag Arduino Store int into EEPROM bedient.
Fertiges Programm zur Temperaturüberwachung mit dem Arduino
//Bibliothek zum speichern & lesen von Daten //aus dem internen Speicher #include <EEPROM.h> //Bibliothek zum entprellen eines Tasters #include <Bounce2.h> //Bibliotheken um mit dem LCD-Display zu //kommunizieren #include <Wire.h> #include <LiquidCrystal_I2C.h> //Bibliothek um den Temperatursensor //DS18B20 auszulesen #include <OneWire.h> #include <DS18B20_INT.h> //Das Relais ist am digitalen Pin D4 angeschlossen. #define relais 4 //Der Temperatursensor DS18B20 ist am digitalen Pin D3 //angeschlossen. #define ds18b20 3 //Taster "select" am digitalen Pin D12 angeschlossen. #define tasterSelect 12 //Taster "hoch" am digitalen Pin D5 angeschlossen. #define tasterHoch 5 //Taster "runter" am digitalen Pin D2 angeschlossen. #define tasterRunter 2 //OneWire Instanz und Objektinitialisierung für den Sensor. OneWire oneWire(ds18b20); DS18B20_INT sensor(&oneWire); //minimale Temperatur int minTemp = 0; //maximale Temperatur int maxTemp = 0; //aktuelle Temperatur int currentTemp = 0; //Bounce2 Objekte für die Taster Bounce btnSelect = Bounce(); Bounce btnUp = Bounce(); Bounce btnDown = Bounce(); //Intervall für das entprellen der Taster const int BTN_INTERVALL = 25; //Auswahl //0 - min. Temperatur //1 - max. Temperatur //2 - aktuelle Temperatur int auswahl = 0; // Initialisieren des LCD Displays mit der I2C Adresse 0x27 LiquidCrystal_I2C lcd(0x27, 20, 2); //Intervall in welcher der Sensor gelesen werden soll const int INTERVALL = 2000; //Feld zum speichern des Zeitstempels der letzten Aktualisierung. long lastUpdate = 0L; const int ADRESSE_MINTEMP = 30; const int ADRESSE_MAXTEMP = 40; void setup() { //der Pin des Relais als Ausgang definieren pinMode(relais, OUTPUT); //beginn der Kommunikation mit dem Sensor DS18B20 sensor.begin(); //beginn der Kommunikation mit dem LCD-Display lcd.init(); lcd.backlight(); //Initialisieren der Taster //die Taster sind über den internen 10 kOhm Widerstand verbunden btnSelect.attach(tasterSelect, INPUT_PULLUP); btnSelect.interval(BTN_INTERVALL); btnUp.attach(tasterHoch, INPUT_PULLUP); btnUp.interval(BTN_INTERVALL); btnDown.attach(tasterRunter, INPUT_PULLUP); btnDown.interval(BTN_INTERVALL); //lesen der Werte aus dem internen Speicher //beim erstmaligen Upload sind die Werte -1 minTemp = readFromEEPROM(ADRESSE_MINTEMP); maxTemp = readFromEEPROM(ADRESSE_MAXTEMP); writeLcdDisplay(); } void writeToEEPROM(int adresse, int wert) { EEPROM.write(adresse, wert >> 8); EEPROM.write(adresse + 1, wert & 0xFF); } int readFromEEPROM(int adresse) { return (EEPROM.read(adresse) << 8) + EEPROM.read(adresse + 1); } //Schreibt eine Zeile auf dem Display void printTextAt(int lineNumber, int column, String text) { lcd.setCursor(column, lineNumber); lcd.print(text); } //Beschreibt das Display mit Text in abhängigkeit mit der //aktuellen Auswahl. void writeLcdDisplay() { lcd.clear(); if (auswahl < 2) { printTextAt(0, 0, auswahl == 0 ? ">" : " "); printTextAt(1, 0, auswahl == 1 ? ">" : " "); printTextAt(0, 1, "min. Temp.:" + String(minTemp, DEC)); printTextAt(1, 1, "max. Temp.:" + String(maxTemp, DEC)); } else { printTextAt(0, 0, " max. Temp.:" + String(maxTemp, DEC)); printTextAt(1, 0, ">akt. Temp.:" + String(currentTemp, DEC)); } //schreiben der Werte für minTemp & maxTemp in den internen Speicher writeToEEPROM(ADRESSE_MINTEMP, minTemp); writeToEEPROM(ADRESSE_MAXTEMP, maxTemp); } void loop() { //aktualisieren der Taster btnSelect.update(); btnUp.update(); btnDown.update(); //Wenn der Taster "select" gedrückt wurde, dann... if (btnSelect.fell()) { if (auswahl < 2) { auswahl += 1; } else { auswahl = 0; } writeLcdDisplay(); } //Wenn der Taster "hoch" gedrückt wurde, dann... if (btnUp.fell()) { if (auswahl == 0) { minTemp += 1; } else if (auswahl == 1) { maxTemp += 1; } writeLcdDisplay(); } //Wenn der Taster "runter" gedrückt wurde, dann... if (btnDown.fell()) { if (auswahl == 0) { minTemp -= 1; } else if (auswahl == 1) { maxTemp -= 1; } writeLcdDisplay(); } //Wenn der Zeitpunkt der letzten Ausführung plus dem Wert //des INTERVALLs kleiner als die aktuellen Millisekunden sind, dann... if ((lastUpdate + INTERVALL) < millis()) { //anfordern der Temperaturwerte sensor.requestTemperatures(); //auslesen der Temperatur in Grad Celsius currentTemp = sensor.getTempC(); //überschreiben des Wertes für die letzte Ausführung lastUpdate = millis(); //nur wenn die Auswahl auf 2 steht dann soll das LCD-Display aktualisiert werden //(Auswahl 2 zeigt die aktuelle Temperatur an) if (auswahl == 2) { writeLcdDisplay(); } //Wenn die gelesene Temperatur kleiner / gleich als der Wert der Konstante MIN_TEMP ist, //dann soll das Relais aktiviert werden. if (currentTemp <= minTemp) { digitalWrite(relais, LOW); Serial.println("min"); } else if (currentTemp >= maxTemp) { //Ist der gelesene Wert jedoch größer / gleich als der Wert der Konstante MAX_TEMP so //soll das Relais deaktiviert werden. digitalWrite(relais, HIGH); Serial.println("max"); } } }
Hallo Stefan,
Klasse, wie immer super erklärt. Es macht Spass es zu lesen / nachzumachen,
Viele Grüße.
Hi,
vielen Dank.
Gruß
Stefan