Dieser Beitrag wurde uns von unserem Gastautoren Miguel Torres Gordo zugesandt. Viel Spaß beim Lesen und Nachbauen:
Dies ist ein einfaches und nützliches Projekt, um mit wenigen Modulen die Zeit, Temperatur und Luftfeuchtigkeit in einem Raum anzuzeigen. Für die Uhrzeit habe ich mich entschieden, nur die Stunde und die Minuten anzuzeigen, da die Sekunden meiner Meinung nach nicht relevant sind. Das Foto zeigt eine mögliche Verteilung der Anzeige, aber es bleibt der Phantasie des Lesers überlassen, wie sie z.B. in einer mit einem 3D-Drucker hergestellten Box eingesetzt werden könnten.
Benötigte Materialien
- Nano V3.0 CH340 Chip fertig gelötet, verbesserte Version mit USB-Kabel
- MAX7219 8x32 4 in 1 Dot Matrix LED Anzeigemodul
- KY-015 DHT 11 Temperatursensor Modul
- DS3231 I2C-Echtzeituhr (baugleich zu DS1307)
- alternativ mit Änderungen DS1302 Serielle Echtzeituhr RTC Echtzeituhr-Modul
- MG995 Micro Digital Servo Motor oder SG90 Micro Servo Motor 9G oder MG90S Micro Servomotor
- MB 102 Breadboard Kit - 830 Breadboard, Netzteil Adapter 3,3V 5V, 65Stk Steckbrücken
- externes Netzteil (9V - 12V)
Erforderliche Software
- Arduino IDE
- DS1307_setup.ino sketch
- clock_temperature_humidity.ino sketch
- MD_Parola Bibliothek
- MD_MAX72xx Bibliothek
- SPI Bibliothek (integriert)
- Wire Bibliothek (integriert)
- DS3231 Bibliothek (von jarzebski)
- DHT Bibliothek
- Servo Bibliothek
Suchen Sie die fehlenden Bibliotheken in der Arduino IDE über "Werkzeuge -> Bibliotheken verwalten..."
Schaltung und Beschreibung der Funktionsweise
Das RTC-Modul DS1302 ist für die Bereitstellung der Uhrzeit am Mikrocontroller zuständig, während das DHT-11-Modul die Temperatur und die Luftfeuchtigkeit misst. Der Mikrocontroller steuert dann mit den Informationen die 8x8-LED-Modulgruppe für die Uhrzeit und die Servomotoren für die Anzeige von Temperatur und Luftfeuchtigkeit.
Es ist sehr wichtig, dass wir eine entsprechende Batterie einsetzen, denn obwohl dieses Modul ohne sie korrekt funktioniert, wird die Zeit zurückgesetzt, wenn wir das Modul vom Stromkreis trennen.
Um die aktuelle Uhrzeit und das Datum einzustellen, müssen wir die folgende Schaltung aufbauen:
RTC (I2C) |
Nano V3 |
VCC |
5V |
GND |
GND |
CLK |
A5 (SCL) |
DAT |
A4 (SDA) |
RST |
- |
Wir führen dann den Sketch DS1307_setup.ino aus, wir öffnen den Serial Monitor und können sowohl das Datum als auch die Uhrzeit sehen, die das Modul gespeichert hat. Diese Daten sind die, die das Betriebssystem des PCs im Moment der Ausführung des Sketches zur Verfügung stellt. Wenn wir uns die Skizze anschauen, können wir sehen, dass die Codezeile
clock.setDateTime(__DATE__, __TIME__);
diejenige ist, die das Modul mit den beiden Daten aus dem System lädt. Von diesem Moment an haben wir das Modul mit Uhrzeit und Datum konfiguriert und dank der Batterie werden diese Daten nicht aus dem Modul gelöscht, wenn die Spannung entfernt wird.
Nachdem wir die Uhrzeit und das Datum eingestellt haben, installieren wir das Modul DS1302 zusammen mit den anderen Modulen in der Schaltung und führen den Sketch clock_temperature_humidity.ino aus. Wenn wir das Laden beendet haben, sollten wir die genaue Uhrzeit auf der LED-Matrix sehen und die beiden Servomotoren sollten sich bewegen, bis sie auf den Wert der Temperatur und der Luftfeuchtigkeit in der Umgebung positioniert sind.
Um den Sketch auf den Mikrocontroller zu laden, entfernen Sie die Leitung zwischen +5V und Vin.
Wir haben die 5V Gleichspannungsversorgung, den Mikrocontroller, das RTC Modul DS1302, DHT-11, das LED Array und die 2 Servomotoren.
Analysieren wir den Code:
Als erstes laden wir die Bibliotheken, die für die Ausführung des Sketches notwendig sind. Die ersten drei sind für die LED-Matrix, die nächsten zwei für die Verwendung des DS1307-Moduls, die vorletzte ist die Bibliothek für das DHT-11-Modul und die letzte ist für die Verwendung der Servomotoren:
#include <MD_Parola.h> #include <MD_MAX72xx.h> #include <SPI.h> #include <Wire.h> #include <DS3231.h> #include <DHT.h> #include <Servo.h>
Nach den Bibliotheken müssen wir die Verbindungen der Module mit den Pins des Mikrocontrollers konfigurieren. Anschließend den Typ des Controllers und die Anzahl der LED-Module der Matrix (4 in unserem Fall). Dann den Typ des DHT-Moduls. Wir erstellen die Instanzen jedes Moduls und die notwendigen Variablen, um die Daten dafür zu speichern:
// Define hardware type, size, and output pins MAX7219 8x32 4 in 1 Dot Matrix LED Display Module #define HARDWARE_TYPE MD_MAX72XX::FC16_HW #define MAX_DEVICES 4 #define CS_PIN 10 // Define hardware type andi pins DHT-11 #define DHTPIN 2 #define DHTTYPE DHT11 // Create a new instance of the MD_Parola class with hardware SPI connection: MD_Parola reloj = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // Create a instance of DHT-11 sensor and variables for temperature and humidity DHT dht(DHTPIN, DHTTYPE); float t, hu; // Instances of the servos for humidity and temperature Servo servoTemperature; Servo servoHumidity; // Instance for the DS3231 clock DS3231 clock; RTCDateTime dt;
Nachdem wir die Modulparameter konfiguriert haben, initialisieren wir die Module in der setup()-Funktion des Sketches:
// Initialization of Monitor Serial Serial.begin(9600); Serial.println("Initialize RTC module"); // Initialization of DS3231 Module clock.begin(); // Initialization MAX7219 LED Matrix Display reloj.begin(); // Intialize the object reloj.setIntensity(0); // Set the intensity (brightness) of the display (0-15) reloj.displayClear(); // Clear the display // Initialization DHT-11 module dht.begin(); // Servo pins connections servoTemperature.attach(3); servoHumidity.attach(4);
In der loop()-Funktion werden die Messwerte und die Berechnungen erzeugt, die für die Anzeige erforderlich sind.
Zunächst werden wir die Temperatur- und Luftfeuchtigkeitsdaten analysieren. Wir ordnen den Temperaturwert der Variablen t und den Feuchtigkeitswert der Variablen hu zu. Wenn wir keine Daten erhalten, teilen wir das über den seriellen Monitor mit. Die Wertebereiche, mit denen wir arbeiten werden, reichen von 0 bis 50 Grad Celsius Temperatur und von 0 % bis 100 % Luftfeuchtigkeit. Wir wissen, dass die Servomotoren normalerweise einen Winkelbereich von 180 Grad haben. Damit die Servomotoren die Daten richtig markieren, führen wir eine einfache mathematische Operation durch, um die Maximalwerte der Bereiche den 180 Grad des Winkels der Servomotoren zuzuordnen.
// Temperature and humidity reading t = dht.readTemperature(); hu = dht.readHumidity(); if (isnan(hu) || isnan(t)) { Serial.println("DHT sensor reading failure !!!"); }
...
servoTemperature.write((t*180)/50); // Move the servos to value servoHumidity.write((hu*180)/100);
Als Alternative können Sie die map()-Funktion einsetzen.
Das Verfahren zur Erfassung und Anzeige der Stunden und Minuten ist sehr einfach. Nur eine Anmerkung: Wenn das Modul DS1302 die Stunden und Minuten sendet, sendet es die minimal notwendigen Ziffern, also von 0 bis 9 nur eine Ziffer. Wenn wir also weniger als 10 Stunden oder 10 Minuten erhalten, wird jeweils nur eine Ziffer angezeigt. Das würde den Eindruck einer Fehlfunktion erwecken, oder sieht nicht schön aus. Also müssen wir immer zwei Ziffern in den Stunden und Minuten anzeigen.
Mit der ersten Zeile fordern wir das DS1302-Modul auf, die Zeit- und Datumsdaten abzurufen. Dann erstellen wir zwei Variablen (h und m), um die Daten im String-Format der Stunde und der Minuten zu speichern. Sind die Werte jeweils kleiner als 10, wird mit der if-Anweisung eine 0 als Zeichen, nicht als Ziffer, mit concat vorangestellt. Jetzt müssen wir diese Daten nur noch auf der LED-Matrix anzeigen. Um zu zeigen, dass die Uhr läuft, zeigen wir zwei sehr ähnliche Strings an. Einen mit der Trennung zwischen Stunden und Minuten mit einem Doppelpunkt und einen anderen ohne den Doppelpunkt. Die Anzeige erfolgt im Wechsel von 500ms, was einer halben Sekunde entspricht. Somit blinken die Doppelpunkte.
Die delay()-Funktion blockiert den Programmablauf, was in diesem Fall nicht weiter relevant ist, da genug Zeit bleibt, die Daten auszulesen und anzuzeigen.
dt = clock.getDateTime(); // Reading data from the RTC module String h; // Variable for the hours String m; // Variable for the minutes int hora = (dt.hour); // The variable "hora" is used if (dt.hour<10) { // to set the time to always show two digits h = "0"; // two digits in the clock hours. h.concat((String) hora); } else { h = (String) hora; } int minuto = (dt.minute); // The variable "minuto" is used if (dt.minute<10) { // to set the minutes to always m ="0"; // two digits en the clock minutes m.concat((String) minuto); } else { m = (String) minuto; } String r = h + ":" + m; // Hour and minutes with colon separation String q = h + " " + m; // Hour and minutes without colon separation Serial.print("Hora: "); Serial.print(dt.hour); Serial.print(":"); Serial.print(dt.minute); Serial.print(":"); Serial.print(dt.second); Serial.println(""); Serial.print( "T = " ); Serial.print(t); Serial.print(" ºC, H = "); Serial.print(hu); Serial.print( "%, " ); reloj.setTextAlignment(PA_CENTER); // Configuration the text centered reloj.print(r); // We change the text showing the separation delay(500); // and without it every half second for the reloj.print(q); // sensation of movement. delay(500);
Komplette Sketches als Download:
clock_temperature_humidity.ino
6 Kommentare
Andreas Wolter
@Veit Burmester: Danke für den Hinweis. Das hier verwendete RTC Modul war das DS1307, welches genauso angeschlossen wird, wie das DS3231. Ich habe das im Beitrag in der Komponentenliste geändert. Entschuldigung, wenn das zu Verwirrungen geführt hat. Der Autor des Beitrags hatte das so nicht vorgesehen. Ich wollte eine Alternative hinzufügen, falls das RTC Modul nicht verfügbar ist.
Sie haben also völlig Recht. DS3231 und DS1307 sollten funktionieren. Für das DS1302 müssen Änderungen vorgenommen werden.
Grüße,
Andreas Wolter
Veit Burmester
Hallo Herr Wolter
Nach längerer Auszeit konnte ich mich wieder um obiges Projekt kümmern. Ich möchte Ihnen auch ungern die Zeit stehlen.
Ich habe alles genau so Aufgebaut wie beschrieben. Funktion gleich Null. Habe den Fehler erst bei mir gesucht. Jedoch nach genaueren Kontrolle kam ich zu dem Schluss das das von Ihnen benutzte RTC 1302 Modul nicht für diese Verdrahtung und Programm geeignet ist. Das Modul DS 3231 hingegen funktioniert. Auch Modul DS 1307 sollte funktioniert. Nachschlagen auf Ihrer Produktseite zeigt eine andere Verdrahtung ( 3Datenkabel auf Digitale IO ) des RTC 1302 und auch die Librarie ist ganz anders. So wie ich die Produktbeschreibung verstehe hat das Modul 1302 keine I²C Schnittstelle. Das kleine Programm zum Zeit-Einstellen heißt ja auch DS 1307 setup. ino.
Sollte ich hier falsch liegen bitte ich schon im Vorfeld um Entschuligung.
Mit Freundlichen Grüßen aus dem hohen Norden
Veit Burmester
Andreas Wolter
@Veit Burmeister: danke für den Hinweis. Es handelt sich nicht um die Bibliothek DS3231 aus der Bibliotheksverwaltung von Andrew Wickert. Ich habe den Link zum Download ergänzt. Ich konnte es tatsächlich auch erst kompilieren, wenn ich die besagte Bibliothek DS3231 gelöscht habe. Die kommt sich mit der Arduino 3231 Bibliothek stark in die Quere. Sorry für das Missverständnis.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Veit Burmester
Hallo
Ich habe Probleme mit der Bibliothek DS3231. So wie ich die Fehlerliste lese passt sie nicht zu der Programmierung. Ein Keyword1 RTCDateTime gibt es nicht in der Bibliothek.
Vielleicht habe ich auch die falsche Bibliothek heruntergeladen. die ich in Benutzung habe ist genau so geschrieben wie im Sketch benötigt.
Diese gilt für beide DS1307_setup.ino und
clock_temperature_humidity.ino Bitte um kurze Info
Andreas Wolter
@jue: an dieser Stelle werden die Werte ausgelesen:
t = dht.readTemperature();
hu = dht.readHumidity();
und an dieser Stelle an die Servos gegeben:
servoTemperature.write((t*180)/50);
servoHumidity.write((hu*180)/100);
statt der Servos müssen Sie jetzt die Werte t und hu an das Display (ich nehme an, Sie meinten 7-Segment-Anzeigen) geben. Wie Sie diese verwenden können, zeigt dieser Blogbeitrag. Eventuell hilft Ihnen das weiter:
https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/echtzeituhr-mit-display-am-nano-v3
jue
gute idee. wie würde das programm und das schaltbild aussehen, wenn man statt der servos 2 digianzeigen verwendet?