Cuprins:
- Pasul 1: configurați placa
- Pasul 2: Adăugați butonul și rezistorul
- Pasul 3: Conexiuni buton
- Pasul 4: Codul …
- Pasul 5: O mică dezamăgire
- Pasul 6: Realizarea unui meniu
- Pasul 7: defalcarea codului - global
- Pasul 8: defalcarea codului - Setare și funcții personalizate
- Pasul 9: Bucla …
- Pasul 10: Blocarea codului final
Video: Un meniu în Arduino și modul de utilizare a butoanelor: 10 pași (cu imagini)
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:44
În tutorialul meu Arduino 101, veți fi învățat cum să vă configurați mediul în Tinkercad. Folosesc Tinkercad, deoarece este o platformă online destul de puternică, care îmi permite să demonstrez o serie de abilități studenților pentru construirea circuitelor. Simțiți-vă liber să construiți toate tutorialele mele folosind Arduino IDE și un adevărat Arduino!
În acest tutorial, vom afla despre butoane! Trebuie sa stim:
- Cum să le conectăm
- Citindu-le valoarea
- Dezbateți și de ce este important
- O aplicație practică (crearea unui meniu)
Majoritatea oamenilor cred că cel mai practic lucru cu un buton este aprinderea și oprirea luminii. Vom, nu aici! O vom folosi pe a noastră pentru a crea un meniu și pentru a seta câteva opțiuni pe Arduino.
Gata? Să începem!
Pasul 1: configurați placa
Primul pas este să puneți un Arduino și Breadboard Small pe zona de prototipare. Verificați imaginile de mai sus pentru a vedea cum să conectați șinele de alimentare.
Un Breadboard Mini are două șine superioare și inferioare. Le conectăm la Arduino, astfel încât să putem furniza energie mai multor componente. Mai târziu în acest tutorial vom folosi 3 butoane, astfel încât vom avea nevoie de mai multă putere. Lucrul de remarcat este că pe o placă mică, șinele electrice trec peste bord, orizontal. Acest lucru este diferit de coloanele din zona principală de prototipare din mijloc; acestea rulează vertical. Puteți utiliza oricare dintre pinii de alimentare pentru a furniza energie oricărei coloane din zona principală din mijloc.
Când adăugați putere, utilizați fire negre și roșii la negativ și respectiv pozitiv. Adăugați fire la capăt care alimentează cealaltă parte a plăcii. Nu vom folosi această latură, dar este o bună practică.
Pasul 2: Adăugați butonul și rezistorul
Adăugați un mic buton din tava pentru componente. Ar trebui să arate ca cel din imagine. Asigurați-vă că nu este un comutator! Adăugați și un rezistor. Faceți clic pe acesta și setați valoarea sa la 10kΩ. Acest lucru este suficient pentru a trage pinul jos când nu este conectat, ceea ce este foarte important mai târziu în cod.
Așezați componenta peste mijlocul panoului. Modul în care funcționează un buton este:
- Colț în colț, butonul nu este conectat. Apăsarea butonului închide contactele și conectează colțurile.
- Partile laterale ale butonului sunt conectate. Dacă ați conectat un fir la stânga sus și la stânga jos, circuitul ar fi închis.
Acesta este motivul pentru care punem componenta în spațiul din mijloc. Se asigură că colțurile nu sunt conectate sub pinii din tablă.
Următorul pas oferă câteva imagini care ilustrează aceste puncte.
Așezați rezistorul din pinul din dreapta jos, peste coloane, astfel încât să stea orizontal.
Pasul 3: Conexiuni buton
Imaginile de mai sus arată destul de clar modul în care butoanele se conectează. A fost întotdeauna un punct de confuzie atunci când crezi că ceva este totul bun și nu funcționează!
Acum, să adăugăm firele.
- Așezați un cablu roșu de la un știft de putere pozitivă la aceeași coloană ca știftul din dreapta jos de pe buton
- Așezați un cablu negru de la un pin negativ de putere la aceeași coloană ca rezistența.
- Plasați un fir colorat (nu roșu / negru) de la pinul din stânga sus la pinul digital 2 de pe Arduino
Verificați imaginile de mai sus pentru a vă asigura că cablajul este corect.
Pasul 4: Codul …
Să aruncăm o privire la codul unui buton de bază.
Deschideți editorul de cod și treceți de la Blocuri la Text. Ștergeți avertismentul care apare. Suntem mulțumiți de text!
Cunoașteți configurarea de bază, așa că haideți să definim butonul și să facem o citire de bază. Vom imprima ieșirea pe Serial.
Am pus câteva comentarii suplimentare în codul de mai jos, astfel încât să fie mai ușor de citit decât imaginea.
// Definiți constantele
#define button 2 void setup () {pinMode (buton, INPUT); Serial.begin (9600); } void loop () {// Citiți pinul digital pentru a verifica starea butonului int apăsat = digitalRead (buton); // Butonul returnează HIGH dacă este apăsat, LOW dacă nu dacă (apăsat == HIGH) {Serial.println ("Apăsat!"); }}
Ok, bine asta funcționează!
În esență, tot ce facem este să verificăm starea pinului digital de fiecare dată când codul se blochează. Dacă faceți clic pe Start Simulare și apăsați butonul, veți vedea ecranul Serial Monitor (faceți clic pe butonul de sub cod) afișat „Apăsat!” repetat.
O caracteristică pe care o veți vedea în codul de mai sus este evaluarea condiției if () care are loc. Tot ceea ce face codul este să pună o întrebare și să evalueze dacă este adevărat, în acest caz. Folosim este egal (semne egale duble, astfel: ==) pentru a verifica dacă valoarea variabilei este egală cu o anumită valoare. Un digitalRead () returnează fie HIGH, fie LOW.
Folosind if () else if / else putem verifica multe condiții sau toate condițiile și, dacă reveniți la noțiunile de bază Arduino, veți vedea câteva dintre comparațiile pe care le puteți face.
Acum … Codul nostru ar putea părea complet … Dar avem o problemă.
Vezi, asta funcționează foarte bine când ești în simulator. Însă electricitatea reală are zgomot, în special electronice de curent continuu. Deci butonul nostru ar putea întoarce uneori o citire falsă. Și aceasta este o problemă, deoarece proiectul dvs. ar putea să nu răspundă în mod corect pentru utilizator.
Să o reparăm!
Pasul 5: O mică dezamăgire
Folosim o procedură numită debounce pentru a depăși problema butonului nostru. Acest lucru așteaptă, în esență, o perioadă de timp specificată între momentul în care butonul a fost apăsat și răspunsul efectiv la apăsare. Se simte în continuare natural pentru utilizator (cu excepția cazului în care faceți timpul prea lung). De asemenea, îl puteți utiliza pentru a verifica durata apăsării, astfel încât să puteți răspunde diferit de fiecare dată. Nu trebuie să schimbați niciun cablaj!
Să ne uităm la cod:
#define button 2 # define debounceTimeout 100
Prima schimbare se referă la domeniul de aplicare global. Vă veți aminti că acolo definim variabile pe care o pot folosi multe dintre funcțiile noastre sau care nu pot fi resetate de fiecare dată când bucla se declanșează. Deci, am adăugat debounceTimeout la constantele definite. Am făcut acest 100 (care se va traduce ulterior la 100ms), dar ar putea fi mai scurt. Mai mult și se va simți nefiresc.
long int lastDebounceTime;
Această variabilă este declarată sub constante. Acesta este un tip int lung, care practic ne permite să stocăm numere lungi în memorie. Am numit-o lastDebounceTime.
Nu este nevoie să schimbăm nimic în funcția de configurare nulă (). Să-l lăsăm pe acela.
void loop () {// Citiți pinul digital pentru a verifica starea butonului int apăsat = digitalRead (buton); long int currentTime = millis (); // Cod buton}
Prima modificare pe care o facem în funcția loop () este sub apel pentru a citi butonul. Trebuie să urmărim ora curentă. Funcția millis () returnează ora curentă a ceasului de când Arduino a pornit în milisecunde. Trebuie să stocăm acest lucru într-o variabilă de tip int lung.
Acum, trebuie să ne asigurăm că suntem conștienți de timpul de la apăsarea butonului, așa că resetăm temporizatorul atunci când nu este apăsat. Aruncați o privire:
void loop () {// Citiți pinul digital pentru a verifica starea butonului int apăsat = digitalRead (buton); long int currentTime = millis (); if (apăsat == LOW) {// Resetați timpul de numărare în timp ce butonul nu este apăsat lastDebounceTime = currentTime; } // Cod buton}
Algoritmul if (apăsat == LOW) verifică dacă butonul nu este apăsat. Dacă nu este, atunci codul stochează ora curentă de la ultima retragere. În acest fel, de fiecare dată când butonul este apăsat, avem un moment în care putem verifica când a fost apăsat butonul. Putem face apoi un calcul matematic rapid pentru a vedea cât timp a fost apăsat butonul și pentru a răspunde corect. Să ne uităm la restul codului:
void loop () {// Citiți pinul digital pentru a verifica starea butonului int apăsat = digitalRead (buton); long int currentTime = millis (); if (apăsat == LOW) {// Resetați timpul de numărare în timp ce butonul nu este apăsat lastDebounceTime = currentTime; } // Butonul a fost apăsat pentru un anumit timp dacă (((CurrentTime - lastDebounceTime)> debounceTimeout)) {// Dacă timpul de expirare este atins, butonul este apăsat! Serial.println („Apăsat!”); }}
Ultimul bloc de cod ia ora curentă, scade ultimul timp de debounce și îl compară cu timeout-ul stabilit de noi. Dacă este mai mare, codul presupune că butonul a fost apăsat pentru acea perioadă și răspunde. Ingrijit!
Rulați codul și verificați dacă funcționează. Dacă aveți erori, verificați codul!
Acum, să privim un exemplu practic.
Pasul 6: Realizarea unui meniu
Butoanele sunt interesante, deoarece există atât de multe posibilități la ele! În acest exemplu, vom crea un meniu. Să presupunem că ați creat acest dispozitiv cu adevărat grozav și că aveți nevoie ca utilizatorii să poată schimba opțiunile pentru a activa sau dezactiva anumite lucruri sau pentru a seta o anumită valoare pentru o setare. Acest design cu trei butoane poate face asta!
Deci, pentru acest proiect avem nevoie de:
- Trei butoane
- Trei rezistențe setate la 10kΩ
Avem deja una dintre acestea, avem nevoie doar de celelalte două. Așa că adăugați-le pe tablă. Cablarea este puțin mai complexă, dar numai pentru că am vrut să o păstrez cu adevărat compactă. Ați putea urma același model pentru primul buton sau urmați imaginea de mai sus.
Cele trei butoane sunt o opțiune meniu deschis / următor, o opțiune de modificare (ca în, modificați setarea) și un buton meniu salvare / închidere.
Conectează-l, să ne uităm la cod!
Pasul 7: defalcarea codului - global
Ok, acesta va fi un pas lung, dar voi parcurge fiecare secțiune de cod.
În primul rând, să analizăm variabilele globale necesare.
// Definirea constantelor # define menuButton 2 #define menuSelect 3 # define menuSave 4 #define debounceTimeout 50 // Definirea variabilelor int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; long int lastDebounceTime; // Opțiuni meniu char * menuOptions = {"Verificați temperatura", "Verificați lumina"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0;
Aceste trei blocuri sunt destul de similare cu ceea ce am văzut înainte. În primul, am definit cele trei butoane și timpul de expirare. Pentru această parte a proiectului, l-am setat la 50 ms, așa că este nevoie de o presă deliberată pentru a-l face să funcționeze.
Al doilea bloc este reprezentat de toate variabilele. Trebuie să ținem evidența butonuluiPreviousState și trebuie să ținem evidența ultimuluiDebounceTime. Acestea sunt toate variabile de tip int, dar ultima este de tip lung, deoarece presupun că avem nevoie de spațiul din memorie.
Blocul de opțiuni al meniului are câteva caracteristici noi. În primul rând, char * (da, acesta este un asterisc deliberat), care este o variabilă literală de caractere / șiruri. Este un indicator către o stocare statică în memorie. Nu o puteți schimba (așa cum puteți face în Python, de exemplu). Această linie char * menuOptions creează o matrice de litere șir. Puteți adăuga câte elemente de meniu doriți.
Variabila featureSetting bool este doar matricea de valori care reprezintă fiecare element de meniu. Da, ai putea să stochezi orice îți place, doar să schimbi tipul variabilei (toate trebuie să fie de același tip). Acum, ar putea exista modalități mai bune de a gestiona acest lucru, cum ar fi dicționarele sau tuplurile, dar acest lucru este simplu pentru această aplicație. Aș crea probabil unul dintre acestea din urmă într-o aplicație implementată.
Am ținut evidența meniului Mode, așa că dacă aș dori alte lucruri pe ecranul meu aș putea face asta. De asemenea, dacă aș avea logica senzorului, aș putea întrerupe acest lucru în timpul funcționării meniului, doar în cazul în care ceva intră în conflict. Am o variabilă menuNeedsPrint pentru că vreau să tipăresc meniul la anumite ore, nu doar tot timpul. În cele din urmă, am o variabilă optionSelected, astfel încât să pot urmări opțiunea selectată pe măsură ce o accesez în mai multe locuri.
Să ne uităm la următorul set de funcții.
Pasul 8: defalcarea codului - Setare și funcții personalizate
Funcția setup () este suficient de ușoară, doar trei declarații de intrare:
void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }
Următoarele sunt cele trei funcții personalizate. Să ne uităm la primele două, apoi la ultima separat.
Avem nevoie de două funcții care returnează unele informații. Motivul este că vrem să ne asigurăm că acesta este un fel de citit de om. De asemenea, va ajuta la depanarea codului dacă avem o problemă. Cod:
// Funcție pentru a returna opțiunea curentă selectată char * ReturnOptionSelected () {char * menuOption = menuOptions [optionSelected]; // Opțiune de returnare Meniu de returnare selectat Opțiune; } // Funcție pentru a returna starea opțiunii curente selectate char * ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char * optionSettingVal; if (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; }
Funcția char * ReturnOptionSelected () verifică opțiunea selectată (dacă vedeți mai sus, setăm o variabilă pentru a urmări asta) și extrage șirul literal din matricea pe care am creat-o mai devreme. Apoi îl returnează ca tip char. Știm acest lucru deoarece funcția indică tipul de returnare.
A doua funcție, char * ReturnOptionStatus () citește starea opțiunii salvate în matrice și returnează un literal șir care reprezintă valoarea. De exemplu, dacă setarea pe care am stocat-o este falsă, aș întoarce „False”. Acest lucru se datorează faptului că îi arătăm utilizatorului această variabilă și este mai bine să păstrăm toată această logică împreună. Aș putea să o fac mai târziu, dar are mai mult sens să o fac aici.
// Funcție pentru a comuta opțiunea curentă bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; întoarce-te adevărat; }
Funcția bool ToggleOptionSelected () este o funcție comodă pentru a modifica valoarea setării pe care am selectat-o în meniu. Întoarce valoarea. Dacă ați avea un set de opțiuni mai complex, acest lucru ar putea fi destul de diferit. Întorc adevărat în această funcție, deoarece apelul meu (apelul ulterior din codul care declanșează această funcție) așteaptă un răspuns adevărat / fals. Sunt 100% sigur că acest lucru va funcționa, așa că nu mi-am dat seama că nu funcționează, dar aș face-o într-o aplicație implementată (pentru orice eventualitate).
Pasul 9: Bucla …
Funcția loop () este destul de lungă, așa că o vom face în părți. Puteți presupune că totul este mai jos cuiburi în cadrul acestei funcții:
bucla nulă () {
// Lucrați aici <-----}
Ok, am văzut aceste lucruri înainte:
// Citiți butoanele int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Obțineți timpul curent lung int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Resetați timpul de numărare în timp ce butonul nu este apăsat lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }
Tot ce a trebuit să fac aici a fost să adaug în cele trei apeluri digitalRead () și să mă asigur că am contat faptul că, dacă toate butoanele ar fi reduse, ar trebui să resetăm temporizatorul (lastDebounceTime = currentTime) și să setăm toate stările anterioare la nivel scăzut. De asemenea, stochez millis () în currentTime.
Următoarea secțiune se cuibărește în interiorul liniei
if (((currentTime - lastDebounceTime)> debounceTimeout)) {
// Lucrați aici <----}
Există trei secțiuni. Da, aș fi putut să le mut în propriile funcții, dar, din simplitate, am păstrat aici cei trei algoritmi principali ai butoanelor.
if ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Anunțați utilizatorul Serial.println („Meniul este activ”); } else if (menuMode == true && optionSelected = 1) {// Reset option optionSelected = 0; } // Imprimați meniul menuNeedsPrint = true; // Comutați butonul prev. state pentru a afișa meniul numai // dacă butonul este eliberat și apăsat din nou menuButtonPreviousState = menuButtonPressed; // Ar fi ÎNALT}
Primul se ocupă când meniul ButonPresat este ÎNALT sau când este apăsat butonul meniu. De asemenea, verifică pentru a vă asigura că starea anterioară a fost scăzută, astfel încât butonul a trebuit să fie eliberat înainte de a fi apăsat din nou, ceea ce împiedică programul să declanșeze în mod constant același eveniment de mai multe ori.
Apoi verifică dacă, dacă meniul nu este activ, îl activează. Se va imprima prima opțiune selectată (care este primul element din meniul matrice Opțiuni în mod implicit. Dacă apăsați butonul o a doua sau a treia oară (etc), veți primi următoarea opțiune din listă. Ceva pe care aș putea să-l remediez este că, când ajunge la sfârșit, revine la început. Acest lucru ar putea citi lungimea matricei și ar putea face ciclismul mai ușor dacă schimbați numărul de opțiuni, dar acest lucru a fost simplu pentru moment.
Ultima mică secțiune (// Tipărește meniul) tipărește evident meniul, dar stabilește și starea anterioară la HIGH astfel încât aceeași funcție să nu se bucle (vezi nota mea de mai sus despre verificarea dacă butonul a fost anterior LOW).
// menuSelect este apăsat, furnizați logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Schimbați opțiunea selectată // În acest moment, acest lucru este doar adevărat / fals // dar ar putea fi orice bool toggle = ToggleOptionSelected (); if (comutare) {menuNeedsPrint = true; } else {Serial.println ("Ceva nu a mers bine. Încercați din nou"); }} // Comutați starea pentru a comuta numai dacă este eliberat și apăsat din nou menuSelectPreviousState = menuSelectPressed; }
Acest bit de cod gestionează meniul Selectați butonul apăsat în același mod, cu excepția faptului că de această dată lansăm doar funcția ToggleOptionSelected (). Așa cum am spus mai înainte, puteți schimba această funcție, astfel încât să facă mai mult, dar asta este tot ceea ce am nevoie pentru a face.
Principalul lucru de remarcat este variabila de comutare, care urmărește succesul apelului invers și imprimă meniul dacă este adevărat. Dacă nu returnează nimic sau este fals, va imprima mesajul de eroare. Aici puteți folosi apelul pentru a face alte lucruri.
if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Ieșiți din meniu // Aici puteți face orice ordine // sau salvați în EEPROM menuMode = false; Serial.println („Meniul a ieșit”); // Comutați starea, astfel încât meniul iese doar o dată menuSavePreviousState = menuSavePressed; }}
Această funcție gestionează butonul menuSave, care iese din meniu. Aici ați putea avea o opțiune de anulare sau salvare, poate faceți ceva curățare sau salvați în EEPROM. Imprim doar „Meniu ieșit” și setez starea butonului la ÎNALT, astfel încât să nu se bucle.
if (menuMode && menuNeedsPrint) {// Am imprimat meniul, deci dacă nu se întâmplă //, nu este nevoie să-l imprimăm din nou menuNeedsPrint = false; char * optionActive = ReturnOptionSelected (); char * optionStatus = ReturnOptionStatus (); Serial.print ("Selectat:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }
Acesta este algoritmul menuPrint, care se declanșează numai când meniul este activ și când variabila menuNeedsPrint este setată la adevărat.
Acest lucru ar putea fi mutat cu siguranță la propria funcție, dar din simplitate..!
Ei bine, asta e! Consultați pasul următor pentru întregul bloc de cod.
Pasul 10: Blocarea codului final
// Definiți constantele
#define menuButton 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Definiți variabile long int lastDebounceTime; bool lightSensor = adevărat; bool tempSensor = adevărat; // Opțiuni meniu char * menuOptions = {"Verificați temperatura", "Verificați lumina"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0; // Funcția de configurare
void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }
// Funcție pentru a returna opțiunea curentă selectată char * ReturnOptionSelected () {char * menuOption = menuOptions [optionSelected]; // Opțiune de returnare Meniu de returnare selectat Opțiune; } // Funcție pentru a returna starea opțiunii curente selectate char * ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char * optionSettingVal; if (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; } // Funcție pentru a comuta opțiunea curentă bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; întoarce-te adevărat; } // Bucla principală
void loop () {// Citiți butoanele int menButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Obțineți timpul curent lung int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Resetați timpul de numărare în timp ce butonul nu este apăsat lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } if (((currentTime - lastDebounceTime)> debounceTimeout)) {// Dacă timpul de expirare este atins, butonul apăsat!
// menuButton este apăsat, furnizați logică
// Se declanșează numai când butonul a fost eliberat anterior dacă ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Anunțați utilizatorul Serial.println („Meniul este activ”); } else if (menuMode == true && optionSelected = 1) {// Reset option optionSelected = 0; } // Imprimați meniul menuNeedsPrint = true; // Comutați butonul prev. state pentru a afișa meniul numai // dacă butonul este eliberat și apăsat din nou menuButtonPreviousState = menuButtonPressed; // Ar fi HIGH} // menuSelect este apăsat, furnizați logică if ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Schimbați opțiunea selectată // În acest moment, aceasta este doar adevărat / fals // dar ar putea fi orice bool toggle = ToggleOptionSelected (); if (comutare) {menuNeedsPrint = true; } else {Serial.print ("Ceva nu a mers bine. Încercați din nou"); }} // Comutați starea pentru a comuta numai dacă este eliberat și apăsat din nou menuSelectPreviousState = menuSelectPressed; } if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Ieșiți din meniu // Aici puteți face orice ordonare // sau salvați în EEPROM menuMode = false; Serial.println („Meniul a ieșit”); // Comutați starea, astfel încât meniul iese doar o dată menuSavePreviousState = menuSavePressed; }} // Imprimați opțiunea de meniu curentă activă, dar imprimați-o doar o dată dacă (menuMode && menuNeedsPrint) {// Am imprimat meniul, deci dacă nu se întâmplă ceva //, nu este nevoie să îl imprimați din nou menuNeedsPrint = false; char * optionActive = ReturnOptionSelected (); char * optionStatus = ReturnOptionStatus (); Serial.print ("Selectat:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }}}
Circuitul este disponibil pe site-ul Tinkercad. Am încorporat circuitul de mai jos pentru ca tu să îl vezi și tu!
Ca întotdeauna, dacă aveți întrebări sau probleme, vă rugăm să ne anunțați!
Recomandat:
Instrucțiuni despre modul de utilizare a tăietorului de vinil MH871-MK2: 11 pași
Instrucțiuni despre utilizarea unui tăietor de vinil MH871-MK2: Bună ziua, mă numesc Ricardo Greene și am făcut instrucțiuni despre modul de utilizare a tăietorului de vinil MH871-MK2
Ghid de utilizare a setului de solenoizi Sol-EZ Ghid de utilizare: 9 pași
Sol-EZ Solenoid Driver Kit Ghid de utilizare: DISCLAIMER: ACEST ESTE UN GHID DE UTILIZARE PENTRU UN PRODUS: KITUL DE SOLENOID SOL-EZ SOLID. Acesta nu este un proiect DIY
Robot Arduino controlat vocal + Cameră Wifi + Gripper + APP și utilizare manuală și modul de evitare a obstacolelor (KureBas Ver 2.0): 4 pași
Robot Arduino controlat vocal + Cameră Wifi + Gripper + APP și utilizare manuală și modul de evitare a obstacolelor (KureBas Ver 2.0): KUREBAS V2.0 este înapoi El este foarte impresionant cu funcții noi. Are un gripper, cameră Wifi și o nouă aplicație care i-a fost produsă
HC-06 (Modul Slave) Schimbarea „NAME” Fără utilizare „Monitor Serial Arduino” „Funcționează cu ușurință”: mod fără defecte!: 3 pași
HC-06 (Modul Slave) Schimbarea „NAME” Fără utilizare „Monitor Serial Arduino” … că „Funcționează cu ușurință”: Mod fără probleme!: După " Mult timp " încercarea de a schimba numele pe HC-06 (modul slave), folosind " monitor serial al Arduino, fără " Succes ", am găsit o altă modalitate ușoară și sunt acum partajare! Distrează-te prieteni
Orange PI HowTo: configurați-l pentru utilizare cu un afișaj LCD TFT HDMI de 5 ": 8 pași (cu imagini)
Orange PI HowTo: configurați-l pentru a fi utilizat cu un afișaj LCD TFT HDMI de 5 ": Dacă ați fost suficient de prudent pentru a comanda un afișaj LCD TFT HDMI împreună cu Orange PI, probabil că sunteți descurajat de dificultățile în încercarea de a-l forța să funcționeze … În timp ce alții nu ar putea observa niciun obstacol. Cheia este că există la