Përmbajtje:

Një menu në Arduino dhe si të përdorni butona: 10 hapa (me fotografi)
Një menu në Arduino dhe si të përdorni butona: 10 hapa (me fotografi)

Video: Një menu në Arduino dhe si të përdorni butona: 10 hapa (me fotografi)

Video: Një menu në Arduino dhe si të përdorni butona: 10 hapa (me fotografi)
Video: Топ 5 скрытых полезных программ Windows 10 2024, Korrik
Anonim
Një menu në Arduino dhe si të përdorni butona
Një menu në Arduino dhe si të përdorni butona

Në tutorialin tim Arduino 101, do të mësoheni se si të konfiguroni mjedisin tuaj në Tinkercad. Unë përdor Tinkercad sepse është një platformë mjaft e fuqishme në internet që më lejon të demonstroj një sërë aftësish për studentët për ndërtimin e qarqeve. Ndjehuni të lirë të ndërtoni të gjitha mësimet e mia duke përdorur Arduino IDE dhe një Arduino të vërtetë!

Në këtë tutorial, ne do të mësojmë rreth butonave! Duhet të dimë:

  • Si t'i lidhni ato
  • Leximi i vlerës së tyre
  • Debounce, dhe pse është e rëndësishme
  • Një aplikim praktik (krijimi i një menuje)

Shumica e njerëzve mendojnë se gjëja më praktike për të bërë me një buton është ndezja dhe fikja e dritës. Ne do, jo këtu! Ne do të përdorim tonën për të krijuar një menu dhe për të vendosur disa opsione në Arduino.

Gati? Le të fillojmë!

Hapi 1: Vendosni Bordin

Vendosni Bordin
Vendosni Bordin
Vendosni Bordin
Vendosni Bordin

Hapi i parë është të vendosni një Arduino dhe Breadboard Small në zonën e prototipimit. Kontrolloni imazhet e mësipërme për të parë se si të lidhni binarët e energjisë.

Një Breadboard Mini ka dy shina energjie sipër dhe poshtë. Ne i lidhim ato me Arduino në mënyrë që të mund të sigurojmë energji për më shumë përbërës. Më vonë në këtë tutorial ne do të përdorim 3 butona kështu që do të na duhet më shumë energji. Gjëja që duhet vënë re është se në një pjatë të vogël, binarët e energjisë kalojnë në të gjithë bordin, horizontalisht. Kjo është e ndryshme nga kolonat në zonën kryesore të prototipimit në mes; këto funksionojnë vertikalisht. Ju mund të përdorni ndonjë nga kunjat e energjisë për të siguruar energji për çdo kolonë në zonën kryesore në mes.

Kur shtoni energji, përdorni tela të zinj dhe të kuq përkatësisht negativ dhe pozitiv. Shtoni tela në fund që kalojnë energjinë në anën tjetër të tabelës. Ne nuk do ta përdorim atë anë, por është praktikë e mirë.

Hapi 2: Shtoni butonin dhe rezistencën

Shtoni butonin dhe rezistencën
Shtoni butonin dhe rezistencën
Shtoni butonin dhe rezistencën
Shtoni butonin dhe rezistencën
Shtoni butonin dhe rezistencën
Shtoni butonin dhe rezistencën

Shtoni një buton të vogël nga tabaka e përbërësve. Duhet të duket si ajo në imazh. Sigurohuni që nuk është një ndërprerës! Shtoni gjithashtu një rezistencë. Klikoni mbi të dhe vendosni vlerën e tij në 10kΩ. Kjo është e mjaftueshme për ta tërhequr pinin poshtë kur nuk është i lidhur, gjë që është shumë e rëndësishme më vonë në kod.

Vendoseni përbërësin në mes të tabelës së bukës. Mënyra se si funksionon një buton është:

  • Këndi në cep, butoni nuk është i lidhur. Shtypja e butonit mbyll kontaktet dhe lidh qoshet.
  • Anët e butonit janë të lidhura. Nëse lidhni një tel në pjesën e sipërme majtas dhe poshtë majtas, qarku do të mbyllet.

Kjo është arsyeja pse ne e vendosim përbërësin në të gjithë hapësirën në mes. Sigurohet që qoshet të mos jenë të lidhur nën kunjat në tabelë.

Hapi tjetër siguron disa imazhe që ilustrojnë këto pika.

Vendoseni rezistencën nga kunja e poshtme e djathtë nëpër kolona, në mënyrë që të ulet horizontalisht.

Hapi 3: Lidhjet e butonave

Lidhjet e butonave
Lidhjet e butonave
Lidhjet e butonave
Lidhjet e butonave

Imazhet e mësipërme e bëjnë mjaft të qartë sesi lidhen butonat. Ishte gjithmonë një pikë konfuzioni kur mendon se diçka është mirë dhe nuk funksionon!

Tani, le të shtojmë telat.

  • Vendosni një plumb të kuq nga një kunj pozitiv i fuqisë në të njëjtën kolonë si kunja e poshtme e djathtë në buton
  • Vendosni një plumb të zi nga një kunj i fuqisë negative në të njëjtën kolonë me rezistencën.
  • Vendosni një tel me ngjyrë (jo të kuqe/të zezë) nga kunja e sipërme e majtë në Kunjin dixhital 2 në Arduino

Kontrolloni imazhet e mësipërme për t'u siguruar që instalimet tuaja elektrike janë të sakta.

Hapi 4: Kodi…

Kodi…
Kodi…
Kodi…
Kodi…

Le të hedhim një vështrim në kodin për një buton bazë.

Hapni redaktorin e kodit dhe ndryshoni nga Blocks në Text. Pastroni paralajmërimin që vjen. Ne jemi të kënaqur me tekstin!

Ju e dini konfigurimin bazë, kështu që le të përcaktojmë butonin dhe të bëjmë një lexim bazë. Ne do të shtypim daljen në Serial.

Vendosa disa komente shtesë në kodin më poshtë, kështu që është më e lehtë të lexohet sesa imazhi.

// Përcaktoni konstantet

#define button 2 void setup () {pinMode (button, INPUT); Serial.filloj (9600); } void loop () {// Lexoni pinin dixhital për të kontrolluar statusin e butonit int të shtypur = digitalRead (buton); // Butoni kthehet LART HIGH nëse shtypet, LOW nëse jo nëse (shtypur == LART) {Serial.println ("Shtypur!"); }}

Ok, mirë që funksionon!

Në thelb, gjithçka që ne po bëjmë është të kontrollojmë statusin e pinit dixhital sa herë që kodet lakojnë. Nëse klikoni Start Simulation dhe shtypni butonin, do të shihni ekranin Serial (kliko butonin poshtë kodit) "Presed!" në mënyrë të përsëritur.

Një veçori që do të shihni në kodin e mësipërm është vlerësimi i gjendjes if (). E tëra që kodi po bën është të bëni një pyetje dhe të vlerësoni nëse është e vërtetë, në këtë rast. Ne përdorim barazinë (shenja të barabarta të dyfishta, si kjo: ==) për të kontrolluar nëse vlera e ndryshores është e barabartë me një vlerë të caktuar. Një digitalRead () kthen ose HIGH ose LOW.

Duke përdorur if () tjetër nëse / përndryshe ne mund të kontrollojmë shumë kushte ose të gjitha kushtet, dhe nëse ktheheni në Bazat e Arduino, do të shihni disa nga krahasimet që mund të bëni.

Tani… Kodi ynë mund të duket i plotë … Por ne kemi një problem.

Shikoni, kjo funksionon vërtet mirë kur jeni në imitues. Por energjia elektrike e vërtetë ka zhurmë, veçanërisht elektronika DC. Pra, butoni ynë ndonjëherë mund të kthejë një lexim të rremë. Dhe ky është një problem, sepse projekti juaj mund të mos përgjigjet në mënyrën e duhur për përdoruesit.

Le ta rregullojmë!

Hapi 5: Pak Debounce

Një Debounce e Vogël
Një Debounce e Vogël

Ne përdorim një procedurë të quajtur debounce për të kapërcyer problemin tonë të butonit. Kjo në thelb pret një kohë të caktuar midis shtypjes së butonit dhe përgjigjes në të vërtetë ndaj shtytjes. Ende ndihet e natyrshme për përdoruesin (nëse nuk e bëni kohën shumë të gjatë). Ju gjithashtu mund ta përdorni atë për të kontrolluar gjatësinë e shtypit, kështu që ju mund të përgjigjeni ndryshe çdo herë. Nuk keni nevojë të ndryshoni asnjë prej instalimeve elektrike!

Le të shikojmë kodin:

#përcakto butonin 2#përcakto debounceTimeout 100

Ndryshimi i parë është në fushën globale. Ju do të mbani mend se aty përcaktojmë variablat që shumë prej funksioneve tona mund të përdorin ose ato që nuk mund të rivendosen sa herë që laku të ndizet. Pra, ne shtuam debounceTimeout në konstantet e përcaktuara. Ne e bëmë këtë 100 (e cila më vonë do të përkthehet në 100ms), por mund të jetë më e shkurtër. Më gjatë dhe do të duket e panatyrshme.

long int lastDebounceTime;

Ky ndryshore deklarohet nën konstantet. Ky është një lloj i gjatë int, i cili në thelb na lejon të ruajmë numra të gjatë në kujtesë. Ne e quajtëm atë lastDebounceTime.

Ne nuk kemi nevojë të ndryshojmë asgjë në funksionin void setup (). Le ta lëmë atë.

void loop () {// Lexoni pinin dixhital për të kontrolluar statusin e butonit int të shtypur = digitalRead (buton); gjatë int currentTime = millis (); // Kodi i butonit}

Ndryshimi i parë që bëjmë në funksionin loop () është nën thirrjen për të lexuar butonin. Ne duhet të mbajmë gjurmët e kohës aktuale. Funksioni millis () kthen kohën aktuale të orës që kur Arduino filloi në milisekonda. Ne duhet ta ruajmë këtë në një ndryshore të tipit int të gjatë.

Tani, ne duhet të sigurohemi që jemi të vetëdijshëm për kohën që kur është shtypur butoni, kështu që ne e rivendosim kohëmatësin kur nuk shtypet. Hidhi nje sy:

void loop () {// Lexoni pinin dixhital për të kontrolluar statusin e butonit int të shtypur = digitalRead (buton); gjatë int currentTime = millis (); nëse (shtypur == LOW) {// Rivendos kohën e numërimit ndërsa butoni nuk shtypet lastDebounceTime = currentTime; } // Kodi i butonit}

Algoritmi if (shtypur == LOW) kontrollon nëse butoni nuk shtypet. Nëse nuk është, atëherë kodi ruan kohën aktuale që nga debunimi i fundit. Në atë mënyrë, sa herë që shtypet butoni, ne kemi një pikë në kohë nga e cila mund të kontrollojmë kur është shtypur butoni. Ne pastaj mund të bëjmë një llogaritje të shpejtë matematikore për të parë se për sa kohë është shtypur butoni dhe të përgjigjemi saktë. Le të shikojmë pjesën tjetër të kodit:

void loop () {// Lexoni pinin dixhital për të kontrolluar statusin e butonit int të shtypur = digitalRead (buton); gjatë int currentTime = millis (); nëse (shtypur == LOW) {// Rivendos kohën e numërimit ndërsa butoni nuk shtypet lastDebounceTime = currentTime; } // Butoni është shtypur për një kohë të caktuar nëse ((((aktualTime - lastDebounceTime)> debounceTimeout)) {// Nëse afati është arritur, shtypni butonin! Serial.println ("Shtypur!"); }}

Blloku i fundit i kodit merr kohën aktuale, zbret kohën e fundit të zbërthimit dhe e krahason atë me afatin kohor që kemi vendosur. Nëse është më i madh, kodi supozon se butoni është shtypur për atë kohë dhe përgjigjet. I zoti!

Drejtoni kodin tuaj dhe kontrolloni se funksionon. Nëse keni gabime, kontrolloni kodin tuaj!

Tani, le të shohim një shembull praktik.

Hapi 6: Krijimi i një menuje

Krijimi i një menuje
Krijimi i një menuje

Butonat janë interesantë, sepse ka kaq shumë mundësi me to! Në këtë shembull, ne do të bëjmë një menu. Le të themi që ju keni krijuar këtë pajisje vërtet të mrekullueshme dhe keni nevojë që përdoruesit të jenë në gjendje të ndryshojnë opsionet për të aktivizuar ose fikur gjëra të caktuara, ose për të vendosur një vlerë të veçantë për një cilësim. Ky dizajn me tre butona mund ta bëjë këtë!

Pra, për këtë projekt na duhen:

  • Tre butona
  • Tre rezistencë të vendosur në 10kΩ

Ne tashmë kemi një nga këto, na duhen vetëm dy të tjerat. Pra, shtojini ato në tabelë. Instalimi është pak më kompleks, por vetëm sepse doja ta mbaja vërtet kompakt. Ju mund të ndiqni të njëjtin model për butonin e parë, ose të ndiqni imazhin e mësipërm.

Tre butonat janë një menu e hapur/opsioni tjetër, një opsion ndryshimi (si në, ndryshoni cilësimin) dhe një buton i menysë ruajtje/mbyllje.

Lidheni atë, le të shohim kodin!

Hapi 7: Ndarja e Kodit - Global

Ok, ky do të jetë një hap i gjatë, por unë do të kaloj nëpër secilën pjesë të kodit.

Së pari, le të shohim ndryshoret globale të nevojshme.

// Përcakto konstantet #përcakto menynëButoni 2 #përcakto menynëZgjidh 3 #përcakto menynëKurso 4 #përcakto debounceTimeout 50 // Përcakto variablat në menunëButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; long int lastDebounceTime; // Opsionet e menusë char * menuOptions = {"Kontrollo Temp", "Kontrollo dritën"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0;

Këto tre blloqe janë mjaft të ngjashme me atë që kemi parë më parë. Në të parën, unë kam përcaktuar tre butonat dhe afatin kohor. Për këtë pjesë të projektit, e kam vendosur në 50ms kështu që duhet një shtyp i qëllimshëm për ta bërë atë të funksionojë.

Blloku i dytë janë të gjitha ndryshoret. Ne duhet të mbajmë gjurmët e butonitPreviousState, dhe duhet të mbajmë gjurmët e funditDebounceTime. Këto janë të gjitha variabla të tipit int, por e fundit është një lloj i gjatë sepse po supozoj se na duhet hapësira në memorie.

Blloku i opsioneve të menusë ka disa veçori të reja. Së pari, char * (po, ky është një yll i qëllimshëm), i cili është një ndryshore fjalë për fjalë karakter/varg. Shtë një tregues për një ruajtje statike në kujtesë. Ju nuk mund ta ndryshoni atë (siç mund të bëni në Python, për shembull). Kjo linjë char *menuOptions krijon një sërë letrash të vargut. Ju mund të shtoni sa më shumë artikuj të menusë që dëshironi.

Ndryshorja e funksionit boolSetting është vetëm një grup vlerash që përfaqëson çdo artikull të menysë. Po, mund të ruani gjithçka që ju pëlqen, thjesht ndryshoni llojin e ndryshores (të gjithë duhet të jenë të të njëjtit lloj). Tani, mund të ketë mënyra më të mira për ta menaxhuar këtë, si fjalorë ose tuple, por kjo është e thjeshtë për këtë aplikacion. Unë ndoshta do të krijoja një nga këto të fundit në një aplikacion të vendosur.

Unë kam mbajtur gjurmët e menyve të menusë, kështu që nëse do të doja gjëra të tjera në ekranin tim, mund ta bëja atë. Gjithashtu, nëse do të kisha logjikën e sensorit mund ta ndaloja atë gjatë funksionimit të menysë, vetëm në rast se diçka bie ndesh. Unë kam një ndryshore menuNeedsPrint sepse dua të printoj menunë në kohë të veçanta, jo vetëm gjatë gjithë kohës. Së fundi, unë kam një variabël optionSelected, kështu që unë mund të mbaj shënime opsionin e zgjedhur ndërsa e qasem atë në një numër vendesh.

Le të shikojmë grupin tjetër të funksioneve.

Hapi 8: Ndarja e Kodit - Konfigurimi dhe Funksionet e personalizuara

Funksioni i konfigurimit () është mjaft i lehtë, vetëm tre deklarata hyrëse:

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

Tjetra janë tre funksionet e personalizuara. Le të shikojmë dy të parët, pastaj të fundit veç e veç.

Ne kemi nevojë për dy funksione që kthejnë disa informacione. Arsyeja është, ne duam të sigurohemi që kjo është një lloj e lexueshme nga njerëzit. Gjithashtu do të ndihmojë me korrigjimin e kodit nëse kemi një problem. Kodi:

// Funksioni për të kthyer opsionin aktual të zgjedhurchar *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]; // Opsioni i kthimitMenyja e zgjedhur e kthimitOpsioni; } // Funksioni për të kthyer statusin e opsionit aktual të zgjedhur char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char *optionSettingVal; nëse (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "E vërtetë"; } // Opsioni i kthimitSetting option returnSettingVal; }

Funksioni char *ReturnOptionSelected () kontrollon opsionin e zgjedhur (nëse shihni më lart, ne vendosim një ndryshore për ta mbajtur atë), dhe tërheq vargun fjalë për fjalë nga grupi që kemi krijuar më herët. Pastaj e kthen atë si një tip char. Ne e dimë këtë sepse funksioni tregon llojin e kthimit.

Funksioni i dytë, char *ReturnOptionStatus () lexon statusin e opsionit të ruajtur në grup dhe kthen një varg literal që përfaqëson vlerën. Për shembull, nëse cilësimi që kemi ruajtur është i rremë, unë do të ktheja "False". Kjo ndodh sepse ne i tregojmë përdoruesit këtë ndryshore dhe është më mirë të mbash të gjithë këtë logjikë së bashku. Mund ta bëj më vonë, por ka më shumë kuptim ta bëj këtu.

// Funksioni për të ndryshuar opsionin aktualbool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; kthehet e vërtetë; }

Funksioni bool ToggleOptionSelected () është një funksion i përshtatshëm për të ndryshuar vlerën e cilësimit që kemi zgjedhur në meny. Thjesht e kthen vlerën. Nëse keni pasur një grup opsionesh më komplekse, kjo mund të jetë krejtësisht e ndryshme. Unë kthehem i vërtetë në këtë funksion, sepse thirrja ime (thirrja më vonë në kodin që aktivizon këtë funksion) pret një përgjigje të vërtetë/të rreme. Unë jam 100% i sigurt se kjo do të funksionojë, kështu që nuk kam marrë parasysh që nuk funksionon, por do ta bëja në një aplikacion të vendosur (për çdo rast).

Hapi 9: Lakja…

Funksioni loop () është mjaft i gjatë, kështu që ne do ta bëjmë atë në pjesë. Ju mund të supozoni gjithçka nën foletë brenda këtij funksioni:

lak void () {

// Bëni punë këtu <-----}

Ok, ne i kemi parë këto gjëra më parë:

// Lexoni butonat int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Merrni kohën aktuale të gjatë int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Rivendos kohën e numërimit ndërsa butoni nuk shtypet lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }

E tëra çfarë më duhej të bëja këtu ishte të shtoja në tre thirrjet digitalRead () dhe të sigurohesha që kisha parasysh faktin se nëse të gjithë butonat ishin të ulët, ne duhet të rivendosim kohëmatësin (lastDebounceTime = currentTime) dhe t'i vendosim të gjitha gjendjet e mëparshme në të ulët. Unë gjithashtu ruaj millis () në currentTime.

Seksioni tjetër fole brenda linjës

nëse (((aktualeTime - lastDebounceTime)> debounceTimeout)) {

// Bëni punë këtu <----}

Ka tre seksione. Po, unë mund t'i kisha zhvendosur ato në funksionet e tyre, por për hir të thjeshtësisë kam mbajtur këtu tre algoritmet kryesore të butonave.

nëse ((menuButtonPressed == LART) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Lëreni përdoruesin të dijë Serial.println ("Menyja është aktive"); } else if (menuMode == e vërtetë && optionSelected = 1) {// Rivendos opsionin opsionSelected = 0; } // Shtyp menunë e menusëNeedsPrint = true; // Ndrysho butonin e mëparshëm. gjendja për të shfaqur vetëm menunë // nëse butoni lëshohet dhe shtypet përsëri menuButtonPreviousState = menuButtonPressed; // Do të ishte LART}}

Kjo e para trajton kur menuButtonPressed është LART, ose kur shtypet butoni i menysë. Ai gjithashtu kontrollon për të siguruar që gjendja e mëparshme të ishte LOW, kështu që butoni duhej të lëshohej para se të shtyhej përsëri, gjë që ndalon programin të shkrepë vazhdimisht të njëjtën ngjarje pa pushim.

Pastaj kontrollon që nëse menyja nuk është aktive, e aktivizon atë. Ai do të printojë opsionin e parë të zgjedhur (i cili është artikulli i parë në menunë Opsionet e grupit sipas parazgjedhjes. Nëse shtypni butonin për herë të dytë ose të tretë (etj), do të merrni opsionin tjetër në listë. Diçka që mund të rregulloj është që kur të arrijë në fund, ai kthehet në fillim. Kjo mund të lexojë gjatësinë e grupit dhe të bëjë çiklizmin më të lehtë nëse ndryshoni numrin e opsioneve, por kjo ishte e thjeshtë tani për tani.

Seksioni i fundit i vogël (// Shtyp menunë) padyshim që printon menunë, por gjithashtu vendos gjendjen e mëparshme në HIGH kështu që i njëjti funksion nuk do të lakohet (shiko shënimin tim më lart për të kontrolluar nëse butoni ishte më parë i ULOWT).

// menuSelect shtypet, jep logjikif ((menuSelectPressed == LART) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Ndrysho opsionin e zgjedhur // Për momentin, kjo është thjesht e vërtetë/e rreme // por mund të jetë gjithçka bool toggle = ToggleOptionSelected (); if (kaloni) {menuNeedsPrint = true; } else {Serial.println ("Diçka nuk shkoi mirë. Provo përsëri"); }} // Ndrysho gjendjen për të ndryshuar vetëm nëse lëshohet dhe shtypet përsëri menuSelectPreviousState = menuSelectPressed; }

Kjo pjesë e kodit trajton butonin menuSelectPressed në të njëjtën mënyrë, me përjashtim të kësaj rradhe që ne thjesht aktivizojmë funksionin ToggleOptionSelected (). Siç thashë më parë, ju mund ta ndryshoni këtë funksion në mënyrë që të bëjë më shumë, por kjo është gjithçka që më duhet për të bërë.

Gjëja kryesore që duhet vënë re është ndryshorja e ndërrimit, e cila gjurmon suksesin e thirrjes dhe printon menunë nëse është e vërtetë. Nëse nuk kthen asgjë ose të rreme, do të printojë mesazhin e gabimit. Këtu mund të përdorni përgjigjen e thirrjes për të bërë gjëra të tjera.

nëse ((menuSavePressed == LART) && (menuSavePreviousState == LOW)) {// Dilni nga menyja // Këtu mund të bëni ndonjë rregullim // ose të ruani në menynë EEPROMMode = false; Serial.println ("Menyja doli"); // Ndrysho gjendjen kështu menyja del vetëm një herë menuSavePreviousState = menuSavePressed; }}

Ky funksion trajton butonin menuSave, i cili sapo del nga menyja. Këtu mund të keni një opsion anulimi ose ruajtjeje, ndoshta bëni një pastrim ose ruani në EEPROM. Unë thjesht printoj "Meny doli" dhe e vendos gjendjen e butonit në LART në mënyrë që të mos lakohet.

nëse (menuMode && menuNeedsPrint) {// Ne e kemi shtypur menunë, kështu që nëse diçka // nuk ndodh, nuk ka nevojë ta printoni përsëri menuNeedsPrint = false; char *optionActive = ReturnOptionSelected (); char *optionStatus = ReturnOptionStatus (); Serial.print ("Zgjedhur:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }

Ky është algoritmi menuPrint, i cili ndizet vetëm kur menuja është aktive dhe kur ndryshorja menuNeedsPrint është vendosur në true.

Kjo patjetër mund të zhvendoset në funksionin e vet, por për hir të thjeshtësisë..!

Epo, kjo është ajo! Shikoni hapin tjetër për të gjithë bllokun e kodit.

Hapi 10: Blloku i Kodit Final

// Përcaktoni konstantet

#përcakto menynëButoni 2 #përcakto menunëPërzgjidhni 3 #përcaktoni menunëKurseni 4 #përcaktoni debounceTimeout 50 int menuButtonPrepareState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Përcaktoni variablat long int lastDebounceTime; bool lightSensor = e vërtetë; bool tempSensor = e vërtetë; // Opsionet e menusë char * menuOptions = {"Kontrollo Temp", "Kontrollo dritën"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0; // Funksioni i konfigurimit

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

// Funksioni për të kthyer opsionin aktual të zgjedhur char *ReturnOptionSelected () {char *menuOption = menuOptions [optionSelected]; // Opsioni i kthimitMenyja e zgjedhur e kthimitOpsioni; } // Funksioni për të kthyer statusin e opsionit aktual të zgjedhur char *ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char *optionSettingVal; nëse (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "E vërtetë"; } // Opsioni i kthimitSetting option returnSettingVal; } // Funksioni për të ndryshuar opsionin aktual bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; kthehet e vërtetë; } // Laku kryesor

void loop () {// Lexoni butonat int menuButtonPpress = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Merrni kohën aktuale të gjatë int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Rivendos kohën e numërimit ndërsa butoni nuk shtypet lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } nëse (((aktualTime - lastDebounceTime)> debounceTimeout)) {// Nëse mbaron afati, shtypni butonin!

// menuButton shtypet, jep logjikë

// Ndez vetëm kur butoni është lëshuar më parë nëse ((menuButtonPressed == LART) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Lëreni përdoruesin të dijë Serial.println ("Menyja është aktive"); } else if (menuMode == e vërtetë && optionSelected = 1) {// Rivendos opsionin opsionSelected = 0; } // Shtyp menunë e menusëNeedsPrint = true; // Ndrysho butonin e mëparshëm. gjendja për të shfaqur vetëm menunë // nëse butoni lëshohet dhe shtypet përsëri menuButtonPreviousState = menuButtonPressed; // Do të ishte HIGH} // menuSelect është shtypur, jep logjikë nëse ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Ndrysho opsionin e zgjedhur // Për momentin, kjo është thjesht true/false // por mund të jetë çdo gjë bool toggle = ToggleOptionSelected (); if (kaloni) {menuNeedsPrint = true; } else {Serial.print ("Diçka nuk shkoi mirë. Provo përsëri"); }} // Ndrysho gjendjen për të ndryshuar vetëm nëse lëshohet dhe shtypet përsëri menuSelectPreviousState = menuSelectPressed; } if ((menuSavePressed == LART) && (menuSavePreviousState == LOW)) {// Dilni nga menyja // Këtu mund të bëni ndonjë rregullim // ose të ruani në menynë EEPROMMode = false; Serial.println ("Menyja doli"); // Ndrysho gjendjen kështu menyja del vetëm një herë menuSavePreviousState = menuSavePressed; }} // Shtypni opsionin aktual të menusë aktive, por printojeni vetëm një herë nëse (menuMode && menuNeedsPrint) {// Ne e kemi shtypur menunë, kështu që nëse nuk ndodh //, nuk ka nevojë ta printoni përsëri menuNeedsPrint = false; char *optionActive = ReturnOptionSelected (); char *optionStatus = ReturnOptionStatus (); Serial.print ("Zgjedhur:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }}}

Qarku është i disponueshëm në sitin Tinkercad. Unë kam futur qarkun më poshtë që ta shihni edhe ju!

Si gjithmonë, nëse keni pyetje ose çështje, ju lutem më tregoni!

Recommended: