Inhoudsopgave:

Een menu in Arduino en het gebruik van knoppen: 10 stappen (met afbeeldingen) Antwoorden op al uw "Hoe?"
Een menu in Arduino en het gebruik van knoppen: 10 stappen (met afbeeldingen) Antwoorden op al uw "Hoe?"

Video: Een menu in Arduino en het gebruik van knoppen: 10 stappen (met afbeeldingen) Antwoorden op al uw "Hoe?"

Video: Een menu in Arduino en het gebruik van knoppen: 10 stappen (met afbeeldingen) Antwoorden op al uw
Video: WordPress webshop maken in 2023 | WooCommerce handleiding Nederlands 2024, November
Anonim
Een menu in Arduino en hoe knoppen te gebruiken
Een menu in Arduino en hoe knoppen te gebruiken

In mijn Arduino 101-zelfstudie leert u hoe u uw omgeving in Tinkercad kunt instellen. Ik gebruik Tinkercad omdat het een behoorlijk krachtig online platform is waarmee ik een reeks vaardigheden aan studenten kan demonstreren voor het bouwen van circuits. Voel je vrij om al mijn tutorials te bouwen met behulp van de Arduino IDE en een echte Arduino!

In deze tutorial gaan we leren over knoppen! Wij moeten weten:

  • Hoe u ze kunt aansluiten
  • Hun waarde lezen
  • Debounce, en waarom het belangrijk is
  • Een praktische toepassing (menu maken)

De meeste mensen denken dat het meest praktische wat je met een knop kunt doen, is een lamp aan en uit te zetten. Wij wel, niet hier! We gaan de onze gebruiken om een menu te maken en enkele opties op de Arduino in te stellen.

Klaar? Laten we beginnen!

Stap 1: Stel het bord in

Stel het bord in
Stel het bord in
Stel het bord in
Stel het bord in

De eerste stap is om een Arduino en Breadboard Small op het prototypegebied te plaatsen. Bekijk de afbeeldingen hierboven om te zien hoe u de stroomrails moet aansluiten.

Een Breadboard Mini heeft twee stroomrails boven en onder. We verbinden deze met de Arduino zodat we meer componenten van stroom kunnen voorzien. Later in deze tutorial zullen we 3 knoppen gebruiken, dus we hebben meer kracht nodig. Het ding om op te merken is dat op een klein breadboard de stroomrails horizontaal over het bord lopen. Dit is anders dan de kolommen in het hoofdprototyping-gebied in het midden; deze lopen verticaal. U kunt elk van de stroompinnen gebruiken om elke kolom in het hoofdgebied in het midden van stroom te voorzien.

Wanneer u stroom toevoegt, gebruikt u zwarte en rode draden naar respectievelijk de negatieve en positieve draad. Voeg aan het einde draden toe die de stroom naar de andere kant van het bord leiden. We zullen die kant niet gebruiken, maar het is een goede gewoonte.

Stap 2: Voeg de knop en weerstand toe

Voeg de knop en weerstand toe
Voeg de knop en weerstand toe
Voeg de knop en weerstand toe
Voeg de knop en weerstand toe
Voeg de knop en weerstand toe
Voeg de knop en weerstand toe

Voeg een kleine drukknop toe vanuit de componentenlade. Het moet eruit zien zoals op de afbeelding. Zorg ervoor dat het geen schakelaar is! Voeg ook een weerstand toe. Klik erop en stel de waarde in op 10kΩ. Dat is genoeg om de pin laag te trekken wanneer deze niet is aangesloten, wat later in de code erg belangrijk is.

Plaats het onderdeel in het midden van het breadboard. De manier waarop een knop werkt is:

  • Hoek tot hoek, de knop is niet verbonden. Door op de knop te drukken, worden de contacten gesloten en worden de hoeken met elkaar verbonden.
  • De zijkanten van de knop zijn verbonden. Als je linksboven en linksonder een draad zou aansluiten, zou het circuit gesloten zijn.

Daarom plaatsen we het onderdeel in het midden over de ruimte. Het zorgt ervoor dat de hoeken niet onder de pinnen in het bord worden aangesloten.

De volgende stap biedt een aantal afbeeldingen die deze punten illustreren.

Plaats de weerstand van de pin rechtsonder over kolommen, zodat deze horizontaal zit.

Stap 3: Knopverbindingen

Knopaansluitingen
Knopaansluitingen
Knopaansluitingen
Knopaansluitingen

De afbeeldingen hierboven maken vrij duidelijk hoe de knoppen aansluiten. Het was altijd een punt van verwarring als je denkt dat iets helemaal goed is en het niet werkt!

Laten we nu de draden toevoegen.

  • Plaats een rode draad van een positieve stroompin naar dezelfde kolom als de pin rechtsonder op de knop
  • Plaats een zwarte draad van een negatieve voedingspin naar dezelfde kolom als de weerstand.
  • Plaats een gekleurde draad (niet rood/zwart) van de pin linksboven naar Digital Pin 2 op de Arduino

Controleer de afbeeldingen hierboven om er zeker van te zijn dat uw bedrading correct is.

Stap 4: De code…

De code…
De code…
De code…
De code…

Laten we eens kijken naar de code voor een basisknop.

Open de code-editor en verander van Blokken naar Tekst. Wis de waarschuwing die verschijnt. Wij zijn blij met tekst!

U kent de basisinstellingen, dus laten we de knop definiëren en een basislezing uitvoeren. We printen de uitvoer naar Serieel.

Ik heb een paar extra opmerkingen in de onderstaande code geplaatst, zodat het gemakkelijker te lezen is dan de afbeelding.

// Definieer constanten

#define button 2 void setup() { pinMode(button, INPUT); Serieel.begin(9600); } void loop () { // Lees de digitale pin om de status van de knop te controleren int ingedrukt = digitalRead (knop); // Knop geeft HOOG terug als erop wordt gedrukt, LAAG als niet als (ingedrukt == HOOG) {Serial.println ("Ingedrukt!"); } }

Oké, dat werkt!

In wezen controleren we alleen de status van de digitale pin elke keer dat de code wordt herhaald. Als u op Simulatie starten klikt en op de knop drukt, ziet u op de seriële monitor (klik op de knop onder de code) "Pressed!" herhaaldelijk.

Een functie die u in de bovenstaande code ziet, is de evaluatie van de if()-voorwaarde. Het enige wat de code doet, is een vraag stellen en evalueren of deze waar is, in dit geval. We gebruiken de is gelijk (dubbele gelijktekens, zoals dit: ==) om te controleren of de waarde van de variabele gelijk is aan een bepaalde waarde. Een digitalRead() retourneert HOOG of LAAG.

Door de if() else if / else te gebruiken, kunnen we veel voorwaarden of alle voorwaarden controleren, en als u teruggaat naar de Arduino Basics, ziet u enkele van de vergelijkingen die u kunt maken.

Nu… Onze code lijkt misschien compleet… Maar we hebben een probleem.

Kijk, dat werkt heel goed in de simulator. Maar echte elektriciteit heeft ruis, vooral DC-elektronica. Dus onze knop kan soms een verkeerde waarde opleveren. En dat is een probleem, omdat uw project mogelijk niet op de juiste manier reageert voor de gebruiker.

Laten we het oplossen!

Stap 5: Een beetje debounce

Een beetje debounce
Een beetje debounce

We gebruiken een procedure genaamd debounce om ons knopprobleem op te lossen. Dit wacht in wezen een bepaalde hoeveelheid tijd tussen het moment waarop de knop werd ingedrukt en het daadwerkelijk reageren op de druk. Het voelt nog steeds natuurlijk aan voor de gebruiker (tenzij je de tijd te lang maakt). Je kunt het ook gebruiken om de persduur te controleren, zodat je elke keer anders kunt reageren. U hoeft niets aan de bedrading te veranderen!

Laten we naar de code kijken:

#define-knop 2#define debounceTimeout 100

De eerste wijziging betreft de globale scope. U zult zich herinneren dat we hier variabelen definiëren die veel van onze functies kunnen gebruiken of die niet kunnen worden gereset telkens wanneer de lus wordt geactiveerd. Dus hebben we debounceTimeout toegevoegd aan de gedefinieerde constanten. We hebben deze 100 gemaakt (wat later zal worden vertaald naar 100 ms), maar het kan korter zijn. Nog langer en het zal onnatuurlijk aanvoelen.

lange int lastDebounceTime;

Deze variabele wordt gedeclareerd onder de constanten. Dit is een long int-type, waarmee we in principe lange nummers in het geheugen kunnen opslaan. We noemden het lastDebounceTime.

We hoeven niets te veranderen in de void setup() functie. Laten we die achterwege laten.

void loop () {// Lees de digitale pin om de status van de knop te controleren int ingedrukt = digitalRead (knop); lange int currentTime = millis(); // Knopcode }

De eerste wijziging die we aanbrengen in de functie loop() is onder de aanroep om de knop te lezen. We moeten de huidige tijd in de gaten houden. De functie millis() retourneert de huidige tijd van de klok sinds de Arduino in milliseconden is opgestart. We moeten dit opslaan in een long int type variabele.

Nu moeten we ervoor zorgen dat we op de hoogte zijn van de tijd sinds de knop werd ingedrukt, dus we resetten de timer wanneer deze niet is ingedrukt. Kijk eens:

void loop () {// Lees de digitale pin om de status van de knop te controleren int ingedrukt = digitalRead (knop); lange int currentTime = millis(); if (pressed == LOW) {// Reset de teltijd terwijl de knop niet is ingedrukt lastDebounceTime = currentTime; } // Knopcode }

Het if(pressed == LOW) algoritme controleert of de knop niet is ingedrukt. Als dit niet het geval is, slaat de code de huidige tijd op sinds de laatste debounce. Op die manier hebben we elke keer dat de knop wordt ingedrukt, een tijdstip waarop we kunnen controleren wanneer de knop is ingedrukt. We kunnen dan een snelle wiskundige berekening doen om te zien hoe lang de knop is ingedrukt en correct te reageren. Laten we eens kijken naar de rest van de code:

void loop () {// Lees de digitale pin om de status van de knop te controleren int ingedrukt = digitalRead (knop); lange int currentTime = millis(); if (pressed == LOW) {// Reset de teltijd terwijl de knop niet is ingedrukt lastDebounceTime = currentTime; } // Knop is een bepaalde tijd ingedrukt if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Als de time-out is bereikt, knop ingedrukt! Serial.println ("Gedrukt!"); } }

Het laatste codeblok neemt de huidige tijd, trekt de laatste debounce-tijd af en vergelijkt deze met de time-out die we hebben ingesteld. Als het groter is, gaat de code ervan uit dat de knop gedurende die tijd is ingedrukt en reageert. Netjes!

Voer uw code uit en controleer of deze werkt. Als je fouten hebt, controleer dan je code!

Laten we nu naar een praktisch voorbeeld kijken.

Stap 6: Het maken van een menu

Het maken van een menu
Het maken van een menu

Knoppen zijn interessant, omdat er zoveel mogelijkheden mee zijn! In dit voorbeeld gaan we een menu maken. Laten we zeggen dat je dit echt geweldige apparaat hebt gemaakt en dat gebruikers opties moeten kunnen wijzigen om bepaalde dingen aan of uit te zetten, of een bepaalde waarde voor een instelling in te stellen. Dit ontwerp met drie knopen kan dat!

Dus voor dit project hebben we nodig:

  • Drie knoppen
  • Drie weerstanden ingesteld op 10kΩ

We hebben er al een, we hebben alleen de andere twee nodig. Dus voeg die toe aan het bord. Bedrading is iets ingewikkelder, maar alleen omdat ik het echt compact wilde houden. U kunt hetzelfde patroon volgen voor de eerste knop, of de afbeelding hierboven volgen.

De drie knoppen zijn een menu open/volgende optie, een wijzigingsoptie (zoals in, de instelling wijzigen) en een menuknop opslaan/sluiten.

Sluit het aan, laten we naar de code kijken!

Stap 7: Code-uitsplitsing - wereldwijd

Ok, dit wordt een lange stap, maar ik ga door elk deel van de code.

Laten we eerst eens kijken naar de benodigde globale variabelen.

// Definieer constanten#define menuButton 2 #define menuSelect 3#define menuSave 4 #define debounceTimeout 50 // Definieer variabelen int menuButtonPreviousState = LOW; int menuSelectPreviousState = LAAG; int menuSavePreviousState = LAAG; lange int lastDebounceTime; // Menu-opties char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optieGeselecteerd = 0;

Deze drie blokken lijken redelijk op wat we eerder hebben gezien. In de eerste heb ik de drie knoppen en de time-out gedefinieerd. Voor dit deel van het project heb ik het ingesteld op 50 ms, dus er is een bewuste druk voor nodig om het te laten werken.

Het tweede blok zijn alle variabelen. We moeten de buttonPreviousState bijhouden en we moeten de lastDebounceTime bijhouden. Dit zijn allemaal variabelen van het type int, maar de laatste is een lang type omdat ik aanneem dat we de ruimte in het geheugen nodig hebben.

Het menu-optiesblok heeft een paar nieuwe functies. Ten eerste, de char * (ja, dat is een opzettelijke asterisk), wat een letterlijke karakter-/tekenreeksvariabele is. Het is een verwijzing naar een statische opslag in het geheugen. Je kunt het niet veranderen (zoals in Python bijvoorbeeld). Deze char *menuOptions regel maakt een array van letterlijke tekenreeksen. U kunt zoveel menu-items toevoegen als u wilt.

De bool featureSetting variabele is slechts de reeks waarden die elk menu-item vertegenwoordigt. Ja, je kunt alles opslaan wat je wilt, verander gewoon het type variabele (ze moeten allemaal van hetzelfde type zijn). Nu zijn er misschien betere manieren om dit te beheren, zoals woordenboeken of tupels, maar dit is eenvoudig voor deze toepassing. Ik zou waarschijnlijk een van de laatste maken in een geïmplementeerde toepassing.

Ik heb de menuMode bijgehouden, dus als ik andere dingen op mijn display wilde, kon ik dat doen. Als ik sensorlogica had, zou ik dat ook kunnen pauzeren tijdens het bedienen van het menu, voor het geval er iets conflicteert. Ik heb een menuNeedsPrint-variabele omdat ik het menu op bepaalde tijden wil afdrukken, niet alleen de hele tijd. Ten slotte heb ik een variabele optionSelected, zodat ik de geselecteerde optie kan volgen terwijl ik deze op een aantal plaatsen open.

Laten we eens kijken naar de volgende reeks functies.

Stap 8: Code-uitsplitsing - Setup en aangepaste functies

De setup()-functie is eenvoudig genoeg, slechts drie invoerdeclaraties:

void setup () { pinMode (menuSelect, INPUT); pinMode (menu Opslaan, INPUT); pinMode (menuSelecteren, INGANG); Serieel.begin(9600); }

Hierna volgen de drie aangepaste functies. Laten we eens kijken naar de eerste twee, dan de laatste afzonderlijk.

We hebben twee functies nodig die wat informatie teruggeven. De reden is dat we ervoor willen zorgen dat dit voor mensen leesbaar is. Het zal ook helpen bij het debuggen van de code als we een probleem hebben. Code:

// Functie om de huidige geselecteerde optionchar *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected] te retourneren; // Retouroptie Geselecteerd retourmenuOptie; } // Functie om de status van de huidige geselecteerde optie terug te geven char *ReturnOptionStatus(){ bool optionSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionSettingVal = "False"; }else{ optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; }

De functie char *ReturnOptionSelected() controleert de geselecteerde optie (als je hierboven ziet, stellen we een variabele in om dat bij te houden), en haalt de letterlijke tekenreeks uit de array die we eerder hebben gemaakt. Het retourneert het vervolgens als een char-type. We weten dit omdat de functie het retourtype aangeeft.

De tweede functie, char *ReturnOptionStatus() leest de status van de optie die is opgeslagen in de array en retourneert een letterlijke tekenreeks die de waarde vertegenwoordigt. Als de instelling die we hebben opgeslagen bijvoorbeeld false is, zou ik "False" retourneren. Dit komt omdat we de gebruiker deze variabele laten zien en het is beter om al deze logica bij elkaar te houden. Ik zou het later kunnen doen, maar het is logischer om het hier te doen.

// Functie om huidige optionbool te schakelen ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; retourneer waar; }

De functie bool ToggleOptionSelected() is een handige functie om de waarde te wijzigen van de instelling die we in het menu hebben geselecteerd. Het draait gewoon de waarde om. Als u een complexere reeks opties had, zou dit heel anders kunnen zijn. Ik retourneer true in deze functie, omdat mijn callback (de aanroep later in de code die deze functie activeert) een waar/onwaar antwoord verwacht. Ik ben er 100% zeker van dat dit zal werken, dus ik heb er geen rekening mee gehouden dat het niet werkte, maar ik zou het wel doen in een geïmplementeerde applicatie (voor het geval dat).

Stap 9: De lus…

De functie loop() is vrij lang, dus we doen het in delen. Je kunt aannemen dat alles hieronder nesten binnen deze functie:

lege lus() {

// Werk hier binnen <----- }

Ok, we hebben dit spul eerder gezien:

// Lees de knoppen int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Haal de huidige tijd op long int currentTime = millis(); if (menuButtonPressed == LAAG && menuSelectPressed == LAAG && menuSavePressed == LAAG){ // Reset de teltijd terwijl de knop niet is ingedrukt lastDebounceTime = currentTime; menuButtonPreviousState = LAAG; menuSelectPreviousState = LAAG; menuSavePreviousState = LAAG; }

Het enige dat ik hier hoefde te doen, was de drie digitalRead()-aanroepen toevoegen en ervoor zorgen dat ik er rekening mee hield dat als alle knoppen laag waren, we de timer opnieuw moesten instellen (lastDebounceTime = currentTime) en alle vorige statussen op laag moesten zetten. Ik sla millis() ook op in currentTime.

De volgende sectie nestelt binnen de regel

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

// Werk hier binnen <----}

Er zijn drie secties. Ja, ik had ze naar hun eigen functies kunnen verplaatsen, maar voor de eenvoud heb ik de drie belangrijkste knopalgoritmen hier bewaard.

if((menuButtonPressed == HOOG) && (menuButtonPreviousState == LAAG)){ if(menuMode == false){ menuMode = true; // Laat de gebruiker weten Serial.println ("Menu is actief"); }else if (menuMode == true && optionSelected = 1){ // Reset option optionSelected = 0; } // Druk het menu af menuNeedsPrint = true; // Schakel de knop vorige. status om alleen menu // weer te geven als de knop wordt losgelaten en opnieuw wordt ingedrukt menuButtonPreviousState = menuButtonPressed; // Zou HOOG zijn}

Deze eerste handelt wanneer menuButtonPressed HOOG is, of wanneer de menuknop wordt ingedrukt. Het controleert ook om ervoor te zorgen dat de vorige status LAAG was, zodat de knop moest worden losgelaten voordat deze opnieuw werd ingedrukt, waardoor het programma niet constant dezelfde gebeurtenis opnieuw en opnieuw activeert.

Het controleert vervolgens of het menu wordt geactiveerd als het niet actief is. Het zal de eerste geselecteerde optie afdrukken (wat standaard het eerste item in de menuOptions-array is. Als u een tweede of derde (enz.) keer op de knop drukt, krijgt u de volgende optie in de lijst. Iets wat ik zou kunnen oplossen is dat wanneer het aan het einde komt, het terug naar het begin fietst. Dit zou de lengte van de array kunnen aflezen en het terugfietsen gemakkelijker maken als je het aantal opties verandert, maar dit was eenvoudig voor nu.

De laatste kleine sectie (// drukt het menu af) drukt uiteraard het menu af, maar het stelt ook de vorige status in op HOOG, zodat dezelfde functie niet in een lus wordt geplaatst (zie mijn opmerking hierboven over controleren of de knop eerder LAAG was).

// menuSelect is ingedrukt, geef logicif((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Verander de geselecteerde optie // Op dit moment is dit gewoon waar/onwaar // maar kan van alles zijn bool toggle = ToggleOptionSelected(); if(toggle){ menuNeedsPrint = true; }else{ Serial.println("Er is iets misgegaan. Probeer het opnieuw"); } } // Schakel tussen status om alleen te wisselen als deze wordt losgelaten en opnieuw wordt ingedrukt menuSelectPreviousState = menuSelectPressed; }

Dit stukje code behandelt de menuSelectPressed-knop op dezelfde manier, behalve dat we deze keer alleen de ToggleOptionSelected()-functie activeren. Zoals ik al eerder zei, je zou deze functie kunnen veranderen zodat hij meer doet, maar dat is alles wat ik nodig heb.

Het belangrijkste om op te merken is de toggle-variabele, die het succes van de callback bijhoudt en het menu afdrukt als dit waar is. Als het niets of false retourneert, wordt het foutbericht afgedrukt. Hier kunt u uw terugbelverzoek gebruiken om andere dingen te doen.

if((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)){ // Verlaat het menu // Hier kunt u alles opruimen // of opslaan in EEPROM menuMode = false; Serial.println("Menu afgesloten"); // Schakel status zodat het menu slechts één keer wordt afgesloten menuSavePreviousState = menuSavePressed; } }

Deze functie behandelt de menuSave-knop, die het menu gewoon verlaat. Dit is waar u een optie voor annuleren of opslaan kunt hebben, misschien wat opschonen of opslaan in de EEPROM. Ik print gewoon "Menu afgesloten" en stel de knopstatus in op HOOG, zodat deze niet in een lus wordt geplaatst.

if(menuMode && menuNeedsPrint){ // We hebben het menu afgedrukt, dus tenzij er iets // gebeurt, hoeft u het niet opnieuw af te drukken menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Geselecteerd: "); Serial.print (optieActief); Serieel.print(": "); Serial.print (optieStatus); Serieel.println(); }

Dit is het menuPrint-algoritme, dat alleen wordt geactiveerd wanneer het menu actief is en wanneer de variabele menuNeedsPrint is ingesteld op true.

Dit zou zeker naar een eigen functie kunnen worden verplaatst, maar voor de eenvoud..!

Nou, dat is het dan! Zie de volgende stap voor het hele codeblok.

Stap 10: Laatste codeblok

// Definieer constanten

#define menuButton 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 int menuButtonPreviousState = LAAG; int menuSelectPreviousState = LAAG; int menuSavePreviousState = LAAG; // Definieer variabelen long int lastDebounceTime; bool lightSensor = waar; bool tempSensor = waar; // Menu-opties char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optieGeselecteerd = 0; // Instelfunctie

void setup () { pinMode (menuSelect, INPUT); pinMode (menu Opslaan, INPUT); pinMode (menuSelecteren, INGANG); Serieel.begin(9600); }

// Functie om de huidige geselecteerde optie terug te geven char *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // Retouroptie Geselecteerd retourmenuOptie; } // Functie om de status van de huidige geselecteerde optie terug te geven char *ReturnOptionStatus(){ bool optionSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionSettingVal = "False"; }else{ optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; } // Functie om huidige optie te wisselen bool ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; retourneer waar; } // De hoofdlus

void loop () {// Lees de knoppen int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Haal de huidige tijd op long int currentTime = millis(); if (menuButtonPressed == LAAG && menuSelectPressed == LAAG && menuSavePressed == LAAG){ // Reset de teltijd terwijl de knop niet is ingedrukt lastDebounceTime = currentTime; menuButtonPreviousState = LAAG; menuSelectPreviousState = LAAG; menuSavePreviousState = LAAG; } if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Als de time-out is bereikt, knop ingedrukt!

// menuKnop is ingedrukt, geef logica

// Gaat alleen af als de knop eerder is losgelaten if((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)){ if(menuMode == false){ menuMode = true; // Laat de gebruiker weten Serial.println ("Menu is actief"); }else if (menuMode == true && optionSelected = 1){ // Reset option optionSelected = 0; } // Druk het menu af menuNeedsPrint = true; // Schakel de knop vorige. status om alleen menu // weer te geven als de knop wordt losgelaten en opnieuw wordt ingedrukt menuButtonPreviousState = menuButtonPressed; // Zou HOOG zijn } // menuSelect wordt ingedrukt, geef logica if((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Wijzig de geselecteerde optie // Op dit moment is dit gewoon waar/onwaar // maar kan van alles zijn bool toggle = ToggleOptionSelected(); if(toggle){ menuNeedsPrint = true; }else{ Serial.print("Er is iets misgegaan. Probeer het opnieuw"); } } // Schakel tussen status om alleen te wisselen als deze wordt losgelaten en opnieuw wordt ingedrukt menuSelectPreviousState = menuSelectPressed; } if((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)){ // Verlaat het menu // Hier kunt u alles opruimen // of opslaan in EEPROM menuMode = false; Serial.println("Menu afgesloten"); // Schakel status zodat het menu slechts één keer wordt afgesloten menuSavePreviousState = menuSavePressed; } } // Druk de huidige menuoptie actief af, maar print deze slechts één keer if(menuMode && menuNeedsPrint){ // We hebben het menu afgedrukt, dus tenzij er iets // gebeurt, hoeft u het niet opnieuw af te drukken menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Geselecteerd: "); Serial.print (optieActief); Serieel.print(": "); Serial.print (optieStatus); Serieel.println(); } } }

Het circuit is beschikbaar op de site van Tinkercad. Ik heb het onderstaande circuit ingesloten zodat u het ook kunt zien!

Zoals altijd, als je vragen of problemen hebt, laat het me weten!

Aanbevolen: