Indholdsfortegnelse:

En menu i Arduino, og hvordan man bruger knapper: 10 trin (med billeder)
En menu i Arduino, og hvordan man bruger knapper: 10 trin (med billeder)

Video: En menu i Arduino, og hvordan man bruger knapper: 10 trin (med billeder)

Video: En menu i Arduino, og hvordan man bruger knapper: 10 trin (med billeder)
Video: Mcdonalds Idioten 2024, November
Anonim
En menu i Arduino, og hvordan man bruger knapper
En menu i Arduino, og hvordan man bruger knapper

I min Arduino 101 -tutorial bliver du lært, hvordan du opsætter dit miljø i Tinkercad. Jeg bruger Tinkercad, fordi det er en temmelig kraftfuld online platform, der giver mig mulighed for at demonstrere en række færdigheder for studerende til at bygge kredsløb. Du er velkommen til at bygge alle mine tutorials ved hjælp af Arduino IDE og en ægte Arduino!

I denne vejledning lærer vi om knapper! Vi skal vide:

  • Sådan kobles de op
  • Læser deres værdi
  • Afvis, og hvorfor det er vigtigt
  • En praktisk applikation (oprettelse af en menu)

De fleste mennesker synes, at det mest praktiske at gøre med en knap er at tænde og slukke et lys. Det gør vi, ikke her! Vi vil bruge vores til at oprette en menu og angive nogle muligheder på Arduino.

Parat? Lad os komme igang!

Trin 1: Konfigurer tavlen

Opsæt bestyrelsen
Opsæt bestyrelsen
Opsæt bestyrelsen
Opsæt bestyrelsen

Det første trin er at sætte en Arduino og Breadboard Small på prototyperingsområdet. Tjek billederne ovenfor for at se, hvordan du tilslutter strømskinnerne.

En Breadboard Mini har to kraftskinner øverst og nederst. Vi leder disse op til Arduino, så vi kan levere strøm til flere komponenter. Senere i denne vejledning bruger vi 3 knapper, så vi skal bruge mere strøm. Det, der skal bemærkes, er, at på et lille brødbræt kører strømskinnerne tværs over brættet, vandret. Dette er forskelligt fra kolonnerne i hovedprototypefeltet i midten; disse løber lodret. Du kan bruge en hvilken som helst af strømstifterne til at levere strøm til enhver søjle i hovedområdet i midten.

Når du tilføjer strøm, skal du bruge sorte og røde ledninger til henholdsvis de negative og positive. Tilføj ledninger i enden, der driver strøm til den anden side af brættet. Vi vil ikke bruge den side, men det er god praksis.

Trin 2: Tilføj knappen og modstanden

Tilføj knappen og modstanden
Tilføj knappen og modstanden
Tilføj knappen og modstanden
Tilføj knappen og modstanden
Tilføj knappen og modstanden
Tilføj knappen og modstanden

Tilføj en lille trykknap fra komponentbakken. Det skal ligne det på billedet. Sørg for, at det ikke er en switch! Tilføj også en modstand. Klik på den, og indstil dens værdi til 10kΩ. Det er nok til at trække stiften lavt, når den ikke er tilsluttet, hvilket er meget vigtigt senere i koden.

Placer komponenten på tværs af midten af brødbrættet. Sådan fungerer en knap:

  • Hjørne til hjørne, knappen er ikke forbundet. Ved at trykke på knappen lukkes kontakterne og forbinder hjørnerne.
  • Knappens sider er forbundet. Hvis du tilsluttede en ledning øverst til venstre og nederst til venstre, ville kredsløbet være lukket.

Det er derfor, vi sætter komponenten på tværs af rummet i midten. Det sikrer, at hjørnerne ikke er forbundet under benene i brættet.

Det næste trin giver et par billeder, der illustrerer disse punkter.

Placer modstanden fra den nederste højre stift på tværs af søjler, så den sidder vandret.

Trin 3: Knapforbindelser

Knapforbindelser
Knapforbindelser
Knapforbindelser
Knapforbindelser

Billederne ovenfor gør det ret klart, hvordan knapperne forbinder. Det var altid et forvirringspunkt, når du synes, at noget er godt, og det ikke virker!

Lad os nu tilføje ledningerne.

  • Placer en rød ledning fra en positiv strømnål til den samme kolonne som den nederste højre stift på knappen
  • Placer en sort ledning fra en negativ strømstift til den samme søjle som modstanden.
  • Placer en farvet ledning (ikke rød/sort) fra den øverste venstre pin til Digital Pin 2 på Arduino

Kontroller billederne ovenfor for at sikre, at dine ledninger er korrekte.

Trin 4: Koden …

Koden…
Koden…
Koden…
Koden…

Lad os se på koden for en grundlæggende knap.

Åbn kodeditoren, og skift fra Blokke til Tekst. Fjern advarslen, der kommer. Vi er glade for teksten!

Du kender den grundlæggende opsætning, så lad os definere knappen og lave en grundlæggende læsning. Vi udskriver output til Serial.

Jeg lagde et par ekstra kommentarer i koden herunder, så det er lettere at læse end billedet.

// Definer konstanter

#define button 2 void setup () {pinMode (button, INPUT); Serial.begin (9600); } void loop () {// Læs den digitale pin for at kontrollere status for knappen int presset = digitalRead (button); // Knap returnerer HIGH hvis der trykkes på, LOW hvis ikke hvis (trykkes == HIGH) {Serial.println ("Presset!"); }}

Ok, det virker!

I det væsentlige er alt, hvad vi gør, at kontrollere status for den digitale pin hver gang koden sløjfer. Hvis du klikker på Start Simulation og trykker på knappen, ser du Serial Monitor (klik på knappen under koden) displayet "Presset!" gentagne gange.

En funktion, du kan se i koden ovenfor, er evalueringen af tilstanden if (). Alt, hvad koden gør, er at stille et spørgsmål og evaluere, om det er sandt, i dette tilfælde. Vi bruger er lige (dobbelte lighedstegn, som dette: ==) for at kontrollere, om værdien af variablen er lig med en bestemt værdi. En digitalRead () returnerer enten HIGH eller LOW.

Ved hjælp af if () else if / else kan vi kontrollere mange betingelser eller alle betingelser, og hvis du går tilbage til Arduino Basics, ser du nogle af de sammenligninger, du kan foretage.

Nu … Vores kode kan se komplet ud … Men vi har et problem.

Se, det fungerer rigtig godt, når du er i simulatoren. Men ægte elektricitet har støj, især DC -elektronik. Så vores knap returnerer muligvis en falsk læsning nogle gange. Og det er et problem, fordi dit projekt muligvis ikke reagerer den rigtige måde for brugeren.

Lad os ordne det!

Trin 5: En lille debounce

Lidt afkald
Lidt afkald

Vi bruger en procedure kaldet debounce for at overvinde vores knapproblem. Dette venter i det væsentlige et bestemt tidsrum, mellem da knappen blev trykket og faktisk reagerede på skubbet. Det føles stadig naturligt for brugeren (medmindre du gør tiden for lang). Du kan også bruge den til at kontrollere presselængden, så du kan reagere forskelligt hver gang. Du behøver ikke at ændre nogen af ledningerne!

Lad os se på koden:

#definer knap 2#definere debounceTimeout 100

Den første ændring er i det globale omfang. Du kan huske, at det er her, vi definerer variabler, mange af vores funktioner kan bruge, eller dem, der ikke kan nulstilles, hver gang sløjfen udløses. Så vi tilføjede debounceTimeout til de definerede konstanter. Vi lavede denne 100 (som senere oversættes til 100 ms), men den kan være kortere. Længere, og det vil føles unaturligt.

long int lastDebounceTime;

Denne variabel deklareres under konstanterne. Dette er en lang int -type, som stort set giver os mulighed for at gemme lange numre i hukommelsen. Vi kaldte det lastDebounceTime.

Vi behøver ikke ændre noget i funktionen til ugyldig opsætning (). Lad os forlade den ene.

void loop () {// Læs den digitale pin for at kontrollere status for knappen int trykket = digitalRead (button); lang int currentTime = millis (); // Knapkode}

Den første ændring, vi foretager i loop () -funktionen, er under opkaldet til at læse knappen. Vi skal holde styr på den aktuelle tid. Funktionen millis () returnerer det aktuelle klokkeslæt, siden Arduino startede i millisekunder. Vi skal gemme dette i en lang variabel af typen int.

Nu skal vi sikre os, at vi er klar over tiden, siden der blev trykket på knappen, så vi nulstiller timeren, når den ikke trykkes. Tag et kig:

void loop () {// Læs den digitale pin for at kontrollere status for knappen int presset = digitalRead (button); lang int currentTime = millis (); hvis (trykket == LOW) {// Nulstil tælletiden, mens der ikke trykkes på knappen lastDebounceTime = currentTime; } // Knapkode}

If (presset == LOW) algoritmen kontrollerer, om der ikke trykkes på knappen. Hvis det ikke er det, gemmer koden den aktuelle tid siden sidste debounce. På den måde har vi hver gang der trykkes på knappen et tidspunkt, hvorfra vi kan kontrollere, hvornår der blev trykket på knappen. Vi kan derefter lave en hurtig matematisk beregning for at se, hvor længe knappen blev trykket ind, og reagere korrekt. Lad os se på resten af koden:

void loop () {// Læs den digitale pin for at kontrollere status for knappen int trykket = digitalRead (button); lang int currentTime = millis (); hvis (trykket == LOW) {// Nulstil tælletiden, mens der ikke trykkes på knappen lastDebounceTime = currentTime; } // Knap er blevet trykket på et givet tidspunkt, hvis (((currentTime - lastDebounceTime)> debounceTimeout)) {// Hvis timeout er nået, trykkes på knappen! Serial.println ("Presset!"); }}

Den sidste kodeblok tager den aktuelle tid, trækker den sidste debounce -tid fra og sammenligner den med den timeout, vi har indstillet. Hvis den er større, antager koden, at der er blevet trykket på knappen i den tid og reagerer. Pænt!

Kør din kode, og kontroller, at den virker. Hvis du har fejl, skal du kontrollere din kode!

Lad os nu se på et praktisk eksempel.

Trin 6: Fremstilling af en menu

Fremstilling af en menu
Fremstilling af en menu

Knapper er interessante, fordi der er så mange muligheder med dem! I dette eksempel laver vi en menu. Lad os sige, at du har oprettet denne virkelig flotte enhed og har brug for brugere for at kunne ændre muligheder for at slå bestemte ting til eller fra eller angive en bestemt værdi for en indstilling. Dette design med tre knapper kan gøre det!

Så til dette projekt har vi brug for:

  • Tre knapper
  • Tre modstande indstillet til 10kΩ

Vi har allerede en af disse, vi mangler bare de to andre. Så tilføj dem til tavlen. Tilslutning er lidt mere kompleks, men kun fordi jeg ville beholde den virkelig kompakt. Du kan følge det samme mønster for den første knap eller følge billedet ovenfor.

De tre knapper er en menu åben/næste indstilling, en ændringsindstilling (som i, ændring af indstillingen) og en gem/luk menu -knap.

Tilslut det, lad os se på koden!

Trin 7: Kodeopdeling - global

Ok, dette bliver et langt skridt, men jeg skal gennemgå hvert afsnit af kode.

Lad os først se på de nødvendige globale variabler.

// Definer konstanter #definer menuButton 2 #define menuVælg 3 #definer menuSave 4 #define debounceTimeout 50 // Definer variabler int menuButtonPreviousState = LOW; int menuSelectPreviousState = LAV; int menuSavePreviousState = LAV; long int lastDebounceTime; // Menuindstillinger char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {false, false}; bool menuMode = falsk; bool menuNeedsPrint = false; int optionSelected = 0;

Disse tre blokke ligner nogenlunde det, vi har set før. I den første har jeg defineret de tre knapper og timeout. For denne del af projektet har jeg indstillet det til 50 ms, så det tager en bevidst tryk for at få det til at fungere.

Den anden blok er alle variablerne. Vi skal holde styr på knappenPreviousState, og vi skal holde styr på den sidsteDebounceTime. Disse er alle int -type variabler, men den sidste er en lang type, fordi jeg går ud fra, at vi har brug for plads i hukommelsen.

Menuen med valgmuligheder har et par nye funktioner. Først char * (ja, det er en bevidst stjerne), som er en bogstavelig variabel med tegn/streng. Det er en markør til en statisk lagring i hukommelsen. Du kan ikke ændre det (som du kan for eksempel i Python). Denne linje *menuOptions opretter en vifte af strenglitteraler. Du kan tilføje så mange menupunkter, som du vil.

Bool featureSetting -variablen er blot den matrix af værdier, der repræsenterer hvert menupunkt. Ja, du kan gemme alt, hvad du kan lide, bare ændre variabeltypen (de skal alle være af samme type). Nu kan der være bedre måder at håndtere dette på, f.eks. Ordbøger eller tupler, men det er enkelt for denne applikation. Jeg ville sandsynligvis oprette en af sidstnævnte i en implementeret applikation.

Jeg har holdt styr på menuMode, så hvis jeg ville have andre ting på min skærm, kunne jeg gøre det. Hvis jeg havde en sensorlogik, kunne jeg også sætte den på pause under betjening af menuen, bare hvis der er noget i konflikt. Jeg har en menuNeedsPrint -variabel, fordi jeg vil udskrive menuen på bestemte tidspunkter, ikke kun hele tiden. Endelig har jeg en optionSelected variabel, så jeg kan holde styr på den valgte mulighed, når jeg får adgang til den flere steder.

Lad os se på det næste sæt funktioner.

Trin 8: Opdeling af kode - Opsætning og brugerdefinerede funktioner

Opsætningsfunktionen () er let nok, kun tre inputdeklarationer:

void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }

Næste er de tre brugerdefinerede funktioner. Lad os se på de to første, derefter den sidste separat.

Vi har brug for to funktioner, der returnerer nogle oplysninger. Årsagen er, at vi vil sikre os, at dette er en slags menneskelig læsning. Det vil også hjælpe med fejlfinding af koden, hvis vi har et problem. Kode:

// Funktion til at returnere den aktuelle valgte optionchar *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]; // Return option Valgt return menuOption; } // Funktion til at returnere status for den aktuelle valgte option char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char *optionSettingVal; hvis (optionSetting == false) {optionSettingVal = "Falsk"; } else {optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; }

Funktionen char *ReturnOptionSelected () kontrollerer den valgte indstilling (hvis du ser ovenfor, sætter vi en variabel til at holde styr på det) og trækker strengen bogstaveligt fra den matrix, vi har oprettet tidligere. Det returnerer det derefter som en forkulletype. Vi ved det, fordi funktionen angiver returtypen.

Den anden funktion, char *ReturnOptionStatus () læser status for den indstilling, der er gemt i arrayet, og returnerer en streng, der repræsenterer værdien. For eksempel, hvis den indstilling, vi har gemt, er falsk, ville jeg returnere "Falsk". Dette er fordi vi viser brugeren denne variabel, og det er bedre at holde al denne logik sammen. Jeg kunne gøre det senere, men det giver mere mening at gøre det her.

// Funktion til at skifte nuværende optionbool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; vende tilbage sandt; }

Funktionen bool ToggleOptionSelected () er en bekvemmelighedsfunktion til at ændre værdien af den indstilling, vi har valgt i menuen. Det vender bare værdien. Hvis du havde et mere komplekst sæt muligheder, kan det være en helt anden. Jeg returnerer sand i denne funktion, fordi mit tilbagekald (opkaldet senere i koden, der udløser denne funktion) forventer et sandt/falsk svar. Jeg er 100% sikker på, at dette vil fungere, så jeg regnede ikke med, at det ikke fungerede, men jeg ville i en implementeret applikation (for en sikkerheds skyld).

Trin 9: Loop …

Loop () -funktionen er ret lang, så vi gør det i dele. Du kan antage alt nedenfor reder inden for denne funktion:

void loop () {

// Arbejde her <-----}

Ok, vi har set disse ting før:

// Læs knapperne int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Få den aktuelle tid lang int currentTime = millis (); hvis (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Nulstil tælletiden, mens der ikke trykkes på knappen lastDebounceTime = currentTime; menuButtonPreviousState = LAV; menuSelectPreviousState = LAV; menuSavePreviousState = LAV; }

Alt, hvad jeg skulle gøre her, var at tilføje de tre digitalRead () -opkald og sørge for, at jeg stod for, at hvis alle knapper var lave, skulle vi nulstille timeren (lastDebounceTime = currentTime) og sætte alle tidligere tilstande til lav. Jeg gemmer også millis () i currentTime.

Det næste afsnit reder inde i linjen

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

// Arbejde her <----}

Der er tre sektioner. Ja, jeg kunne have flyttet dem til deres egne funktioner, men for enkelhedens skyld beholdt jeg de tre hovedknapalgoritmer herinde.

hvis ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Lad brugeren vide Serial.println ("Menu er aktiv"); } ellers hvis (menuMode == true && optionSelected = 1) {// Nulstil option optionSelected = 0; } // Udskriv menuen menuNeedsPrint = true; // Skift knappen forrige. tilstand til kun at vise menu // hvis knappen slippes og trykkes igen menuButtonPreviousState = menuButtonPressed; // Ville være HØJ}

Denne første håndteres, når menuButtonPressed er HIGH, eller når der trykkes på menuknappen. Det kontrollerer også for at sikre, at den tidligere tilstand var LAV, så knappen skulle slippes, før der blev trykket på den igen, hvilket forhindrer programmet i hele tiden at affyre den samme begivenhed igen og igen.

Det kontrollerer derefter, at hvis menuen ikke er aktiv, aktiveres den. Den udskriver den første valgmulighed (som er det første element i menuen Valgmuligheder som standard. Hvis du trykker på knappen en anden eller tredje (osv.) Gang, får du den næste mulighed på listen. Noget jeg kunne rette er at når det kommer til enden, cykler det tilbage til begyndelsen. Dette kunne aflæse arrayets længde og gøre det lettere at cykle tilbage, hvis du ændrede antallet af muligheder, men det var enkelt for nu.

Den sidste lille sektion (// Udskriver menuen) udskriver naturligvis menuen, men den indstiller også den tidligere tilstand til HIGH, så den samme funktion ikke går i loop (se min note ovenfor om kontrol af, om knappen tidligere var LAV).

// menuSelect er trykket, angiv logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Skift den valgte indstilling // I øjeblikket er dette bare sandt/falsk // men kunne være noget bool toggle = ToggleOptionSelected (); hvis (skifte) {menuNeedsPrint = true; } else {Serial.println ("Noget gik galt. Prøv igen"); }}} // Skift tilstand for kun at skifte, hvis den slippes og trykkes igen menuSelectPreviousState = menuSelectPressed; }

Denne bit kode håndterer knappen menuSelectPressed på samme måde, undtagen denne gang aktiverer vi bare funktionen ToggleOptionSelected (). Som jeg sagde før, kan du ændre denne funktion, så den gør mere, men det er alt, hvad jeg har brug for.

Det vigtigste at bemærke er skiftevariablen, som sporer succes med tilbagekald og udskriver menuen, hvis den er sand. Hvis det ikke returnerer noget eller falsk, udskriver det fejlmeddelelsen. Det er her, du kan bruge dit tilbagekald til at gøre andre ting.

hvis ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Afslut menuen // Her kan du foretage enhver oprydning // eller gemme i EEPROM menuMode = false; Serial.println ("Menu lukket"); // Skift tilstand, så menuen kun afslutter, når menuSavePreviousState = menuSavePressed; }}

Denne funktion håndterer menuen Save -knappen, som netop forlader menuen. Det er her, du kan have en annullerings- eller gemmeindstilling, måske rydde op eller gemme i EEPROM. Jeg udskriver bare "Menu afsluttet" og indstiller knaptilstanden til HIGH, så den ikke går i loop.

hvis (menuMode && menuNeedsPrint) {// Vi har udskrevet menuen, så medmindre der sker noget //, er det ikke nødvendigt at udskrive den igen menuNeedsPrint = false; char *optionActive = ReturnOptionSelected (); char *optionStatus = ReturnOptionStatus (); Serial.print ("Udvalgt:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }

Dette er menuPrint -algoritmen, som kun udløses, når menuen er aktiv, og når menuNeedsPrint -variablen er indstillet til sand.

Dette kunne helt sikkert flyttes til sin egen funktion, men for enkelhedens skyld..!

Nå, det er det! Se det næste trin for hele kodeblokken.

Trin 10: Endelig kodeblok

// Definer konstanter

#define menuButton 2 #define menuVælg 3 #define menuGem 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = LAV; int menuSavePreviousState = LAV; // Definer variabler long int lastDebounceTime; bool lightSensor = sand; bool tempSensor = sand; // Menuindstillinger char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {false, false}; bool menuMode = falsk; bool menuNeedsPrint = false; int optionSelected = 0; // Opsætningsfunktion

void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }

// Funktion til at returnere den aktuelle valgte option char *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]; // Return option Valgt return menuOption; } // Funktion til at returnere status for den aktuelle valgte option char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char *optionSettingVal; hvis (optionSetting == false) {optionSettingVal = "Falsk"; } else {optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; } // Funktion til at skifte den aktuelle indstilling bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; vende tilbage sandt; } // Hovedløkken

void loop () {// Læs knapperne int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Få den aktuelle tid lang int currentTime = millis (); hvis (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Nulstil tælletiden, mens der ikke trykkes på knappen lastDebounceTime = currentTime; menuButtonPreviousState = LAV; menuSelectPreviousState = LAV; menuSavePreviousState = LAV; } if (((currentTime - lastDebounceTime)> debounceTimeout)) {// Hvis timeout er nået, trykkes på knappen!

// menuKnappen trykkes, angiv logik

// Udløses kun, når knappen tidligere er blevet frigivet, hvis ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Lad brugeren vide Serial.println ("Menu er aktiv"); } ellers hvis (menuMode == true && optionSelected = 1) {// Nulstil option optionSelected = 0; } // Udskriv menuen menuNeedsPrint = true; // Skift knappen forrige. tilstand til kun at vise menu // hvis knappen slippes og trykkes igen menuButtonPreviousState = menuButtonPressed; // Ville være HØJ} // menuSelect er trykket, angiv logik hvis ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Skift den valgte indstilling // I øjeblikket er dette bare sandt/falsk // men kan være noget bool toggle = ToggleOptionSelected (); hvis (skifte) {menuNeedsPrint = true; } else {Serial.print ("Noget gik galt. Prøv igen"); }}} // Skift tilstand for kun at skifte, hvis den slippes og trykkes igen menuSelectPreviousState = menuSelectPressed; } hvis ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Afslut menuen // Her kan du foretage enhver oprydning // eller gemme i EEPROM menuMode = false; Serial.println ("Menu lukket"); // Skift tilstand, så menuen kun afslutter, når menuSavePreviousState = menuSavePressed; }} // Udskriv den aktuelle menuindstilling aktiv, men udskriv den kun én gang, hvis (menuMode && menuNeedsPrint) {// Vi har udskrevet menuen, så medmindre der sker noget //, er det ikke nødvendigt at udskrive den igen menuNeedsPrint = false; char *optionActive = ReturnOptionSelected (); char *optionStatus = ReturnOptionStatus (); Serial.print ("Udvalgt:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }}}

Kredsløbet er tilgængeligt på Tinkercad -webstedet. Jeg har integreret kredsløbet herunder, så du også kan se det!

Som altid, lad mig vide, hvis du har spørgsmål eller problemer!

Anbefalede: