#LCDKeypadShield
Explore tagged Tumblr posts
Text
Arduino UNO R4 Projekt: Weltzeituhr mit LCD Keypad Shield
Wie du das LCD Keypad Shield programmierst, habe ich dir bereits im Beitrag LCD Keypad Shield für Arduino: Einsteigerfreundliches Display mit Tastensteuerung ausführlich erläutert. In diesem Beitrag soll es nun darum gehen, wie du dir eine Weltzeituhr am Arduino UNO R4 programmierst. Der Arduino UNO R4 verfügt über einen ESP32 Chip und mit dem Formfaktor des alten UNO R3 ist dieser bestens geeignet für dieses Projekt. https://youtu.be/uCFm0KZOZh8 Der Aufbau einer Schaltung ist recht einfach, denn das LCD Keypad Shield wird lediglich auf den Mikrocontroller gesteckt.
Das LCD Display verfüg über zwei Zeilen mit je 16 Zeichen, das ist für die Anzeige von Datum, Uhrzeit und der Zeitzone etwas wenig, daher habe ich das auf den Tag, die Uhrzeit und die Zeitzone in Kurzform komprimiert.
Benötigte Ressourcen für dieses kleine Projekt
Wenn du das kleine Projekt nachbauen möchtest, dann benötigst du: - einen Arduino UNO R4 WiFi*, - ein USB-C Datenkabel*, - ein LCD Keypad Shield* 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!
NTP Timeserver für die Abfrage von Zeiten
Es gibt im Internet einige NTP Timeserver welche für dieses Projekt verwendet werden können, für dieses Projekt verwende ich ptbtime1.ptb.de von der Physikalisch-technische Bundesanstalt. Wir müssen lediglich für die jeweilige Zeitzone noch Stunden dazu oder abzählen. Liste mit Zeitzonen und TimeOffsets Nachfolgend gebe ich dir eine Tabelle, aus welcher du entnehmen kannst, welchen Offset du für die Zeit verwenden musst. Rechenbeispiele: - für Pacific Standard Time (PST) musst du von der aktuellen Uhrzeit -8h rechnen, - für Japan Standard Time (JST) musst du von der aktuellen Uhrzeit +9h rechnen KontinentZeitzoneUTC ZeitNordamerikaEastern Standard Time (EST)UTC-5Central Standard Time (CST)UTC-6Mountain Standard Time (MST)UTC-7Pacific Standard Time (PST)UTC-8Alaska Standard Time (AKST)UTC-9Hawaii-Aleutian Standard Time (HAST)UTC-10SüdamerikaBrasília Time (BRT)UTC-3Argentina Standard Time (ART)UTC-3Chile Standard Time (CLT)UTC-4Venezuela Standard Time (VET)UTC-4:30EuropaGreenwich Mean Time (GMT)UTC+0Central European Time (CET)UTC+1Eastern European Time (EET)UTC+2British Summer Time (BST)UTC+1AfrikaWest Africa Time (WAT)UTC+1Central Africa Time (CAT)UTC+2East Africa Time (EAT)UTC+3South Africa Standard Time (SAT)UTC+2AsienIndian Standard Time (IST)UTC+5:30China Standard Time (CST)UTC+8Japan Standard Time (JST)UTC+9Australian Eastern Standard Time (AEST)UTC+10Australian Central Standard Time (ACST)UTC+9:30Australian Western Standard Time (AWST)UTC+8OzeanienNew Zealand Standard Time (NZST)UTC+12Fiji Standard Time (FST)UTC+12Tonga Standard Time (TST)UTC+13
Programmieren einer Weltzeituhr mit einem NTP Zeitserver
Wie du dich mit einem Mikrocontroller zu einem WiFi Netzwerk verbindest, habe ich dir bereits in einigen Beiträgen ausführlich erläutert. Jedoch nehme ich dich in der nachfolgenden Schritt-für-Schritt-Anleitung an die Hand, sodass du alle Informationen in diesem Beitrag findest. Schritt 1 - Installation der benötigten Bibliotheken Für die Abfrage der Zeit aus dem Internet benötigen wir eine Bibliothek, ich verwende hier NTPClient welche als ZIP-Datei vom GitHub Repository arduino-libraries/NTPClient heruntergeladen werden kann. Schritt 2 - Aufbau einer WiFi Verbindung Im ersten richtigen Schritt programmieren wir die WiFi Verbindung, dieses ist recht einfach und mit wenigen Zeilen Code erledigt. //Bibliotheken zum aufbau einer WiFi Verbindung #include #include //Die Zugangsdaten zum WiFi-Netzwerk const char *ssid = "*****"; const char *password = "*****"; void setup() { //beginn der seriellen Kommunikation Serial.begin(115200); //Aufbau der WiFi Verbindung WiFi.begin(ssid, password); //solange noch keine Verbindung hergestellt wurde, soll //eine Pause von 500ms eingelegt werden, //ein Punkt auf der seriellen Schnittstelle ausgegeben werden while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //Wenn die Verbindung erfolgreich aufgebaut wurde, dann //wird der nchfolgende Text angezeigt. Serial.print("Erfolgreich zu "); Serial.print(ssid); Serial.println(" verbunden!"); } void loop() { //bleibt leer } Wenn die Verbindung zum Netzwerk hergestellt wurde, dann erscheint auf der seriellen Schnittstelle die Ausgabe vom Text "Erfolgreich zu verbunden!". Schritt 3 - Abfrage einer Zeit von einem NTPServer Wie erwähnt möchte ich die Daten vom Zeitserver der Physikalisch-technische Bundesanstalt abrufen. Die Adresse von diesem ist ptbtime1.ptb.de. //Bibliotheken zum aufbau einer WiFi Verbindung #include #include //Die Zugangsdaten zum WiFi-Netzwerk const char *ssid = "*****"; const char *password = "*****"; void setup() { //beginn der seriellen Kommunikation Serial.begin(115200); //Aufbau der WiFi Verbindung WiFi.begin(ssid, password); //solange noch keine Verbindung hergestellt wurde, soll //eine Pause von 500ms eingelegt werden, //ein Punkt auf der seriellen Schnittstelle ausgegeben werden while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //Wenn die Verbindung erfolgreich aufgebaut wurde, dann //wird der nchfolgende Text angezeigt. Serial.print("Erfolgreich zu "); Serial.print(ssid); Serial.println(" verbunden!"); } void loop() { //bleibt leer } Die Ausgabe auf der seriellen Schnittstelle ist wiefolgt: - erste Zeile, der Hinweis das die WiFi-Verbindung aufgebaut wurde, - zweite bis n-te Zeile, die Uhrzeit vom NTPServer
Wenn noch keine Verbindung zum Server hergestellt wurde, dann kann auch einmal die Uhrzeit mit 01:00:00 geliefert werden. Hier muss man lediglich ein paar Sekunden warten. In der Grafik ist ersichtlich, dass die Uhrzeit um eine Stunde verschoben ist, bedingt durch die europäische Sommerzeit. Um dies anzupassen, wird die Funktion setTimeOffset am Objekt timeClient aufgerufen, welches in der setup-Funktion initialisiert wird. Dabei wird der Funktion einmalig ein Parameter von 7200 Sekunden übergeben, was zwei Stunden entspricht. timeClient.setTimeOffset(7200); Schritt 4 - Ausgeben der Daten auf dem LCD Display Das LCD Display hat maximal 16 Zeichen für je zwei Zeilen zur Verfügung, anders als bei OLED Displays kann man hier nicht durch die Auswahl einer kleineren Schriftart für mehr Platz sorgen. Man muss quasi Abstriche machen. Damit wir mit dem LCD Display kommunizieren können, importieren wir die LiquidCrystal Bibliothek welche bei der Arduino IDE 2.x dabei ist. //Bibliotheken zum aufbau einer WiFi Verbindung #include #include //Bibliothek zum kommunizieren mit einem Zeitserver #include //Bibliothek zum kommunizieren mit dem LCD Display #include //Objekt vom Typ LiquidCrystal initialisieren LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Die Zugangsdaten zum WiFi-Netzwerk const char *ssid = "*****"; const char *password = "******"; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "ptbtime1.ptb.de", 3600, 60000); void setup() { //beginn der seriellen Kommunikation Serial.begin(115200); //Aufbau der WiFi Verbindung WiFi.begin(ssid, password); //solange noch keine Verbindung hergestellt wurde, soll //eine Pause von 500ms eingelegt werden, //ein Punkt auf der seriellen Schnittstelle ausgegeben werden while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //Wenn die Verbindung erfolgreich aufgebaut wurde, dann //wird der nchfolgende Text angezeigt. Serial.print("Erfolgreich zu "); Serial.print(ssid); Serial.println(" verbunden!"); //beginn der Kommunikation mit dem Zeitserver timeClient.begin(); //Zeitoffset von 1h für die europäische Sommerzeit timeClient.setTimeOffset(7200); //Das verbaute LCD Display hat 16 Zeichen mit zwei Zeilen. //Die Bibliothek kann für viele weitere verwendet werden, daher müssen //diese Daten übergeben werden. lcd.begin(16, 2); } void loop() { //aktualisieren der Daten timeClient.update(); //Ausgeben eines formatierten Zeitstempels String formattedTime = timeClient.getFormattedTime(); Serial.println(formattedTime); //Daten im LCD Display leeren lcd.clear(); //Anzeigen der Uhrzeit lcd.print(formattedTime); //eine Pause von 1 Sekunde delay(1000); } Die Uhrzeit wird nun nicht nur auf der seriellen Schnittstelle ausgegeben, sondern auch auf dem LCD Display.
Schritt 5 - Anzeigen von unterschiedlichen Weltzeiten auf dem Display Im nächsten Schritt wollen wir jetzt eine Liste von Weltzeiten anlegen und diese nacheinander anzeigen lassen. In der zweiten noch leeren Zeile möchte ich die Zeitzone und die Differenz anzeigen lassen. Weltzeituhr am Arduino UNO R4 WiFi mit dem LCD Keypad ShieldHerunterladen Am einfachsten geht dieses mit einem MenuItem welches nachfolgende Eigenschaften hat: struct MenuItem { double timeOffset; //die Zeit welche abgezogen/addiert werden soll String timezone; //die Bezeichnung der Zeitzone }; Von diesem neuen Datentyp MenuItem können wir uns nun beliebig viele anlegen und in ein Array ablegen. MenuItem item1 = { 1, "CEST (UTC +2)" }; //Central European Summer Time (CEST) MenuItem item2 = { 0, "GMT (UTC +0)" }; //Greenwich Mean Time (GMT) MenuItem item3 = { -4, "CLT (UTC -4)" }; //Chile Standard Time (CLT) MenuItem item4 = { 12, "NZST (UTC +12)" }; //New Zealand Standard Time (NZST) MenuItem item5 = { 9.5, "ACST (UTC +9:30)" }; //Australian Central Standard Time (ACST) MenuItem item6 = { -10, "HAST (UTC -10)" }; //Hawaii-Aleutian Standard Time (HAST) const int NUM_MENUITEMS = 6; MenuItem menu = { item1, item2, item3, item4, item5, item6 }; Wir entnehmen ein MenuItem mit dem aktuellen index aus dem Array. Im Anschluss berechnen wir den Offset. Dieser Offset wird in Sekunden übergeben (1h = 3600 Sekunden). Die nächsten Zeilen dienen dann lediglich um den Zeitstempel wie zuvor zu laden und auf dem Display anzuzeigen. MenuItem item = menu; double timeOffset = item.timeOffset * 3600; timeClient.setTimeOffset(timeOffset); //aktualisieren der Daten timeClient.update(); //Ausgeben eines formatierten Zeitstempels String formattedTime = timeClient.getFormattedTime(); Serial.println(formattedTime); //Daten im LCD Display leeren lcd.clear(); //Anzeigen der Uhrzeit lcd.print(formattedTime); //Anzeigen der Zeitzone lcd.setCursor(0, 1); lcd.print(item.timezone); Die Weltzeiten sollen immer jeweils für 5 Sekunden angezeigt werden, dafür nutze ich eine bekannte Lösung mit einer Pause ohne Delay. Da ich auf die Werte im Array mit der Variable index zugreife erhöhe ich diese damit alle 5 Sekunden jedoch läuft das Programm im Hintergrund weiter. long lastAction = -1; const long PAUSE = 3000; //Alle 5 Sekunden die Zeitzone wechseln long currentMillis = millis(); if (lastAction + PAUSE < currentMillis) { lastAction = currentMillis; if (index < NUM_MENUITEMS-1) { index++; } else { index = 0; } }
Arbeiten mit dem Timestamp
Von der Bibliothek erhalten wir mit der Funktion getEpochTime() einen Zeitstempel in Sekunden. Dieser repräsentiert die vergangenen Sekunden seit dem 01.01.1970. Aus diesem können wir zusätzlich auch das Datum berechnen und somit auf dem Display zusätzlich das Datum anzeigen. Ich habe hier bei der Uhrzeit die Sekunden abgeschnitten und das Jahr auf zweistellig gekürzt.
Das fertige Programm kannst du nachfolgend herunterladen: Anzeige von Datum & Uhrzeit von verschiedenen Zeitzonen am LCD Keypad Shield mit dem Arduino UNO R4 WiFiHerunterladen // Funktion zur Umwandlung eines Unix-Timestamps in ein Datum String formatiereDatum(unsigned long timestamp) { unsigned long days = timestamp / 86400; // Tage seit dem Unix-Epoch unsigned long years = 1970; // Beginn des Unix-Epoch unsigned long remainingDays = days; // Jahr berechnen while (remainingDays >= 365) { if (istSchaltjahr(years)) { remainingDays -= 366; } else { remainingDays -= 365; } years++; } // Monat und Tag berechnen unsigned long months = 0; unsigned long monthLength = 0; while (remainingDays > monthLength) { monthLength = tageImMonat(months, years); remainingDays -= monthLength; months++; } return zweistellig(remainingDays + 1) + "." + zweistellig(months + 1) + "." + String(years % 100); } // Funktion zur Überprüfung, ob ein Jahr ein Schaltjahr ist bool istSchaltjahr(unsigned long year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } // Funktion zur Rückgabe der Anzahl der Tage in einem Monat unsigned long tageImMonat(unsigned long month, unsigned long year) { if (month == 1) { // Februar if (istSchaltjahr(year)) { return 29; } else { return 28; } } else if (month == 3 || month == 5 || month == 8 || month == 10) { // April, Juni, September, November return 30; } else { return 31; } } // Funktion zur Umwandlung eines Unix-Timestamps in eine Uhrzeit String formatiereUhrzeit(unsigned long timestamp) { unsigned long minutes = (timestamp % 3600) / 60; unsigned long hours = (timestamp % 86400) / 3600; return zweistellig(hours) + ":" + zweistellig(minutes); } // Funktion zur Formatierung von Zahlen auf zwei Stellen String zweistellig(unsigned long zahl) { if (zahl < 10) { return "0" + String(zahl); } else { return String(zahl); } } Read the full article
0 notes
Video
Found cool car game code, controlled by Arduino on LCD keypad shield Source: https://codebender.cc/sketch:13390#16x2%20Car%20game.ino #arduino #microcontroller #game #cargame #lcdkeypadshield #lcd #electronics #programming
0 notes
Text
LCD Keypad Shield für Arduino: Einsteigerfreundliches Display mit Tastensteuerung

Das coole LCD Keypad Shield gibt es schon sehr lange auf dem Markt und wurde auch auf anderen Seiten schon beschrieben. Dieser Beitrag soll jedoch etwas tiefer gehen und ich möchte dir, nachdem ich den Aufbau und die Programmierung erläutert habe, ein cooles nützliches Projekt mit diesem zeigen. https://youtu.be/4eqaoDKCIZU Ich möchte meinem ehemaligen Abteilungsleiter im Elektroniklabor herzlich danken. Durch die großzügige Möglichkeit, sich bei der Auflösung des Labors zu bedienen, konnte ich unter anderem das LCD Keypad Shield für Arduino erhalten.



Technische Daten
Zunächst zu den technischen Daten des LCD Keypad Shield: HerstellerDF-RobotBetriebsspannung5VAbmessungen80 mm x 58 mmFeatures2x16 Zeilen LCD-Display, 1x Potentiometer zur Regulierung der Hintergrundbeleuchtung, 6 Taster (davon 1 Taster für RESET),
Aufbau des LCD Keypad Shield
Das Shield verfügt über ein 2x16 Zeichen LCD-Display und sechs Tasten, welche mit SELECT, LEFT, UP, DOWN, RIGHT und RST (Reset) beschriftet sind. Zusätzlich hast du ein Drehpotentiometer zum Regulieren der Hintergrundbeleuchtung.
Aufbau des LCD Keypad Shield von DF Robot Das Shield ist fertig aufgebaut auf einer Platine, welche du direkt auf einen Arduino UNO R3 / R4, Leonardo oder Mega 2560 R3 stecken kannst. Du kannst mit zusätzlichen Stiftleisten noch die freien Pins des Mikrocontrollers nach oben führen und so an diese Pins weitere Komponenten (Sensoren, Aktoren) anschließen.
Der Mega 2560 R3 hat deutlich mehr digitale & analoge Pins und somit verbleiben noch weitere für ein eventuelles Projekt mit dem LCD Keypad Shield.
Pinout des LCD Keypad Shield
Bevor wir dieses Shield programmieren können, müssen wir zunächst prüfen, an welche Pins die Taster und das LCD-Display angeschlossen ist. KomponenteArduino UNO R3LCD-DisplayRSD8EnableD9D4D4D5D5D6D6D7D7TasterA0 Analoge Werte der Tasten am LCD Keypad Shield Die Taster sind alle am analogen Pin A0 angeschlossen und liefern beim Betätigen jeweils unterschiedliche Werte. Über diese Werte kann man die betätigte Taste im Code quasi recht einfach erkennen. Tasteranaloger WertSELECT640LEFT409RIGHT0UP99DOWN256 Unterschiede bei Mikrocontrollern Für die Schaltung in diesem Beitrag verwende ich den originalen Arduino UNO R3, dieser ist deutlich wertiger aufgebaut als die einfachen China Klone. Durch die andere Verarbeitung sind auch die Werte, welche die Tasten beim Betätigen liefern etwas anders als wie bei besagten Mikrocontrollern auch China. Getestet habe ich die Werte mit: - dem originalem Arduino UNO R3, - dem Funduino UNO R3, - einem Noname China Klone, - dem Funduino Mega 2560 R3,
Programmieren des LCD Keypad Shield in der Arduino IDE
Die Programmierung erfolgt in der Arduino IDE wobei ich hier die aktuelle Version 2.0.x verwende. Du kannst die nachfolgenden Programme aber auch in der klassischen Version 1.8.x programmieren (welche unter Umständen etwas schneller ist). Schritt 1 - auslesen der Taster Mit nachfolgendem Code lesen wir zunächst die Werte der Tasten aus und geben diese auf der seriellen Schnittstelle aus. #define taster A0 void setup() { Serial.begin(9600); pinMode(taster, INPUT); } void loop() { Serial.println(analogRead(taster)); delay(250); } Das Shield habe ich hier an einen Funduino Mega 2560 angeschlossen und dieser liefert ein paar unterschiedliche Werte für die Tasten (um genau zu sagen, um eins versetzt).
analoge Werte der Tasten am LCD Keyad Shield
Schritt 2 - Programmieren des 2x16 LCD-Display
Wie du ein LCD-Display programmierst, habe ich dir bereits im Beitrag Arduino Lektion 7: LCD Display ansteuern erläutert, hier greife ich zunächst das Beispiel auf und zeige den Text "Hallo Welt!" auf der ersten Zeile und auf der zweiten Zeile die Buchstaben A bis P. #include //Das Display ist wiefolgt mit dem Shield / Mikrocontroller verbunden /** * rs > D8 * enabled > D9 * D4 > D4 * D5 > D5 * D6 > D6 * D7 > D7 **/ LiquidCrystal lcd(8, 9, 4, 5, 6, 7); void setup() { //Das LCD-Display mit 16 Zeichen und 2 Zeilen initialisieren //Die Bibliothek LiquidCrystal kann für viele LCD-Displays verwendet werden! lcd.begin(16, 2); //Erste Zeile mit dem Text "Hallo Welt!" belegen. lcd.print("Hallo Welt!"); //Die zweite Zeile soll mit den Buchstaben A bis P belegt werden. //Dafür legen wir uns eine Variable zeichen an und weisen dieser den Wert //65 zu dieser repräsentiert den ASCII Wert A siehe (https://draeger-it.blog/ascii-tabelle/) int zeichen = 65; for (int i = 0; i < 16; i++) { //Cursor an die Position i (aus der Schleife) und Zeile 1 setzen //die erste Zeile hat den Wert 0 und die zweite 1 lcd.setCursor(i, 1); //die Zahl in ein Charakter umwandeln lcd.print(char(zeichen)); //Die Zahl um eins erhöhen. zeichen++; //eine kleine Pause von 350ms delay(350); } } void loop() { //bleibt leer } Der obige Quellcode erzeugt die Ausgabe von "Hallo Welt!" in der ersten Zeile und die Buchstabenfolge von A bis P in der zweiten Zeile.
Beispiele für das LCD Keypad Shield am Arduino UNO R3
Nachdem ich dir jetzt gezeigt habe wie dieses Shield programmiert wird, möchte ich dir nun ein paar Beispiele aufzeigen welche du damit nachprogrammieren kannst. Beispiel 1- navigieren durch ein Array Mit den Navigationstasten kannst du recht einfach über ein Array navigieren und mit der Taste SELECT die Auswahl bestätigen. Im ersten Beispiel möchte ich dir gerne zeigen wie du durch die Werte eines Arrays navigieren kannst. #include //initialisieren des Displays LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //die Taster sind gemeinsam über den //analogen Pin A0 angeschlossen #define taster A0 //analoge Werte der Taster const int SELECT = 640; const int LEFT = 409; const int RIGHT = 0; const int UP = 99; const int DOWN = 256; //Aufbau des Menüs //maximale Anzahl der Einträge im Array const int NUM_MENU_ITEMS = 4; //aktueller Index int index = -1; //das Menü String menu = { "Eintrag 1", "Eintrag 2", "Eintrag 3", "Eintrag 4" }; //Feld für den Wert des Tasters welcher betätigt wurde. int tasterValue = -1; void setup() { //das LCD-Display hat 2 Zeilen mit maximal 16 Zeichen pro Zeile lcd.begin(16, 2); //der Index ist initial auf -1 gesetzt, //die Funktion displayMenuItem prüft anhand des Indexes und der gegebenen //Richtung welche Einträge angezeigt werden sollen displayMenuItem(true); } void loop() { //auslesen des analogen Wertes, dieser ändert sich je nach Taster tasterValue = analogRead(taster); //prüfen welcher Taster betätigt wurde switch (tasterValue) { case UP: displayMenuItem(false); break; case DOWN: displayMenuItem(true); break; case SELECT: doSomething(); break; } } //Diese Funktion zeigt zwei Daten auf dem LCD-Display an, abhängig //von dem Index und der Richtung welche navigiert werden soll. void displayMenuItem(bool directionDown) { //leeren des Displays lcd.clear(); //Zeile 2 soll den Inhalt "-ENDE-" haben wenn das Ende des Menüs erreicht wurde. String line2 = "-ENDE-"; //Wenn der Wert des Parameters //directionDown Wahr/True ist UND //der Wert vom index kleiner als die maximale Anzahl der Menüeinträge -1 ist, dann... if (directionDown && index < NUM_MENU_ITEMS - 1) { index++; } else if (!directionDown && index > 0) { index--; } //Die erste Zeile enthält den Text aus dem Menü mit dem Wert index. //Der erste Eintrag im Array hat den Eintrag 0! String line1 = menu; //prüfen ob das Ende des Menüs / Arrays erreicht wurde if (index < NUM_MENU_ITEMS - 1) { line2 = menu; } //Anzeigen der Daten auf dem Display lcd.setCursor(0, 0); lcd.print(">" + line1); lcd.setCursor(0, 1); lcd.print(" " + line2); //eine kleine Pause von 250ms um die Taster zu entprellen delay(250); } void doSomething() { //eine kleine Pause von 250ms um die Taster zu entprellen delay(250); } Mit den beiden Tasten UP & DOWN können wir nun durch das Menü navigieren. Die Taste SELECT wurde im Code bereits eingebunden, hat jedoch derzeit noch keine Funktion. Beispiel 2 - Aktivieren / Deaktivieren von LEDs über ein Menü Ein einfaches Beispiel ist das Schalten von LEDs. Im nachfolgenden Beispiel möchte ich vier LEDs über das Menü Aktivieren bzw. Deaktivieren. Statt einer LED kannst du auch ein Relais schalten und somit andere Verbraucher steuern.
LEDLCD Keypad ShieldGelbD2BlauD3RotD11GrünD12Kathode / GNDGND Der Quellcode ist etwas länger geworden da ich hier eine Struktur für die LEDs implementiert habe welche die Daten für die Pins, den aktuellen Status sowie den Menüeintrag beinhalten. struct MenuItem { int ledPin; bool ledStatus; String caption; }; Damit können wir nun über einen sprechenden Namen auf die jeweilige LED zugreifen aber auch unser Menü aufbauen. MenuItem mILedGelb = { 2, false, "LED Gelb" }; MenuItem mILedBlau = { 3, false, "LED Blau" }; MenuItem mILedRot = { 11, false, "LED Rot" }; MenuItem mILedGruen = { 12, false, "LED Gruen" }; //maximale Anzahl der Einträge im Array const int NUM_MENU_ITEMS = 4; //das Menü MenuItem menu = { mILedGelb, mILedBlau, mILedRot, mILedGruen }; Der komplette Quellcode zum steuern von LEDs über ein Menü am LCD Keypad Shield: #include //initialisieren des Displays LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //die Taster sind gemeinsam über den //analogen Pin A0 angeschlossen #define taster A0 //analoge Werte der Taster const int SELECT = 640; const int LEFT = 409; const int RIGHT = 0; const int UP = 99; const int DOWN = 256; //Feld für den Wert des Tasters welcher betätigt wurde. int tasterValue = -1; //Aufbau des Menüs //aktueller Index int index = -1; //Struktur für ein Menüeintrag struct MenuItem { int ledPin; //der Pin der LED bool ledStatus; //der Status String caption; //Text für das Menü }; //initialisieren der Menüeinträge MenuItem mILedGelb = { 2, false, "LED Gelb" }; MenuItem mILedBlau = { 3, false, "LED Blau" }; MenuItem mILedRot = { 11, false, "LED Rot" }; MenuItem mILedGruen = { 12, false, "LED Gruen" }; //maximale Anzahl der Einträge im Array const int NUM_MENU_ITEMS = 4; //das Menü MenuItem menu = { mILedGelb, mILedBlau, mILedRot, mILedGruen }; void setup() { //Pins der LEDs als Ausgang definieren pinMode(mILedGelb.ledPin, OUTPUT); pinMode(mILedBlau.ledPin, OUTPUT); pinMode(mILedRot.ledPin, OUTPUT); pinMode(mILedGruen.ledPin, OUTPUT); //das LCD-Display hat 2 Zeilen mit maximal 16 Zeichen pro Zeile lcd.begin(16, 2); //der Index ist initial auf -1 gesetzt, //die Funktion displayMenuItem prüft anhand des Indexes und der gegebenen //Richtung welche Einträge angezeigt werden sollen displayMenuItem(true, false); } void loop() { //auslesen des analogen Wertes, dieser ändert sich je nach Taster tasterValue = analogRead(taster); //prüfen welcher Taster betätigt wurde switch (tasterValue) { case UP: displayMenuItem(false, false); break; case DOWN: displayMenuItem(true, false); break; case SELECT: doSomething(); break; } } //Diese Funktion zeigt zwei Daten auf dem LCD-Display an, abhängig //von dem Index und der Richtung welche navigiert werden soll. //Parameter updateOnly steuert ob der Index erhöht oder verringert werden soll, //bei true wird der Abschnitt übersprungen void displayMenuItem(bool directionDown, bool updateOnly) { //leeren des Displays lcd.clear(); //Zeile 2 soll den Inhalt "-ENDE-" haben wenn das Ende des Menüs erreicht wurde. String line2 = "-ENDE-"; if (!updateOnly) { //Wenn der Wert des Parameters //directionDown Wahr/True ist UND //der Wert vom index kleiner als die maximale Anzahl der Menüeinträge -1 ist, dann... if (directionDown && index < NUM_MENU_ITEMS - 1) { index++; } else if (!directionDown && index > 0) { index--; } } //Die erste Zeile enthält den Text aus dem Menü mit dem Wert index. //Der erste Eintrag im Array hat den Eintrag 0! MenuItem& itemLine1 = menu; //prüfen ob das Ende des Menüs / Arrays erreicht wurde lcd.setCursor(0, 1); if (index < NUM_MENU_ITEMS - 1) { MenuItem itemLine2 = menu; lcd.print(" " + itemLine2.caption + getLEDStatus(itemLine2.ledStatus)); } else { lcd.print("-ENDE-"); } //Anzeigen der Daten auf dem Display lcd.setCursor(0, 0); lcd.print(">" + itemLine1.caption + getLEDStatus(itemLine1.ledStatus)); Serial.println(itemLine1.ledStatus); //eine kleine Pause von 250ms um die Taster zu entprellen delay(250); } //Liefert anhand des boolschen Wertes einen Text //bei true wird " AN", //bei false wird " AUS" geliefert String getLEDStatus(bool status) { String result = " "; if (status == true) { result += "AN"; } else { result += "AUS"; } return result; } //Führt eine Aktion aus void doSomething() { //Wichtig ist das wir das MenuItem aus dem Array mit //einem & entnehmen, damit holen wir uns keine Kopie //sondern eine Referenz. Dieses wird benötigt, da wir //den Status der LED togglen und speichern wollen. MenuItem& item = menu; //umkehren des Status der LED item.ledStatus = !item.ledStatus; //schreiben des aktuellen Status an die LED digitalWrite(item.ledPin, item.ledStatus); //aktualisieren des Displays displayMenuItem(true, true); //eine kleine Pause von 250ms um die Taster zu entprellen delay(250); } Über das Menü können wir nun jede LED einzeln ansteuern und Aktivieren bzw. Deaktiviern. Beispiel 3 - schalten von Relais über ein Menü Ich kann quasi schon den Kommentar erahnen "Wie mache ich das mit Relais?". Daher gleich als nächstes das Beispiel mit einem Relaisshield. Zunächst passen wir die Struktur des MenuItems für eine allgemeingültige Form an. //Struktur für ein Menüeintrag struct MenuItem { int pin; //der Pin bool status; //der Status String caption; //Text für das Menü }; In meinem Fall erstelle ich zwei Menüeinträge, zum einen für eine Gartenpumpe und für eine Lampe. //initialisieren der Menüeinträge MenuItem mI1 = { 2, true, "Gartenpumpe" }; MenuItem mI2 = { 3, true, "Lampe" }; //maximale Anzahl der Einträge im Array const int NUM_MENU_ITEMS = 2; //das Menü MenuItem menu = { mI1, mI2 }; Relais haben eine besonderheit diese sind bei einem aktiven Pin deaktiviert und bei einem deaktivierten Pin aktiviert. Dazu lege ich mir eine Variable an mit welcher man dieses übersteuern kann und somit der Code wiederverwendet werden kann. bool defaultDeactive = true; Das macht es nun möglich den Code im grunde zu belassen und wir brauchen lediglich unser Menü aufbauen. #include //initialisieren des Displays LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //die Taster sind gemeinsam über den //analogen Pin A0 angeschlossen #define taster A0 //analoge Werte der Taster const int SELECT = 640; const int LEFT = 409; const int RIGHT = 0; const int UP = 99; const int DOWN = 256; //Feld für den Wert des Tasters welcher betätigt wurde. Read the full article
0 notes
Video
Running text with LCD Keypad shield controlled by Arduino #arduino #lcd #lcdkeypadshield #microcontroller #diy #electronics
0 notes
Video
Detects the distance of the closest object in front of HC-SR04 ultrasonic sensor. It emits ultrasonic wave at 40 000 Hz through the air. If there is an object or obstacle on its path It will bounce back to the sensor. #microcontrollers #electronics #pcb #lcd #lcdkeypadshield #ultrasonic #sensor #ultrasonicsensor #c
0 notes