Tartalomjegyzék:

Az Arduino menüje és a gombok használata: 10 lépés (képekkel)
Az Arduino menüje és a gombok használata: 10 lépés (képekkel)

Videó: Az Arduino menüje és a gombok használata: 10 lépés (képekkel)

Videó: Az Arduino menüje és a gombok használata: 10 lépés (képekkel)
Videó: #6 Как запрограммировать таймер задержки ПЛК Outseal Arduino 2024, November
Anonim
Az Arduino menüje és a gombok használata
Az Arduino menüje és a gombok használata

Az Arduino 101 oktatóanyagomban megtanítod a környezet beállítására a Tinkercad alkalmazásban. Azért használom a Tinkercad -ot, mert ez egy nagyon hatékony online platform, amely lehetővé teszi számomra, hogy számos készséget mutassak be a diákoknak áramkörök építéséhez. Nyugodtan megépítheti az összes oktatóanyagomat az Arduino IDE és egy igazi Arduino segítségével!

Ebben az oktatóanyagban a gombokról fogunk tanulni! Tudnunk kell:

  • Hogyan kösse be őket
  • Értékük olvasása
  • Debounce, és miért fontos
  • Praktikus alkalmazás (menü létrehozása)

A legtöbb ember úgy gondolja, hogy a gombokkal a legpraktikusabb dolog a lámpa fel- és kikapcsolása. Mi, nem itt! A sajátunkat fogjuk használni menü létrehozásához és néhány beállítás beállításához az Arduino -n.

Kész? Lássunk neki!

1. lépés: Állítsa be a táblát

Állítsa be a táblát
Állítsa be a táblát
Állítsa be a táblát
Állítsa be a táblát

Az első lépés egy Arduino és Breadboard Small felhelyezése a prototípusterületre. Tekintse meg a fenti képeket, hogy megtudja, hogyan kell bekötni az elektromos síneket.

A Breadboard Mini két felső és alsó sínekkel rendelkezik. Ezeket bekötjük az Arduino -ba, hogy több alkatrésznek tudjunk áramot adni. Ebben az oktatóanyagban később 3 gombot fogunk használni, így több energiára lesz szükségünk. Érdemes megjegyezni, hogy egy kenyérsütő táblán kicsi, a támasztó sínek vízszintesen futnak a táblán. Ez eltér a fő prototípusterület oszlopaitól középen; ezek függőlegesen futnak. A tápcsapok bármelyikével tápellátást biztosíthat a középső főterület bármely oszlopához.

Amikor áramot ad hozzá, fekete és piros vezetéket használjon a negatívhoz és a pozitívhoz. Adjon hozzá vezetékeket a végén, amelyek áramot szolgáltatnak a tábla másik oldalára. Ezt az oldalt nem használjuk, de ez jó gyakorlat.

2. lépés: Adja hozzá a gombot és az ellenállást

Adja hozzá a gombot és az ellenállást
Adja hozzá a gombot és az ellenállást
Adja hozzá a gombot és az ellenállást
Adja hozzá a gombot és az ellenállást
Adja hozzá a gombot és az ellenállást
Adja hozzá a gombot és az ellenállást

Adjon hozzá egy kis nyomógombot az alkatrészek tálcájából. Úgy kell kinéznie, mint a képen. Győződjön meg róla, hogy nem kapcsoló! Adjon hozzá ellenállást is. Kattintson rá, és állítsa 10kΩ értékre. Ez elég ahhoz, hogy alacsonyan húzza a csapot, ha nincs csatlakoztatva, ami nagyon fontos a későbbi kódban.

Helyezze az alkatrészt a kenyértábla közepére. A gomb működése a következő:

  • Saroktól sarokig, a gomb nincs csatlakoztatva. A gomb megnyomása bezárja az érintkezőket és összeköti a sarkokat.
  • A gomb oldalai össze vannak kötve. Ha vezetéket csatlakoztatott a bal felső és bal alsó részhez, akkor az áramkör lezárul.

Ezért helyezzük a komponenst a középen lévő térbe. Ez biztosítja, hogy a sarkok ne legyenek összekapcsolva a tábla csapjai alatt.

A következő lépés néhány képet mutat be, amelyek illusztrálják ezeket a pontokat.

Helyezze az ellenállást a jobb alsó csapból az oszlopok közé, így vízszintesen helyezkedik el.

3. lépés: Gombkapcsolatok

Gombkapcsolatok
Gombkapcsolatok
Gombkapcsolatok
Gombkapcsolatok

A fenti képek egyértelműen mutatják, hogyan kapcsolódnak a gombok. Mindig zűrzavar volt, amikor azt gondolja, hogy valami jó és nem működik!

Most adjuk hozzá a vezetékeket.

  • Helyezzen egy piros vezetéket a pozitív tápcsapból ugyanabba az oszlopba, mint a gomb jobb alsó csapja
  • Helyezzen egy fekete vezetéket a negatív tápcsatlakozóból ugyanabba az oszlopba, mint az ellenállás.
  • Helyezzen egy színes vezetéket (nem piros/fekete) a bal felső tűből az Arduino digitális tüskéjébe

Ellenőrizze a fenti képeket, hogy megbizonyosodjon a vezetékezés helyességéről.

4. lépés: A kód…

A kód…
A kód…
A kód…
A kód…

Nézzük meg az alapvető gomb kódját.

Nyissa meg a kódszerkesztőt, és váltson blokkokról szövegre. Törölje a megjelenő figyelmeztetést. Örülünk a szövegnek!

Ismeri az alapbeállításokat, ezért határozzuk meg a gombot, és végezzük el az alapolvasást. A kimenetet sorosra nyomtatjuk.

Néhány megjegyzést fűzök az alábbi kódhoz, így könnyebb olvasni, mint a képen.

// Állandó meghatározása

#define gomb 2 void setup () {pinMode (gomb, INPUT); Sorozat.kezdet (9600); } void loop () {// Olvassa el a digitális tűt, hogy ellenőrizze az int gomb megnyomását = digitalRead (gomb); // A gomb HIGH -t ad vissza, ha megnyomja, LOW, ha nem, ha (lenyomva == HIGH) {Serial.println ("Nyomva!"); }}

Oké, ez működik!

Lényegében csak annyit teszünk, hogy minden alkalommal ellenőrizzük a digitális tüskés állapotát, amikor a kód ciklusba lép. Ha rákattint a Szimuláció indítása gombra, és megnyomja a gombot, megjelenik a Soros monitor (kattintson a kód alatt található gombra) "Nyomva!" többször.

A fenti kód egyik jellemzője az if () feltétel kiértékelése. Ebben az esetben a kód csupán egy kérdést tesz fel, és felméri, hogy igaz -e. Az egyenlő (kettős egyenlőjelek, például: ==) segítségével ellenőrizzük, hogy a változó értéke megegyezik -e egy bizonyos értékkel. A digitalRead () vagy HIGH vagy LOW értéket ad vissza.

Az if () else if / else használatával sok feltételt vagy összes feltételt ellenőrizhetünk, és ha visszatér az Arduino alapjaihoz, látni fogja az összehasonlításokat.

Most… A kódunk teljesnek tűnhet… De van egy problémánk.

Látod, ez nagyon jól működik a szimulátorban. De az igazi elektromosságnak van hangja, különösen az egyenáramú elektronikának. Tehát a gombunk néha hamis értéket ad vissza. Ez pedig probléma, mert előfordulhat, hogy a projekt nem a megfelelő módon válaszol a felhasználó számára.

Javítsuk ki!

5. lépés: Egy kis visszalépés

Egy kis Debounce
Egy kis Debounce

Debounce nevű eljárással oldjuk meg a gombproblémánkat. Ez lényegében egy bizonyos ideig vár a gomb megnyomása és a nyomásra való reagálás között. Még mindig természetesnek érzi magát a felhasználó számára (kivéve, ha túl hosszúra fordítja az időt). Használhatja a préselés hosszának ellenőrzésére is, így minden alkalommal másképpen reagálhat. Nem kell vezetékeket cserélni!

Nézzük a kódot:

#define gomb 2#define debounceTimeout 100

Az első változás a globális hatókörre vonatkozik. Emlékezni fog arra, hogy itt határozzuk meg a változókat, amelyeket sok funkciónk használhat, vagy azokat, amelyeket nem lehet visszaállítani minden egyes ciklusindításkor. Tehát hozzáadtuk a debounceTimeout -ot a meghatározott állandókhoz. Ezt a 100 -at készítettük (ami később 100 ms lesz), de lehet rövidebb. Még sokáig, és ez természetellenes lesz.

long int lastDebounceTime;

Ez a változó az állandók alatt van deklarálva. Ez egy hosszú int típus, amely alapvetően lehetővé teszi számunkra, hogy hosszú számokat tároljunk a memóriában. LastDebounceTime -nek hívtuk.

Nem kell semmit változtatnunk a void setup () függvényben. Ezt hagyjuk.

void loop () {// Olvassa el a digitális tűt, hogy ellenőrizze a gomb állapotát megnyomva = digitalRead (gomb); long int currentTime = millis (); // Gombkód}

Az első változtatás, amelyet a loop () függvényben hajtunk végre, a gomb olvasására vonatkozó hívás alatt van. Követnünk kell az aktuális időt. A millis () függvény az Arduino rendszerindítása óta eltelt órát jeleníti meg ezredmásodpercben. Ezt egy hosszú int típusú változóban kell tárolnunk.

Most meg kell győződnünk arról, hogy tisztában vagyunk -e a gomb megnyomása óta eltelt idővel, ezért alaphelyzetbe állítjuk az időzítőt, ha nem nyomja meg. Nézd meg:

void loop () {// Olvassa el a digitális tűt, hogy ellenőrizze a gomb állapotát megnyomva = digitalRead (gomb); long int currentTime = millis (); if (megnyomva == LOW) {// A számlálási idő visszaállítása, miközben a gomb nincs lenyomva lastDebounceTime = currentTime; } // Gombkód}

Az if (lenyomva == LOW) algoritmus ellenőrzi, hogy nincs -e megnyomva a gomb. Ha nem, akkor a kód eltárolja az utolsó visszakapcsolás óta eltelt időt. Így minden alkalommal, amikor megnyomja a gombot, van egy időpontunk, amelyből ellenőrizhetjük, hogy mikor nyomtuk meg a gombot. Ezután gyors matematikai számítást végezhetünk, hogy lássuk, mennyi ideig volt lenyomva a gomb, és helyesen válaszoljunk. Nézzük a kód többi részét:

void loop () {// Olvassa el a digitális tűt, hogy ellenőrizze a gomb állapotát megnyomva = digitalRead (gomb); long int currentTime = millis (); if (megnyomva == LOW) {// A számlálási idő visszaállítása, miközben a gomb nincs lenyomva lastDebounceTime = currentTime; } // A gombot egy bizonyos ideig megnyomták, ha ((((currentTime - lastDebounceTime)> debounceTimeout)) {// Ha elérte az időtúllépést, nyomja meg a gombot! Serial.println ("Nyomva!"); }}

Az utolsó kódblokk veszi az aktuális időt, kivonja az utolsó visszakapcsolási időt, és összehasonlítja azt a beállított időtúllépéssel. Ha ez nagyobb, a kód feltételezi, hogy a gombot addig megnyomták, és válaszol. Tiszta!

Futtassa a kódot, és ellenőrizze, hogy működik -e. Ha hibát észlel, ellenőrizze a kódot!

Most nézzünk egy gyakorlati példát.

6. lépés: Menü készítése

A menü elkészítése
A menü elkészítése

A gombok érdekesek, mert rengeteg lehetőség van velük! Ebben a példában menüt készítünk. Tegyük fel, hogy megalkotta ezt az igazán nagyszerű eszközt, és szüksége van rá, hogy a felhasználók módosíthassák a beállításokat bizonyos dolgok be- és kikapcsolásához, vagy egy adott értéket állítsanak be egy beállításhoz. Ez a három gombos kivitel képes erre!

Tehát ehhez a projekthez szükségünk van:

  • Három gomb
  • Három ellenállás 10 kΩ -ra van állítva

Ezek közül az egyik már megvan, csak a másik kettő kell. Tehát add hozzá a táblához. A bekötés egy kicsit bonyolultabb, de csak azért, mert igazán kompakt akartam maradni. Ugyanazt a mintát követheti az első gombnál, vagy követheti a fenti képet.

A három gomb egy menü megnyitása/következő opció, egy módosítási lehetőség (mint a beállítás megváltoztatása) és a mentés/bezárás menügomb.

Kösd be, nézzük a kódot!

7. lépés: Kódbontás - globális

Rendben, ez hosszú lépés lesz, de át fogom nézni a kód minden szakaszát.

Először nézzük meg a szükséges globális változókat.

// Állandók definiálása #define menuButton 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 // Változók definiálása int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; long int lastDebounceTime; // Menübeállítások char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {hamis, hamis}; bool menuMode = hamis; bool menuNeedsPrint = false; int optionSelected = 0;

Ez a három blokk meglehetősen hasonló ahhoz, amit korábban láttunk. Az elsőben definiáltam a három gombot és az időtúllépést. A projekt ezen részéhez 50 ms -ra állítottam be, így szándékos sajtó kell ahhoz, hogy működjön.

A második blokk az összes változó. Követnünk kell a gombotPreviousState, és nyomon kell követnünk a lastDebounceTime -t. Ezek mind int típusú változók, de az utolsó hosszú típus, mert feltételezem, hogy szükségünk van a memóriában lévő helyre.

A menüopciók blokkjában néhány új funkció található. Először is, a char * (igen, ez egy szándékos csillag), amely egy karakter/karakterlánc literális változó. Ez egy mutató a memória statikus tárolására. Nem tudod megváltoztatni (mint például a Pythonban). Ez a char *menuOptions sor egy karakterlánc -literál tömböt hoz létre. Annyi menüpontot vehet fel, amennyit csak akar.

A bool featureSetting változó csak az értékek tömbje, amely az egyes menüpontokat képviseli. Igen, tárolhat bármit, ami tetszik, csak változtassa meg a változótípust (mindegyiknek azonos típusnak kell lennie). Lehet, hogy vannak jobb módszerek ennek kezelésére, például szótárak vagy sorok, de ez az alkalmazás számára egyszerű. Valószínűleg az utóbbiak egyikét hoznám létre egy telepített alkalmazásban.

Követtem a menuMode módot, így ha más dolgokat szeretnék a kijelzőn, megtehetném. Továbbá, ha lenne érzékelő logikám, akkor a menü működése közben szüneteltethetem, ha valami ütközik. Van egy menuNeedsPrint változóm, mert a menüt meghatározott időpontokban akarom kinyomtatni, nem csak folyamatosan. Végül van egy optionSelected változóm, így nyomon követhetem a kiválasztott opciót, amikor számos helyen hozzáférek hozzá.

Nézzük a következő függvénycsoportot.

8. lépés: Kódbontás - beállítás és egyéni funkciók

A setup () függvény elég egyszerű, mindössze három bemeneti nyilatkozat:

void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Sorozat.kezdet (9600); }

Következzen a három egyéni funkció. Nézzük az első kettőt, majd az utolsót külön.

Két funkcióra van szükségünk, amelyek bizonyos információkat adnak vissza. Ennek az az oka, hogy meg akarjuk győződni arról, hogy ez valahogy ember által olvasható. Segít a kód hibakeresésében is, ha problémánk van. Kód:

// Funkció az aktuális kiválasztott opció visszaadásárachar *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]; // Visszatérési lehetőségKiválasztott visszatérési menüOption; } // Funkció az aktuális kiválasztott opció állapotának visszaadására char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char *optionSettingVal; if (optionSetting == hamis) {optionSettingVal = "Hamis"; } else {optionSettingVal = "Igaz"; } // Visszatérési opcióA visszatérési opció beállításaSettingVal; }

A char *ReturnOptionSelected () függvény ellenőrzi a kiválasztott opciót (ha fent látja, beállítunk egy változót annak nyomon követésére), és lehívja a karakterláncot a korábban létrehozott tömbből. Ezután char típusként adja vissza. Ezt azért tudjuk, mert a függvény jelzi a visszatérési típust.

A második függvény, a char *ReturnOptionStatus () beolvassa a tömbbe mentett opció állapotát, és visszaad egy karakterláncot, amely az értéket képviseli. Például, ha a tárolt beállítás hamis, akkor hamisat adnék vissza. Ez azért van, mert megmutatjuk a felhasználónak ezt a változót, és jobb, ha mindezt együtt tartjuk. Később megtehetném, de ésszerűbb itt megtenni.

// Az aktuális opciógomb átváltására szolgáló funkció ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; return true; }

A bool függvény ToggleOptionSelected () egy kényelmi funkció, amellyel módosíthatja a menüben kiválasztott beállítás értékét. Csak felforgatja az értéket. Ha bonyolultabb lehetőségei vannak, ez egészen más lehet. Ebben a függvényben igaz értéket adok vissza, mert a visszahívásom (a hívás később a funkciót aktiváló kódban) igaz/hamis választ vár. 100% -ig biztos vagyok benne, hogy ez működni fog, ezért nem számoltam arról, hogy nem működik, de egy telepített alkalmazásban igen (minden esetre).

9. lépés: A hurok…

A loop () függvény meglehetősen hosszú, ezért részletekben fogjuk megtenni. Ezen a függvényen belül mindent feltételezhet a fészkek alatt:

void loop () {

// Dolgozz itt <-----}

Oké, ezt láttuk korábban:

// Olvassa el a gombokat int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Az aktuális idő lekérése long int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// A számlálási idő visszaállítása, miközben a gomb nincs lenyomva lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }

Csak annyit kellett tennem, hogy hozzáadtam a három digitalRead () hívást, és győződjön meg róla, hogy elszámoltam azzal a ténnyel, hogy ha minden gomb alacsony, vissza kell állítanunk az időzítőt (lastDebounceTime = currentTime), és minden korábbi állapotot alacsonyra kell állítanunk. Millis () -t is tárolok a currentTime -ban.

A következő szakasz a vonalon belül fészkel

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

// Dolgozz itt <----}

Három szakasz van. Igen, áthelyezhettem őket a saját funkcióikba, de az egyszerűség kedvéért itt tartottam a három főgombos algoritmust.

if ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Tájékoztassa a felhasználót Serial.println ("A menü aktív"); } else if (menuMode == true && optionSelected = 1) {// Opció visszaállítása resetSelected = 0; } // A menü menü kinyomtatásaNeedsPrint = true; // Váltás a gomb között előző állapota csak a menü megjelenítéséhez // ha a gombot elengedik és ismét megnyomják menuButtonPreviousState = menuButtonPressed; // MAGAS lenne

Ez az első akkor működik, ha a menuButtonPressed MAGAS, vagy ha megnyomja a menü gombot. Azt is ellenőrzi, hogy az előző állapot LOW volt -e, hogy a gombot újra le kell nyomni, mielőtt újra megnyomnák, ami megakadályozza, hogy a program folyamatosan újra és újra elindítsa ugyanazt az eseményt.

Ezután ellenőrzi, hogy ha a menü nem aktív, akkor aktiválja azt. Kinyomtatja az első kiválasztott opciót (amely a menü első eleme az Opciók tömb alapértelmezés szerint. Ha másodszor vagy harmadszor (stb.) Megnyomja a gombot, akkor megjelenik a következő lehetőség a listában. hogy amikor a végére ér, visszatér az elejére. Ez leolvashatja a tömb hosszát, és megkönnyítheti a kerékpározást, ha megváltoztatja a lehetőségek számát, de ez most egyszerű volt.

Az utolsó kis rész (// A menü kinyomtatása) nyilvánvalóan kinyomtatja a menüt, de az előző állapotot is HIGH -ra állítja, így ugyanaz a funkció nem fog ciklusba lépni (lásd a fenti megjegyzésemet arról, hogy ellenőrizze, hogy a gomb korábban LOW volt -e).

// a menuSelect le van nyomva, adja meg a logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// A kiválasztott beállítás módosítása // Jelenleg ez csak igaz/hamis // de bármi lehet bool toggle = ToggleOptionSelected (); if (toggle) {menuNeedsPrint = igaz; } else {Serial.println ("Valami hiba történt. Kérjük, próbálja újra"); }} // Váltás az állapotra, hogy csak akkor váltson, ha elengedi és újra megnyomja menuSelectPreviousState = menuSelectPressed; }

Ez a kódrészlet ugyanúgy kezeli a menuSelectPressed gombot, kivéve, hogy ezúttal csak a ToggleOptionSelected () függvényt aktiváljuk. Amint azt korábban mondtam, megváltoztathatja ezt a funkciót, hogy többet tegyen, de csak erre van szükségem.

A legfontosabb dolog a toggle változó, amely nyomon követi a visszahívás sikerét, és kinyomtatja a menüt, ha igaz. Ha nem ad vissza semmit vagy hamis, akkor kinyomtatja a hibaüzenetet. Itt használhatja visszahívását más tevékenységek elvégzésére.

if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Kilépés a menüből // Itt bármilyen rendrakást végezhet // vagy menthet az EEPROM menübeMód = false; Serial.println ("Kilépett a menüből"); // Váltás az állapotra, így a menü csak egyszer lép ki a menuSavePreviousState = menuSavePressed; }}

Ez a funkció kezeli a menuSave gombot, amely csak kilép a menüből. Itt választhat egy törlési vagy mentési lehetőséget, esetleg tisztíthat, vagy menthet az EEPROM -ra. Csak kinyomtatom a "Menü kilépett" -t, és a gomb állapotát HIGH -ra állítom, hogy ne ciklusozzon.

if (menuMode && menuNeedsPrint) {// Kinyomtattuk a menüt, így ha nem történik // valami, nem kell újra kinyomtatni char *optionActive = ReturnOptionSelected (); char *optionStatus = ReturnOptionStatus (); Serial.print ("Kiválasztott:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Sorozat.println (); }

Ez a menuPrint algoritmus, amely csak akkor aktiválódik, ha a menü aktív, és ha a menuNeedsPrint változó értéke true.

Ezt mindenképpen át lehetne helyezni a saját funkciójára, de az egyszerűség kedvéért..!

Hát ennyi! Lásd a következő lépést a teljes kódblokkhoz.

10. lépés: Végső kódblokk

// Állandó meghatározása

#define menuButton 2 #define menuSelect 3 #define menuMentés 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Változók definiálása long int lastDebounceTime; bool lightSensor = igaz; bool tempSensor = igaz; // Menübeállítások char * menuOptions = {"Check Temp", "Check Light"}; bool featureSetting = {hamis, hamis}; bool menuMode = hamis; bool menuNeedsPrint = false; int optionSelected = 0; // Beállítás funkció

void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Sorozat.kezdet (9600); }

// Funkció az aktuális kiválasztott opció visszaadására char *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]; // Visszatérési lehetőségKiválasztott visszatérési menüOption; } // Funkció az aktuális kiválasztott opció állapotának visszaadására char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char *optionSettingVal; if (optionSetting == hamis) {optionSettingVal = "Hamis"; } else {optionSettingVal = "Igaz"; } // Visszatérési opcióA visszatérési opció beállításaSettingVal; } // Az aktuális opció bool váltására szolgáló funkció ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; return true; } // A fő hurok

void loop () {// Olvassa el a gombokat int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Az aktuális idő lekérése long int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// A számlálási idő visszaállítása, miközben a gomb nincs lenyomva lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } if ((((currentTime - lastDebounceTime)> debounceTimeout)) {// Ha elérte az időtúllépést, nyomja meg a gombot!

// A menü gomb le van nyomva, adja meg a logikát

// Csak akkor aktiválódik, ha a gombot előzőleg elengedte, ha ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Tájékoztassa a felhasználót Serial.println ("A menü aktív"); } else if (menuMode == true && optionSelected = 1) {// Opció visszaállítása resetSelected = 0; } // A menü menü kinyomtatásaNeedsPrint = true; // Váltás a gomb között előző állapota csak a menü megjelenítéséhez // ha a gombot elengedik és ismét megnyomják menuButtonPreviousState = menuButtonPressed; // MAGAS lenne} // menuSelect le van nyomva, adjon logikát, ha ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// A kiválasztott opció módosítása // Jelenleg ez csak igaz/hamis // de bármi lehet bool toggle = ToggleOptionSelected (); if (toggle) {menuNeedsPrint = igaz; } else {Serial.print ("Valami hiba történt. Kérjük, próbálja újra"); }} // Váltás az állapotra, hogy csak akkor váltson, ha elengedi és újra megnyomja menuSelectPreviousState = menuSelectPressed; } if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Kilépés a menüből // Itt bármilyen rendrakást végezhet // vagy menthet az EEPROM menübeMode = false; Serial.println ("Kilépett a menüből"); // Váltás az állapotra, így a menü csak egyszer lép ki a menuSavePreviousState = menuSavePressed; }} // Az aktuális menüopció kinyomtatása aktív, de csak egyszer, ha (menuMode && menuNeedsPrint) {// Kinyomtattuk a menüt, így ha nem történik // valami, nem kell újra kinyomtatni menuNeedsPrint = false; char *optionActive = ReturnOptionSelected (); char *optionStatus = ReturnOptionStatus (); Serial.print ("Kiválasztott:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Sorozat.println (); }}}

Az áramkör elérhető a Tinkercad webhelyen. Beágyaztam az alábbi áramkört, hogy Ön is láthassa!

Mint mindig, ha kérdései vagy problémái vannak, kérjük, ossza meg velem!

Ajánlott: