Inhaltsverzeichnis:

Ein Menü in Arduino und die Verwendung von Schaltflächen - Gunook
Ein Menü in Arduino und die Verwendung von Schaltflächen - Gunook

Video: Ein Menü in Arduino und die Verwendung von Schaltflächen - Gunook

Video: Ein Menü in Arduino und die Verwendung von Schaltflächen - Gunook
Video: ARDUINO BASICS #22 - 3 BUTTON LCD MENÜ 2024, November
Anonim
Ein Menü in Arduino und die Verwendung von Schaltflächen
Ein Menü in Arduino und die Verwendung von Schaltflächen

In meinem Arduino 101-Tutorial erfahren Sie, wie Sie Ihre Umgebung in Tinkercad einrichten. Ich benutze Tinkercad, weil es eine ziemlich leistungsstarke Online-Plattform ist, die es mir ermöglicht, den Schülern eine Reihe von Fähigkeiten zum Bauen von Schaltungen zu demonstrieren. Fühlen Sie sich frei, alle meine Tutorials mit der Arduino IDE und einem echten Arduino zu erstellen!

In diesem Tutorial lernen wir Schaltflächen kennen! Wir müssen wissen:

  • So verkabeln Sie sie
  • Lesen ihres Wertes
  • Entprellen und warum es wichtig ist
  • Eine praktische Anwendung (Erstellen eines Menüs)

Die meisten Leute denken, dass es am praktischsten ist, mit einem Knopf ein Licht ein- und auszuschalten. Wir werden, nicht hier! Wir werden unseres verwenden, um ein Menü zu erstellen und einige Optionen auf dem Arduino einzustellen.

Bereit? Lass uns anfangen!

Schritt 1: Einrichten des Boards

Das Board einrichten
Das Board einrichten
Das Board einrichten
Das Board einrichten

Der erste Schritt besteht darin, ein Arduino und ein Breadboard Small auf den Prototyping-Bereich zu legen. Sehen Sie sich die Bilder oben an, um zu sehen, wie Sie die Stromschienen verdrahten.

Ein Breadboard Mini hat oben und unten zwei Stromschienen. Wir verdrahten diese mit dem Arduino, damit wir mehr Komponenten mit Strom versorgen können. Später in diesem Tutorial werden wir 3 Tasten verwenden, damit wir mehr Leistung benötigen. Zu beachten ist, dass auf einem kleinen Steckbrett die Stromschienen horizontal über die Platine verlaufen. Dies unterscheidet sich von den Spalten im Hauptprototyping-Bereich in der Mitte; diese verlaufen vertikal. Sie können jeden der Power-Pins verwenden, um jede Säule im Hauptbereich in der Mitte mit Strom zu versorgen.

Verwenden Sie beim Hinzufügen von Strom schwarze und rote Drähte zum Minus- bzw. Pluspol. Fügen Sie am Ende Drähte hinzu, die die andere Seite der Platine mit Strom versorgen. Wir werden diese Seite nicht nutzen, aber es ist eine gute Praxis.

Schritt 2: Schaltfläche und Widerstand hinzufügen

Fügen Sie die Taste und den Widerstand hinzu
Fügen Sie die Taste und den Widerstand hinzu
Fügen Sie die Taste und den Widerstand hinzu
Fügen Sie die Taste und den Widerstand hinzu
Fügen Sie die Taste und den Widerstand hinzu
Fügen Sie die Taste und den Widerstand hinzu

Fügen Sie eine kleine Drucktaste aus dem Komponentenfach hinzu. Es sollte wie auf dem Bild aussehen. Stellen Sie sicher, dass es kein Schalter ist! Fügen Sie auch einen Widerstand hinzu. Klicken Sie darauf und stellen Sie den Wert auf 10kΩ ein. Das reicht aus, um den Pin nach unten zu ziehen, wenn er nicht angeschlossen ist, was später im Code sehr wichtig ist.

Legen Sie die Komponente über die Mitte des Steckbretts. Die Funktionsweise einer Schaltfläche ist:

  • Ecke zu Ecke, die Schaltfläche ist nicht verbunden. Durch Drücken des Knopfes werden die Kontakte geschlossen und die Ecken verbunden.
  • Die Seiten der Taste sind verbunden. Wenn Sie oben links und unten links einen Draht anschließen, wäre der Stromkreis geschlossen.

Deshalb legen wir das Bauteil mittig über den Raum. Es stellt sicher, dass die Ecken nicht unter den Pins in der Platine verbunden sind.

Der nächste Schritt bietet ein paar Bilder, die diese Punkte veranschaulichen.

Platzieren Sie den Widerstand vom unteren rechten Stift über die Spalten, so dass er horizontal sitzt.

Schritt 3: Tastenverbindungen

Tastenverbindungen
Tastenverbindungen
Tastenverbindungen
Tastenverbindungen

Die obigen Bilder machen ziemlich deutlich, wie die Tasten verbunden sind. Es war immer ein Punkt der Verwirrung, wenn man denkt, dass etwas alles gut ist und es nicht funktioniert!

Jetzt fügen wir die Drähte hinzu.

  • Platzieren Sie eine rote Leitung von einem positiven Stromstift in dieselbe Spalte wie der untere rechte Stift auf der Taste
  • Platzieren Sie eine schwarze Leitung von einem negativen Stromstift in dieselbe Spalte wie der Widerstand.
  • Legen Sie einen farbigen Draht (nicht rot / schwarz) vom oberen linken Pin zum Digital Pin 2 auf dem Arduino

Überprüfen Sie die obigen Bilder, um sicherzustellen, dass Ihre Verkabelung korrekt ist.

Schritt 4: Der Code…

Der Code…
Der Code…
Der Code…
Der Code…

Schauen wir uns den Code für eine einfache Schaltfläche an.

Öffnen Sie den Code-Editor und wechseln Sie von Blöcken zu Text. Löschen Sie die angezeigte Warnung. Wir freuen uns über Text!

Sie kennen die grundlegende Einrichtung, also definieren wir die Schaltfläche und führen eine grundlegende Lesung durch. Wir drucken die Ausgabe auf Serial.

Ich habe ein paar zusätzliche Kommentare in den Code unten eingefügt, damit er leichter zu lesen ist als das Bild.

// Konstanten definieren

#define-Taste 2 Void setup () { PinMode (Taste, INPUT); Serial.begin (9600); aufrechtzuerhalten. Void Schleife () {// Lesen Sie den digitalen Pin, um den Status der Schaltfläche zu überprüfen Int gedrückt = digitalRead (Schaltfläche); // Taste gibt HIGH zurück, wenn sie gedrückt wird, LOW, wenn nicht, wenn (gedrückt == HIGH) { Serial.println ("Gedrückt!"); } }

Okay, das funktioniert!

Im Wesentlichen überprüfen wir nur den Status des digitalen Pins bei jeder Codeschleife. Wenn Sie auf Simulation starten klicken und die Schaltfläche drücken, sehen Sie im Serial Monitor (klicken Sie auf die Schaltfläche unter dem Code) die Anzeige "Gedrückt!" wiederholt.

Eine Funktion, die Sie im obigen Code sehen werden, ist die stattfindende if()-Bedingungsauswertung. Der Code stellt in diesem Fall nur eine Frage und bewertet, ob sie wahr ist. Wir verwenden das Gleichheitszeichen (doppelte Gleichheitszeichen, wie folgt: ==), um zu überprüfen, ob der Wert der Variablen einem bestimmten Wert entspricht. Ein digitalRead() gibt entweder HIGH oder LOW zurück.

Mit if () else if / else können wir viele Bedingungen oder alle Bedingungen überprüfen, und wenn Sie zu den Arduino-Grundlagen zurückkehren, sehen Sie einige der Vergleiche, die Sie anstellen können.

Nun… Unser Code sieht vielleicht vollständig aus… Aber wir haben ein Problem.

Sehen Sie, das funktioniert im Simulator wirklich gut. Aber echte Elektrizität hat Rauschen, insbesondere Gleichstromelektronik. Daher kann unsere Schaltfläche manchmal einen falschen Messwert zurückgeben. Und das ist ein Problem, denn Ihr Projekt reagiert möglicherweise nicht richtig für den Benutzer.

Lass es uns reparieren!

Schritt 5: Eine kleine Entprellung

Eine kleine Entprellung
Eine kleine Entprellung

Wir verwenden ein Verfahren namens Debounce, um unser Schaltflächenproblem zu lösen. Dies wartet im Wesentlichen eine bestimmte Zeit zwischen dem Drücken der Taste und der tatsächlichen Reaktion auf den Druck. Es fühlt sich für den Benutzer immer noch natürlich an (es sei denn, Sie machen die Zeit zu lang). Sie können es auch verwenden, um die Presslänge zu überprüfen, sodass Sie jedes Mal anders reagieren können. Sie müssen nichts an der Verkabelung ändern!

Schauen wir uns den Code an:

#define-Taste 2#define debounceTimeout 100

Die erste Änderung betrifft den globalen Geltungsbereich. Sie werden sich erinnern, dass wir dort Variablen definieren, die viele unserer Funktionen verwenden könnten oder die nicht jedes Mal zurückgesetzt werden können, wenn die Schleife ausgelöst wird. Also haben wir debounceTimeout zu den definierten Konstanten hinzugefügt. Wir haben diese 100 gemacht (was später in 100 ms übersetzt wird), aber sie könnte kürzer sein. Länger und es wird sich unnatürlich anfühlen.

long int lastDebounceTime;

Diese Variable wird unterhalb der Konstanten deklariert. Dies ist ein langer int-Typ, der es uns im Grunde ermöglicht, lange Zahlen im Speicher zu speichern. Wir nannten es lastDebounceTime.

Wir müssen nichts an der Funktion void setup() ändern. Lassen wir das.

Void Schleife () {// Lesen Sie den digitalen Pin, um den Status der Schaltfläche zu überprüfen Int gedrückt = digitalRead (Schaltfläche); long int currentTime = millis(); // Tastencode }

Die erste Änderung, die wir in der Funktion loop() vornehmen, ist der Aufruf zum Lesen der Schaltfläche. Wir müssen die aktuelle Uhrzeit im Auge behalten. Die Funktion millis() gibt die aktuelle Uhrzeit der Uhr seit dem Hochfahren des Arduino in Millisekunden zurück. Wir müssen dies in einer Variablen vom Typ long int speichern.

Jetzt müssen wir sicherstellen, dass wir die Zeit seit dem Drücken der Taste kennen, also setzen wir den Timer zurück, wenn er nicht gedrückt wird. Schau mal:

Void Schleife () {// Lesen Sie den digitalen Pin, um den Status der Schaltfläche zu überprüfen Int gedrückt = digitalRead (Schaltfläche); long int currentTime = millis(); if (pressed == LOW) {// Zurücksetzen der Zählzeit, während die Taste nicht gedrückt wird lastDebounceTime = currentTime; } // Tastencode }

Der if(pressed == LOW)-Algorithmus prüft, ob die Schaltfläche nicht gedrückt ist. Ist dies nicht der Fall, speichert der Code die aktuelle Zeit seit der letzten Entprellung. Auf diese Weise haben wir bei jedem Drücken der Taste einen Zeitpunkt, ab dem wir überprüfen können, wann die Taste gedrückt wurde. Wir können dann eine schnelle mathematische Berechnung durchführen, um zu sehen, wie lange die Taste gedrückt wurde, und richtig reagieren. Schauen wir uns den Rest des Codes an:

Void Schleife () {// Lesen Sie den digitalen Pin, um den Status der Schaltfläche zu überprüfen Int gedrückt = digitalRead (Schaltfläche); long int currentTime = millis(); if (pressed == LOW) {// Zurücksetzen der Zählzeit, während die Taste nicht gedrückt wird lastDebounceTime = currentTime; } // Button wurde für eine bestimmte Zeit gedrückt if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Wenn der Timeout erreicht ist, Button gedrückt! Serial.println ("Gedrückt!"); } }

Der letzte Codeblock nimmt die aktuelle Zeit, subtrahiert die letzte Entprellzeit und vergleicht sie mit dem von uns eingestellten Timeout. Ist sie größer, geht der Code davon aus, dass die Taste für diese Zeit gedrückt wurde und antwortet. Sauber!

Führen Sie Ihren Code aus und überprüfen Sie, ob er funktioniert. Wenn Sie Fehler haben, überprüfen Sie Ihren Code!

Schauen wir uns nun ein praktisches Beispiel an.

Schritt 6: Die Erstellung eines Menüs

Die Herstellung eines Menüs
Die Herstellung eines Menüs

Buttons sind interessant, weil es so viele Möglichkeiten mit ihnen gibt! In diesem Beispiel erstellen wir ein Menü. Nehmen wir an, Sie haben dieses wirklich großartige Gerät entwickelt und möchten, dass Benutzer Optionen ändern können, um bestimmte Dinge ein- oder auszuschalten oder einen bestimmten Wert für eine Einstellung festzulegen. Dieses Design mit drei Knöpfen kann das!

Für dieses Projekt benötigen wir also:

  • Drei Tasten
  • Drei Widerstände auf 10kΩ. eingestellt

Eines davon haben wir bereits, wir brauchen nur die anderen beiden. Fügen Sie diese also dem Board hinzu. Die Verkabelung ist etwas aufwendiger, aber nur, weil ich es wirklich kompakt halten wollte. Sie können dem gleichen Muster für die erste Schaltfläche oder dem obigen Bild folgen.

Die drei Schaltflächen sind eine Menüoption zum Öffnen/Nächsten, eine Änderungsoption (wie in, die Einstellung ändern) und eine Menüschaltfläche speichern/schließen.

Verdrahten Sie es, schauen wir uns den Code an!

Schritt 7: Codeaufschlüsselung - Global

Ok, das wird ein langer Schritt, aber ich werde jeden Codeabschnitt durchgehen.

Schauen wir uns zunächst die benötigten globalen Variablen an.

// Konstanten definieren#define menuButton 2 #define menuSelect 3#define menuSave 4 #define debounceTimeout 50 // Variablen definieren int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; long int lastDebounceTime; // Menüoptionen char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0;

Diese drei Blöcke sind dem, was wir zuvor gesehen haben, ziemlich ähnlich. Im ersten habe ich die drei Buttons und das Timeout definiert. Für diesen Teil des Projekts habe ich es auf 50 ms eingestellt, damit es ein bewusstes Drücken erfordert, damit es funktioniert.

Der zweite Block enthält alle Variablen. Wir müssen den ButtonPreviousState und die lastDebounceTime verfolgen. Dies sind alles Variablen vom Typ int, aber der letzte ist ein langer Typ, da ich davon ausgehe, dass wir den Platz im Speicher benötigen.

Der Menüoptionsblock enthält einige neue Funktionen. Zuerst das char * (ja, das ist ein absichtliches Sternchen), das eine Literalvariable für Zeichen/Zeichenfolgen ist. Es ist ein Zeiger auf einen statischen Speicher im Speicher. Sie können es nicht ändern (wie zum Beispiel in Python). Diese Zeile char *menuOptions erstellt ein Array von String-Literalen. Sie können beliebig viele Menüpunkte hinzufügen.

Die Variable bool featureSetting ist nur das Array von Werten, die jedes Menüelement darstellen. Ja, Sie können alles speichern, was Sie möchten, ändern Sie einfach den Variablentyp (sie müssen alle den gleichen Typ haben). Nun, es könnte bessere Möglichkeiten geben, dies zu verwalten, wie Wörterbücher oder Tupel, aber dies ist für diese Anwendung einfach. Ich würde wahrscheinlich eines der letzteren in einer bereitgestellten Anwendung erstellen.

Ich habe den menuMode im Auge behalten, wenn ich also andere Dinge auf meinem Display haben wollte, könnte ich das tun. Wenn ich eine Sensorlogik hätte, könnte ich das während der Menübedienung pausieren, nur für den Fall, dass etwas kollidiert. Ich habe eine menuNeedsPrint-Variable, weil ich das Menü zu bestimmten Zeiten drucken möchte, nicht nur die ganze Zeit. Schließlich habe ich eine OptionSelected-Variable, damit ich die ausgewählte Option verfolgen kann, wenn ich an mehreren Stellen darauf zugreife.

Schauen wir uns den nächsten Satz von Funktionen an.

Schritt 8: Code-Aufschlüsselung - Setup und benutzerdefinierte Funktionen

Die Funktion setup() ist einfach genug, nur drei Eingabedeklarationen:

Void setup () { pinMode (menuSelect, INPUT); pinMode (MenüSpeichern, INPUT); pinMode (Menüauswahl, EINGANG); Serial.begin (9600); }

Als nächstes sind die drei benutzerdefinierten Funktionen. Betrachten wir die ersten beiden, dann die letzte getrennt.

Wir benötigen zwei Funktionen, die einige Informationen zurückgeben. Der Grund ist, dass wir sicherstellen möchten, dass dies für Menschen lesbar ist. Es hilft auch beim Debuggen des Codes, wenn wir ein Problem haben. Code:

// Funktion zum Zurückgeben der aktuell ausgewählten Optionchar *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // RückgabeoptionSelected return menuOption; } // Funktion zum Zurückgeben des Status der aktuell ausgewählten Option char *ReturnOptionStatus(){ bool optionSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionSettingVal = "False"; }sonst{ optionSettingVal = "Wahr"; } // RückgabeoptionSetting return optionSettingVal; }

Die Funktion char *ReturnOptionSelected() überprüft die ausgewählte Option (wenn Sie oben sehen, setzen wir eine Variable, um dies zu verfolgen) und ruft das String-Literal aus dem zuvor erstellten Array ab. Es gibt es dann als char-Typ zurück. Wir wissen dies, weil die Funktion den Rückgabetyp angibt.

Die zweite Funktion, char *ReturnOptionStatus(), liest den Status der im Array gespeicherten Option und gibt ein String-Literal zurück, das den Wert darstellt. Wenn die von uns gespeicherte Einstellung beispielsweise false ist, würde ich "False" zurückgeben. Dies liegt daran, dass wir dem Benutzer diese Variable zeigen und es besser ist, all diese Logik zusammenzuhalten. Ich könnte es später tun, aber es ist sinnvoller, es hier zu tun.

// Funktion zum Umschalten der aktuellen Optionbool ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; true zurückgeben; }

Die Funktion bool ToggleOptionSelected() ist eine Komfortfunktion, um den Wert der im Menü ausgewählten Einstellung zu ändern. Es dreht nur den Wert um. Wenn Sie einen komplexeren Satz von Optionen hätten, könnte dies ganz anders aussehen. Ich gebe in dieser Funktion true zurück, weil mein Callback (der Aufruf später im Code, der diese Funktion auslöst) eine true/false-Antwort erwartet. Ich bin mir zu 100% sicher, dass dies funktioniert, daher habe ich nicht berücksichtigt, dass es nicht funktioniert, aber ich würde es in einer bereitgestellten Anwendung tun (nur für den Fall).

Schritt 9: Die Schleife…

Die Funktion loop() ist ziemlich lang, daher werden wir sie in Teilen ausführen. Sie können innerhalb dieser Funktion alles unter Nestern annehmen:

Leere Schleife () {

// Arbeite hier ein <----- }

Ok, das Zeug haben wir schon gesehen:

// Die Tasten lesen Int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead(menuSelect); int menuSavePressed = digitalRead(menuSave); // Hole die aktuelle Zeit long int currentTime = millis(); if(menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {//Zählzeit zurücksetzen, während die Taste nicht gedrückt wird lastDebounceTime = currentTime; menuButtonPreviousState = NIEDRIG; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }

Alles, was ich hier tun musste, war, die drei digitalRead()-Aufrufe hinzuzufügen und sicherzustellen, dass ich, wenn alle Schaltflächen niedrig waren, den Timer (lastDebounceTime = currentTime) zurücksetzen und alle vorherigen Zustände auf niedrig setzen sollten. Ich speichere auch millis() in currentTime.

Der nächste Abschnitt verschachtelt sich innerhalb der Linie

if(((currentTime - lastDebounceTime) > debounceTimeout)){

// Arbeite hier drin <---- }

Es gibt drei Abschnitte. Ja, ich hätte sie in ihre eigenen Funktionen verschieben können, aber der Einfachheit halber habe ich die drei wichtigsten Tastenalgorithmen hier belassen.

if((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)){ if(menuMode == false){ menuMode = true; // Informieren Sie den Benutzer Serial.println ("Menü ist aktiv"); } Else if (menuMode == true && optionSelected = 1) {// Option zurücksetzen optionSelected = 0; } // Menü ausgeben menuNeedsPrint = true; // Umschalten der Schaltfläche prev. Zustand, um nur das Menü anzuzeigen // wenn die Taste losgelassen und erneut gedrückt wird menuButtonPreviousState = menuButtonPressed; // Wäre HOCH }

Dieser erste behandelt, wenn menuButtonPressed HIGH ist oder wenn die Menütaste gedrückt wird. Es überprüft auch, ob der vorherige Zustand LOW war, sodass die Taste vor dem erneuten Drücken losgelassen werden musste, was verhindert, dass das Programm ständig das gleiche Ereignis immer wieder auslöst.

Es überprüft dann, ob das Menü aktiviert wird, wenn es nicht aktiv ist. Es wird die erste ausgewählte Option gedruckt (was standardmäßig das erste Element im Array menuOptions ist. Wenn Sie die Taste ein zweites oder drittes Mal (usw.) drücken, erhalten Sie die nächste Option in der Liste. Etwas, das ich beheben könnte, ist dass, wenn es das Ende erreicht, es zum Anfang zurückkehrt. Dies könnte die Länge des Arrays lesen und das Zurückfahren erleichtern, wenn Sie die Anzahl der Optionen ändern, aber das war für den Moment einfach.

Der letzte kleine Abschnitt (//Druckt das Menü) druckt offensichtlich das Menü, setzt aber auch den vorherigen Zustand auf HIGH, damit dieselbe Funktion nicht wiederholt wird (siehe meine Anmerkung oben zum Überprüfen, ob die Schaltfläche zuvor LOW war).

// menuSelect ist gedrückt, liefere logicif((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Ändere die gewählte Option // Im Moment ist dies nur wahr/falsch // aber könnte alles sein bool toggle = ToggleOptionSelected(); if (toggle) { menuNeedsPrint = true; } sonst { Serial.println ("Etwas ist schief gelaufen. Bitte versuchen Sie es erneut"); } } // Zustand umschalten, um nur umzuschalten, wenn losgelassen und erneut gedrückt wird menuSelectPreviousState = menuSelectPressed; }

Dieser Code behandelt die Schaltfläche menuSelectPressed auf die gleiche Weise, außer dass wir diesmal nur die Funktion ToggleOptionSelected() auslösen. Wie ich bereits sagte, können Sie diese Funktion ändern, damit sie mehr tut, aber das ist alles, was ich brauche.

Die wichtigste zu beachtende Sache ist die Toggle-Variable, die den Erfolg des Callbacks verfolgt und das Menü ausgibt, wenn es wahr ist. Wenn nichts oder false zurückgegeben wird, wird die Fehlermeldung ausgegeben. Hier können Sie Ihren Rückruf für andere Dinge verwenden.

if((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)){ // Verlassen des Menüs // Hier könnte man aufräumen // oder im EEPROM speichern menuMode = false; Serial.println ("Menü verlassen"); // Zustand umschalten, damit das Menü nur einmal beendet wird menuSavePreviousState = menuSavePressed; } }

Diese Funktion behandelt die Schaltfläche menuSave, die das Menü nur verlässt. Hier könnten Sie eine Option zum Abbrechen oder Speichern haben, vielleicht etwas aufräumen oder im EEPROM speichern. Ich drucke einfach "Menü verlassen" und setze den Schaltflächenstatus auf HOCH, damit es nicht wiederholt wird.

if(menuMode && menuNeedsPrint){ // Wir haben das Menü gedruckt, also wenn nicht etwas // passiert, muss es nicht erneut gedruckt werden menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Ausgewählt:"); Serial.print (optionActive); Serial.print (: "); Serial.print (optionStatus); Serial.println(); }

Dies ist der menuPrint-Algorithmus, der nur ausgelöst wird, wenn das Menü aktiv ist und die Variable menuNeedsPrint auf true gesetzt ist.

Dies könnte definitiv in eine eigene Funktion verschoben werden, aber der Einfachheit halber..!

Das war's! Siehe den nächsten Schritt für den gesamten Codeblock.

Schritt 10: Endgültiger Codeblock

// Konstanten definieren

#define menuButton 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Variablen definieren long int lastDebounceTime; bool lightSensor = true; bool tempSensor = true; // Menüoptionen char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0; // Setup-Funktion

Void setup () { pinMode (menuSelect, INPUT); pinMode (MenüSpeichern, INPUT); pinMode (Menüauswahl, EINGANG); Serial.begin (9600); }

// Funktion zum Zurückgeben der aktuell ausgewählten Option char *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // RückgabeoptionSelected return menuOption; } // Funktion zum Zurückgeben des Status der aktuell ausgewählten Option char *ReturnOptionStatus(){ bool optionSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionSettingVal = "False"; }sonst{ optionSettingVal = "Wahr"; } // RückgabeoptionSetting return optionSettingVal; } // Funktion zum Umschalten der aktuellen Option bool ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; true zurückgeben; } // Die Hauptschleife

Void loop () {// Lesen Sie die Schaltflächen Int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead(menuSelect); int menuSavePressed = digitalRead(menuSave); // Hole die aktuelle Zeit long int currentTime = millis(); if(menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {//Zählzeit zurücksetzen, während die Taste nicht gedrückt wird lastDebounceTime = currentTime; menuButtonPreviousState = NIEDRIG; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Wenn das Timeout erreicht ist, Taste gedrückt!

// menuButton ist gedrückt, Logik bereitstellen

// Wird nur ausgelöst, wenn die Taste zuvor losgelassen wurde if((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)){ if(menuMode == false){ menuMode = true; // Informieren Sie den Benutzer Serial.println ("Menü ist aktiv"); } Else if (menuMode == true && optionSelected = 1) {// Option zurücksetzen optionSelected = 0; } // Menü ausgeben menuNeedsPrint = true; // Umschalten der Schaltfläche prev. Zustand, um nur das Menü anzuzeigen // wenn die Taste losgelassen und erneut gedrückt wird menuButtonPreviousState = menuButtonPressed; // Wäre HIGH } // menuSelect wird gedrückt, Logik bereitstellen if((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Gewählte Option ändern // Im Moment ist dies nur true/false // könnte aber alles sein bool toggle = ToggleOptionSelected(); if (toggle) { menuNeedsPrint = true; } sonst { Serial.print ("Etwas ist schief gelaufen. Bitte versuchen Sie es erneut"); } } // Zustand umschalten, um nur umzuschalten, wenn losgelassen und erneut gedrückt wird menuSelectPreviousState = menuSelectPressed; } if((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)){ // Verlassen des Menüs // Hier können Sie aufräumen // oder im EEPROM speichern menuMode = false; Serial.println ("Menü verlassen"); // Zustand umschalten, damit das Menü nur einmal beendet wird menuSavePreviousState = menuSavePressed; } } // Die aktuelle aktive Menüoption ausgeben, aber nur einmal drucken if(menuMode && menuNeedsPrint){ // Wir haben das Menü gedruckt, also wenn nicht etwas // passiert, muss es nicht erneut gedruckt werden menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Ausgewählt:"); Serial.print (optionActive); Serial.print (: "); Serial.print (optionStatus); Serial.println(); } } }

Die Strecke ist auf der Tinkercad-Website verfügbar. Ich habe die Schaltung unten eingebettet, damit Sie sie auch sehen können!

Bei Fragen oder Problemen lasst es mich wie immer wissen!

Empfohlen: