Talaan ng mga Nilalaman:

Isang Menu sa Arduino, at Paano Gumamit ng Mga Pindutan: 10 Hakbang (na may Mga Larawan)
Isang Menu sa Arduino, at Paano Gumamit ng Mga Pindutan: 10 Hakbang (na may Mga Larawan)

Video: Isang Menu sa Arduino, at Paano Gumamit ng Mga Pindutan: 10 Hakbang (na may Mga Larawan)

Video: Isang Menu sa Arduino, at Paano Gumamit ng Mga Pindutan: 10 Hakbang (na may Mga Larawan)
Video: МАСТЕР-КЛАСС по Arduino | Полный семинар по программированию за 90 минут! 2024, Hulyo
Anonim
Isang Menu sa Arduino, at Paano Gumamit ng Mga Pindutan
Isang Menu sa Arduino, at Paano Gumamit ng Mga Pindutan

Sa aking Arduino 101 tutorial, tuturuan ka kung paano i-setup ang iyong kapaligiran sa Tinkercad. Gumagamit ako ng Tinkercad sapagkat ito ay isang napakalakas na online platform na nagpapahintulot sa akin na ipakita ang isang hanay ng mga kasanayan sa mga mag-aaral para sa pagbuo ng mga circuit. Huwag mag-atubiling bumuo ng lahat ng aking mga tutorial gamit ang Arduino IDE at isang tunay na Arduino!

Sa tutorial na ito, matututunan natin ang tungkol sa mga pindutan! Kailangan naming malaman:

  • Paano i-wire ang mga ito
  • Binabasa ang kanilang halaga
  • Ipaalam, at kung bakit ito mahalaga
  • Isang praktikal na aplikasyon (paglikha ng isang menu)

Iniisip ng karamihan sa mga tao na ang pinaka praktikal na bagay na dapat gawin sa isang pindutan ay i-on at i-off ang isang ilaw. Kami ay, wala dito! Gagamitin namin ang amin upang lumikha ng isang menu at magtakda ng ilang mga pagpipilian sa Arduino.

Handa na? Magsimula na tayo!

Hakbang 1: I-setup ang Lupon

I-setup ang Lupon
I-setup ang Lupon
I-setup ang Lupon
I-setup ang Lupon

Ang unang hakbang ay upang ilagay ang isang Arduino at Breadboard Maliit sa prototyping area. Suriin ang mga imahe sa itaas upang makita kung paano i-wire ang mga riles ng kuryente.

Ang isang Breadboard Mini ay may dalawang riles ng kuryente sa itaas at ibaba. Inaalok namin ang mga ito hanggang sa Arduino upang makapagbigay kami ng lakas sa maraming mga bahagi. Mamaya sa tutorial na ito gagamitin namin ang 3 mga pindutan kaya kakailanganin namin ng higit na lakas. Ang bagay na dapat tandaan ay sa isang maliit na tinapay, ang mga riles ng kuryente ay tumatakbo sa buong board, pahalang. Ito ay naiiba sa mga haligi sa pangunahing lugar ng prototyping sa gitna; tumatakbo nang patayo. Maaari mong gamitin ang anuman sa mga power pin upang magbigay lakas sa anumang haligi sa pangunahing lugar sa gitna.

Kapag nagdagdag ka ng lakas, gumamit ng itim at pula na mga wire sa negatibo at positibo ayon sa pagkakabanggit. Magdagdag ng mga wire sa dulo na nagpapatakbo ng kuryente sa kabilang panig ng pisara. Hindi namin gagamitin ang panig na iyon, ngunit mahusay na kasanayan.

Hakbang 2: Idagdag ang Button at Resistor

Idagdag ang Button at Resistor
Idagdag ang Button at Resistor
Idagdag ang Button at Resistor
Idagdag ang Button at Resistor
Idagdag ang Button at Resistor
Idagdag ang Button at Resistor

Magdagdag ng isang maliit na pindutan mula sa tray ng mga sangkap. Dapat itong magmukha sa nasa imahe. Tiyaking hindi ito isang switch! Magdagdag din ng risistor. I-click ito, at itakda ang halaga nito sa 10kΩ. Sapat na iyan upang hilahin ang pin na mababa kapag hindi ito nakakonekta, na napakahalaga sa paglaon sa code.

Ilagay ang bahagi sa gitna ng pisara. Ang paraan ng paggana ng isang pindutan ay:

  • Sulok sa sulok, ang pindutan ay hindi konektado. Ang pagtulak sa pindutan ay isinasara ang mga contact at kinokonekta ang mga sulok.
  • Ang mga gilid ng pindutan ay konektado. Kung ikinonekta mo ang isang kawad sa kaliwang tuktok at kaliwang kaliwa, isasara ang circuit.

Ito ang dahilan kung bakit inilalagay namin ang bahagi sa buong puwang sa gitna. Tinitiyak nito na ang mga sulok ay hindi konektado sa ilalim ng mga pin sa board.

Ang susunod na hakbang ay nagbibigay ng isang pares ng mga imahe na naglalarawan sa mga puntong ito.

Ilagay ang risistor mula sa kanang kanang pin sa mga haligi, kaya't pahiga itong nakaupo.

Hakbang 3: Mga Koneksyon sa Button

Mga Koneksyon sa Button
Mga Koneksyon sa Button
Mga Koneksyon sa Button
Mga Koneksyon sa Button

Ang mga imahe sa itaas ay ginagawang malinaw kung paano kumonekta ang mga pindutan. Ito ay palaging isang punto ng pagkalito kapag sa tingin mo ang isang bagay ay mabuti at hindi ito gumagana!

Ngayon, idagdag natin ang mga wires.

  • Maglagay ng isang pulang tingga mula sa isang positibong power pin sa parehong haligi tulad ng kanang kanang pin sa pindutan
  • Maglagay ng isang itim na tingga mula sa isang negatibong power pin sa parehong haligi ng risistor.
  • Maglagay ng isang kulay na kawad (hindi pula / itim) mula sa kaliwang tuktok na pin hanggang sa Digital Pin 2 sa Arduino

Suriin ang mga imahe sa itaas upang matiyak na ang iyong mga kable ay tama.

Hakbang 4: Ang Code…

Ang Code…
Ang Code…
Ang Code…
Ang Code…

Tingnan natin ang code para sa isang pangunahing pindutan.

Buksan ang editor ng code at baguhin mula sa Mga Block sa Teksto. I-clear ang babalang darating. Masaya kami sa text!

Alam mo ang pangunahing pag-set up, kaya't tukuyin natin ang pindutan at gumawa ng isang pangunahing basahin. I-print namin ang output sa Serial.

Naglagay ako ng ilang dagdag na mga puna sa code sa ibaba kaya mas madaling basahin kaysa sa imahe.

// Tukuyin ang mga pare-pareho

#define button 2 void setup () {pinMode (button, INPUT); Serial.begin (9600); } void loop () {// Basahin ang digital pin upang suriin ang katayuan ng button na int press = digitalRead (button); // Button nagbabalik TAAS kung pinindot, Mababa kung hindi kung (pinindot == TAAS) {Serial.println ("Pinindot!"); }}

Ok, maayos na gumagana!

Mahalaga, ang ginagawa lamang namin ay suriin ang katayuan ng digital pin sa bawat oras na ang mga loop ng code. Kung na-click mo ang Simulang Simula at pinindot ang pindutan, makikita mo ang Serial Monitor (i-click ang pindutan sa ibaba ng code) ipakita ang "Pinindot!" paulit-ulit.

Ang isang tampok na makikita mo sa code sa itaas ay kung nagaganap ang pagsusuri sa kundisyon kung (). Ang lahat ng ginagawa ng code ay humihiling ng isang katanungan at suriin kung totoo ito, sa kasong ito. Ginagamit namin ang ay pantay (dobleng pantay na mga palatandaan, tulad nito: ==) upang suriin kung ang halaga ng variable ay katumbas ng isang tiyak na halaga. Ang isang digitalRead () ay nagbabalik alinman sa TAAS o Mababa.

Gamit ang kung () kung iba pa kung / maaari naming suriin ang maraming mga kundisyon o lahat ng mga kundisyon, at kung babalik ka sa Mga Pangunahing Kaalaman sa Arduino, makikita mo ang ilan sa mga paghahambing na magagawa mo.

Ngayon … Ang aming code ay maaaring magmukhang kumpleto … Ngunit mayroon kaming problema.

Kita n'yo, talagang gumagana iyon nang maayos sa simulator. Ngunit ang tunay na elektrisidad ay may ingay, lalo na ang electronics ng DC. Kaya't ang aming pindutan ay maaaring magbalik ng maling pagbasa minsan. At problema iyan, dahil maaaring hindi tumugon ang iyong proyekto sa tamang paraan para sa gumagamit.

Ayusin natin ito!

Hakbang 5: Isang Little Debounce

Isang Little Debounce
Isang Little Debounce

Gumagamit kami ng isang pamamaraan na tinatawag na debounce upang mapagtagumpayan ang aming problema sa pindutan. Mahalagang naghihintay ito ng isang tinukoy na dami ng oras sa pagitan ng kung kailan naitulak ang pindutan at talagang tumutugon sa pagtulak. Karaniwan pa rin itong nararamdaman sa gumagamit (maliban kung gagawin mong masyadong mahaba ang oras). Maaari mo ring gamitin ito para sa pag-check sa haba ng press, kaya't maaari kang tumugon nang magkakaiba sa bawat oras. Hindi mo kailangang baguhin ang anumang mga kable!

Tingnan natin ang code:

#tukoy ang pindutan 2 # tukuyin ang debounceTimeout 100

Ang unang pagbabago ay sa pandaigdigang saklaw. Matatandaan mo na kung saan tinutukoy namin ang mga variable na maaaring gamitin ng maraming mga pag-andar o mga hindi ma-reset sa tuwing umaalis ang loop. Kaya, nagdagdag kami ng debounceTimeout sa mga tinukoy na pare-pareho. Ginawa namin itong 100 (na sa paglaon ay isasalin sa 100ms), ngunit maaaring mas maikli ito. Anumang mas mahaba at ito ay pakiramdam hindi likas.

mahaba int lastDebounceTime;

Ang variable na ito ay idineklara sa ibaba ng mga pare-pareho. Ito ay isang mahabang uri ng int, na karaniwang nagbibigay-daan sa amin upang mag-imbak ng mahabang mga numero sa memorya. Tinawag namin itong hulingDebounceTime.

Hindi namin kailangang baguhin ang anumang bagay sa pag-andar ng void setup (). Iwanan na natin ang isa.

void loop () {// Basahin ang digital pin upang suriin ang katayuan ng button int press = digitalRead (button); mahaba int kasalukuyangTime = millis (); // Button code}

Ang unang pagbabago na ginagawa namin sa pag-andar ng loop () ay nasa ilalim ng tawag upang mabasa ang pindutan. Kailangan nating subaybayan ang kasalukuyang oras. Ang pagpapaandar ng millis () ay nagbabalik ng kasalukuyang oras ng orasan mula nang mag-boot ang Arduino sa milliseconds. Kailangan nating iimbak ito sa isang mahabang variable na uri ng int.

Ngayon, kailangan naming tiyakin na may kamalayan tayo sa oras dahil pinindot ang pindutan, kaya't itinatakda namin ang timer kapag hindi ito pinindot. Tingnan:

void loop () {// Basahin ang digital pin upang suriin ang katayuan ng button int press = digitalRead (button); mahaba int kasalukuyangTime = millis (); kung (pinindot == LOW) {// I-reset ang bilang ng oras habang ang pindutan ay hindi pinindot lastDebounceTime = currentTime; } // Button code}

Sinusuri ng kung (pinindot == LOW) ang algorithm kung hindi pinindot ang pindutan. Kung hindi ito, ang code ay nag-iimbak ng kasalukuyang oras mula noong huling pag-debug. Sa ganoong paraan, sa bawat oras na pinindot ang pindutan, mayroon kaming isang punto sa oras mula sa kung saan maaari nating suriin kung kailan pinindot ang pindutan. Pagkatapos ay makakagawa tayo ng isang mabilis na pagkalkula sa matematika upang makita kung gaano katagal pinindot ang pindutan, at tumutugon nang tama. Tingnan natin ang natitirang code:

void loop () {// Basahin ang digital pin upang suriin ang katayuan ng button int press = digitalRead (button); mahabang int currentTime = millis (); kung (pinindot == LOW) {// I-reset ang bilang ng oras habang ang pindutan ay hindi pinindot lastDebounceTime = currentTime; } // Button ay pinindot para sa isang naibigay na oras kung (((currentTime - lastDebounceTime)> debounceTimeout)) {// Kung naabot ang pag-timeout, pinindot ang pindutan! Serial.println ("Pinindot!"); }}

Ang huling bloke ng code ay tumatagal ng kasalukuyang oras, binabawas ang huling oras ng pagtatalo at inihambing ito sa itinakda naming timeout. Kung ito ay mas malaki, ipinapalagay ng code na ang pindutan ay na-press para sa oras na iyon at tumutugon. Magaling!

Patakbuhin ang iyong code at suriin itong gumagana. Kung mayroon kang mga error, suriin ang iyong code!

Ngayon, tingnan natin ang isang praktikal na halimbawa.

Hakbang 6: Ang Paggawa ng isang Menu

Ang Paggawa ng isang Menu
Ang Paggawa ng isang Menu

Ang mga pindutan ay kagiliw-giliw, dahil maraming mga posibilidad sa kanila! Sa halimbawang ito, gagawa kami ng isang menu. Sabihin nating nilikha mo ang talagang mahusay na aparatong ito, at kailangan ang mga gumagamit na magawang baguhin ang mga pagpipilian upang i-on o i-off ang ilang mga bagay, o magtakda ng isang partikular na halaga para sa isang setting. Magagawa iyon ng disenyo ng tatlong pindutan!

Kaya, para sa proyektong ito kailangan namin:

  • Tatlong mga pindutan
  • Tatlong resistors ay nakatakda sa 10kΩ

Mayroon na kaming isa sa mga ito, kailangan lang namin ang dalawa pa. Kaya idagdag ang mga iyon sa pisara. Ang pag-kable ay medyo mas kumplikado, ngunit dahil lamang sa nais kong panatilihin itong talagang siksik. Maaari mong sundin ang parehong pattern para sa unang pindutan, o sundin ang imahe sa itaas.

Ang tatlong mga pindutan ay isang bukas na menu / susunod na pagpipilian, isang pagpipilian ng pagbabago (tulad ng, baguhin ang setting), at isang i-save / isara ang pindutan ng menu.

Wire up ito, tingnan natin ang code!

Hakbang 7: Pagkasira sa Code - Pandaigdigan

Ok, ito ay magiging isang mahabang hakbang, ngunit dadaan ako sa bawat seksyon ng code.

Una, tingnan natin ang mga pandaigdigang variable na kinakailangan.

// Define Constants # define menu Button 2 #define menuSelect 3 # define menuSave 4 #define debounceTimeout 50 // Tukuyin ang mga variable na int menu ButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; mahaba int lastDebounceTime; // Menu options char * menuOptions = {"Check Temp", "Check Light"}; bool tampokSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int pagpipilianSelected = 0;

Ang tatlong mga bloke na ito ay medyo katulad sa nakita natin dati. Sa una, natukoy ko ang tatlong mga pindutan at ang timeout. Para sa bahaging ito ng proyekto, naitakda ko ito sa 50ms kaya't kinakailangan ng isang sinadyang pindutin upang gumana ito.

Ang pangalawang bloke ay ang lahat ng mga variable. Kailangan naming subaybayan ang pindutan ngPreviousState, at kailangan naming subaybayan ang hulingDebounceTime. Ang mga ito ay ang lahat ng variable ng uri ng int, ngunit ang huli ay isang mahabang uri dahil ipinapalagay kong kailangan namin ang puwang sa memorya.

Ang bloke ng mga pagpipilian sa menu ay may ilang mga bagong tampok. Una, ang char * (oo, iyon ay isang sadyang asterisk), na isang character / string na literal na variable. Ito ay isang pointer sa isang static na imbakan sa memorya. Hindi mo ito mababago (tulad ng magagawa mo sa Python, halimbawa). Ang linya ng char * menuOptions na ito ay lumilikha ng isang hanay ng mga string literal. Maaari kang magdagdag ng maraming mga item sa menu ayon sa gusto mo.

Ang variable na tampok ng boolSetting ay ang hanay lamang ng mga halagang kumakatawan sa bawat item sa menu. Oo, maaari kang mag-imbak ng anumang gusto mo, baguhin lamang ang variable na uri (lahat sila ay dapat na magkatulad na uri). Ngayon, maaaring may mga mas mahusay na paraan upang pamahalaan ito, tulad ng mga diksyunaryo o tuple, ngunit ito ay simple para sa application na ito. Marahil ay lilikha ako ng isa sa huli sa isang na-deploy na application.

Sinusubaybayan ko ang menuMode, kaya kung nais ko ang iba pang mga bagay sa aking display magagawa ko iyon. Gayundin, kung nagkaroon ako ng lohika ng sensor maaari kong i-pause iyon sa panahon ng operasyon ng menu, kung sakali mang may sumalungat. Mayroon akong isang variable ng menuNeedsPrint dahil nais kong i-print ang menu sa mga tukoy na oras, hindi lamang sa lahat ng oras. Sa wakas, mayroon akong isang pagpipilianSelected variable, kaya masusubaybayan ko ang napiling pagpipilian habang ina-access ko ito sa maraming mga lugar.

Tingnan natin ang susunod na hanay ng mga pag-andar.

Hakbang 8: Pagkasira sa Code - Pag-setup at Pasadyang Mga Pag-andar

Ang pag-andar ng pag-setup () ay sapat na madali, tatlong mga pagdeklara lamang ng pag-input:

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

Susunod ang tatlong pasadyang pagpapaandar. Tingnan natin ang unang dalawa, pagkatapos ay ang huling hiwalay.

Kailangan namin ng dalawang pagpapaandar na nagbabalik ng ilang impormasyon. Ang dahilan dito, nais naming tiyakin na ito ay uri ng nababasa ng tao. Makakatulong din ito sa pag-debug ng code kung mayroon kaming isyu. Code:

// Function upang ibalik ang kasalukuyang napiling opsyonchar * ReturnOptionSelected () {char * menuOption = menuOptions [optionsSelected]; // Return optionsSelected return menuOption; } // Function upang ibalik ang katayuan ng kasalukuyang napiling pagpipilian char * ReturnOptionStatus () {bool optionsSetting = featureSetting [optionsSelected]; char * optionsSettingVal; kung (optionsSetting == false) {optionsSettingVal = "Mali"; } iba pa {optionsSettingVal = "True"; } // Return optionsSetting return optionsSettingVal; }

Sinusuri ng pagpapaandar ng char * ReturnOptionSelected () ang napiling pagpipilian (kung nakikita mo sa itaas, nagtakda kami ng isang variable upang subaybayan iyon), at hinihila ang string na literal mula sa array na nilikha namin nang mas maaga. Ito ay ibabalik ito bilang isang uri ng char. Alam namin ito dahil ipinapahiwatig ng pagpapaandar ang uri ng pagbabalik.

Ang pangalawang pagpapaandar, char * ReturnOptionStatus () ay binabasa ang katayuan ng opsyong nai-save sa array at nagbabalik ng isang literal na string na kumakatawan sa halaga. Halimbawa, kung ang setting na naimbak namin ay hindi totoo, ibabalik ko ang "Maling". Ito ay dahil ipinakita namin sa gumagamit ang variable na ito at mas mahusay na panatilihing magkasama ang lahat ng lohika na ito. Magagawa ko ito sa paglaon, ngunit mas may katuturan na gawin ito dito.

// Function toggle current optionsbool ToggleOptionSelected () {featureSetting [optionsSelected] =! TampokSetting [optionsSelected]; bumalik totoo; }

Ang function bool na ToggleOptionSelected () ay isang function na ginhawa upang baguhin ang halaga ng setting na napili namin sa menu. Binaligtad lamang nito ang halaga. Kung mayroon kang isang mas kumplikadong hanay ng mga pagpipilian, maaaring naiiba ito. Bumalik ako ng totoo sa pagpapaandar na ito, dahil ang aking callback (ang tawag sa paglaon sa code na pinapagana ang pagpapaandar na ito) ay inaasahan ang isang totoo / maling tugon. Ako ay 100% sigurado na gagana ito, kaya hindi ko ito account na hindi ito gumana, ngunit naisasagawa ko ang isang naka-deploy na application (kung sakali).

Hakbang 9: Ang Loop …

Ang pag-andar ng loop () ay medyo mahaba, kaya't gagawin namin ito sa mga bahagi. Maaari mong isipin ang lahat sa ibaba ng mga pugad sa loob ng pagpapaandar na ito:

void loop () {

// Gumawa ka ba dito <-----}

Ok, nakita natin ang bagay na ito dati:

// Basahin ang mga pindutan int menu ButtonPressed = digitalRead (menu Button); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Get the current time long int currentTime = millis (); kung (menu ButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// I-reset ang bilang ng oras habang ang pindutan ay hindi pinindot lastDebounceTime = currentTime; menu ButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }

Ang kailangan ko lang gawin dito ay idagdag sa tatlong mga digitalRead () na tawag, at tiyakin na accounted ko ang katotohanan na kung ang lahat ng mga pindutan ay mababa, dapat naming i-reset ang timer (lastDebounceTime = currentTime) at itakda ang lahat ng nakaraang mga estado sa mababa. Nag-iimbak din ako ng millis () sa kasalukuyangTime.

Ang susunod na seksyon ay namumula sa loob ng linya

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

// Do work in here <----}

Mayroong tatlong seksyon. Oo, maililipat ko sila sa kanilang sariling mga pag-andar, ngunit alang-alang sa pagiging simple itinago ko ang tatlong pangunahing mga algorithm ng pindutan dito.

kung ((menu ButtonPressed == MATAAS) && (menu ButtonPreviousState == LOW)) {kung (menuMode == false) {menuMode = true; // Ipaalam sa gumagamit ang Serial.println ("Aktibo ang menu"); } iba pa kung (menuMode == true && optionsSelected = 1) {// Reset options optionsSelected = 0; } // I-print ang menu menuNeedsPrint = totoo; // Toggle the button prev. ipahayag lamang ang ipakita ang menu // kung ang pindutan ay pinakawalan at pinindot muli ang menu ButtonPreviousState = menu ButtonPressed; // would be HIGH}

Ang unang ito ang humahawak kapag ang menu ButtonPressed ay HIGH, o kapag ang pindutan ng menu ay pinindot. Sinusuri din nito upang matiyak na ang dating estado ay mababa, kaya't ang pindutan ay dapat na pinakawalan bago ito pinindot muli, na humihinto sa programa mula sa patuloy na pagpapaputok ng parehong kaganapan nang paulit-ulit.

Sinusuri nito pagkatapos kung ang menu ay hindi aktibo, pinapagana nito. Ipi-print nito ang unang pagpipilian na napili (na kung saan ay ang unang item sa menu ng Option array bilang default. Kung pinindot mo ang pindutan sa isang segundo o pangatlo (atbp) oras, makakakuha ka ng susunod na pagpipilian sa listahan. Isang bagay na maaari kong ayusin ay na pagdating sa dulo, bumabalik ito sa simula. Maaari nitong basahin ang haba ng array at gawing mas madali ang pagbibisikleta kung binago mo ang bilang ng mga pagpipilian, ngunit ito ay simple para sa ngayon.

Ang huling maliit na seksyon (// Nagpi-print sa menu) ay malinaw na naka-print ang menu, ngunit itinatakda din nito ang dating estado sa TAAS kaya ang parehong pag-andar ay hindi loop (tingnan ang aking tala sa itaas tungkol sa pag-check kung ang pindutan ay dating mababa).

// menuSelect ay pinindot, magbigay ng logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {kung (menuMode) {// Baguhin ang napiling pagpipilian // Sa ngayon, ito ay totoo / false // ngunit maaaring maging anumang toggle ng bool = ToggleOptionSelected (); kung (toggle) {menuNeedsPrint = totoo; } iba pa {Serial.println ("May naganap na mali. Mangyaring subukang muli"); }} // Toggle state toggle lang kung pinakawalan at pinindot ulit menuSelectPreviousState = menuSelectPressed; }

Ang bit ng code na ito ang humahawak sa pindutan ng menuSelectPressed sa parehong paraan, maliban sa oras na ito ay ipaputok lamang namin ang function na ToggleOptionSelected (). Tulad ng sinabi ko dati, maaari mong baguhin ang pagpapaandar na ito kaya't higit pa ang ginagawa, ngunit iyon lang ang kailangan kong gawin.

Ang pangunahing bagay na dapat tandaan ay ang variable ng toggle, na sumusubaybay sa tagumpay ng callback at i-print ang menu kung totoo. Kung wala itong ibabalik o mali, mai-print nito ang mensahe ng error. Dito mo magagamit ang iyong callback upang gumawa ng ibang mga bagay.

kung ((menuSavePressed == MATAAS) && (menuSavePreviousState == LOW)) {// Lumabas sa menu // Dito maaari mong gawin ang anumang pag-ayos // o i-save sa EEPROM menuMode = false; Serial.println ("Lumabas sa menu"); // Toggle state so menu only exits once menuSavePreviousState = menuSavePressed; }}

Hinahawakan ng pagpapaandar na ito ang pindutan ng menuSave, na lalabas lamang sa menu. Dito ka maaaring magkaroon ng isang pagkansela o i-save ang pagpipilian, marahil ay maglinis o mag-save sa EEPROM. Nai-print ko lang ang "Exit ng Menu" at itinakda ang pindutan ng estado sa TAAS upang hindi ito loop.

kung (menuMode && menuNeedsPrint) {// Nag-print kami ng menu, kaya maliban kung may // // mangyari, hindi na kailangang i-print muli ito menuNeedsPrint = false; char * optionsActive = ReturnOptionSelected (); char * optionsStatus = ReturnOptionStatus (); Serial.print ("Napili:"); Serial.print (optionsActive); Serial.print (":"); Serial.print (optionsStatus); Serial.println (); }

Ito ang algorithm ng menuPrint, na nagpapagana lamang kapag ang menu ay aktibo at kapag ang menuNeedsPrint variable ay nakatakda sa totoo.

Tiyak na maililipat ito sa sarili nitong pag-andar, ngunit alang-alang sa pagiging simple..!

Aba, ayan na! Tingnan ang susunod na hakbang para sa buong bloke ng code.

Hakbang 10: Final Code Block

// Tukuyin ang mga pare-pareho

#define menu Button 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 int menu ButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Tukuyin ang mga variable na matagal nang hulingDebounceTime; bool lightSensor = totoo; bool tempSensor = totoo; // Menu options char * menuOptions = {"Check Temp", "Check Light"}; bool tampokSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int pagpipilianSelected = 0; // Pag-andar ng pag-setup

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

// Function upang ibalik ang kasalukuyang napiling pagpipilian char * ReturnOptionSelected () {char * menuOption = menuOptions [optionsSelected]; // Return optionsSelected return menuOption; } // Function upang ibalik ang katayuan ng kasalukuyang napiling pagpipilian char * ReturnOptionStatus () {bool optionsSetting = featureSetting [optionsSelected]; char * optionsSettingVal; kung (optionsSetting == false) {optionsSettingVal = "Mali"; } iba pa {optionsSettingVal = "True"; } // Return optionsSetting return optionsSettingVal; } // Function upang i-toggle ang kasalukuyang pagpipilian bool ToggleOptionSelected () {featureSetting [optionsSelected] =! TampokSetting [optionsSelected]; bumalik totoo; } // Ang pangunahing loop

void loop () {// Basahin ang mga pindutan int menu ButtonPressed = digitalRead (menu Button); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Get the current time long int currentTime = millis (); kung (menu ButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// I-reset ang bilang ng oras habang ang pindutan ay hindi pinindot lastDebounceTime = currentTime; menu ButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } kung (((kasalukuyangTime - lastDebounceTime)> debounceTimeout)) {// Kung naabot ang pag-timeout, pinindot ang pindutan!

// menu Button ay pinindot, magbigay ng lohika

// Sunog lamang kapag ang pindutan ay dati nang inilabas kung ((menu ButtonPressed == HIGH) && (menu ButtonPreviousState == LOW)) {kung (menuMode == false) {menuMode = true; // Ipaalam sa gumagamit ang Serial.println ("Aktibo ang menu"); } iba pa kung (menuMode == true && optionsSelected = 1) {// Reset options optionsSelected = 0; } // I-print ang menu menuNeedsPrint = totoo; // Toggle the button prev. ipahayag lamang ang ipakita ang menu // kung ang pindutan ay pinakawalan at pinindot muli ang menu ButtonPreviousState = menu ButtonPressed; // would be HIGH} // menuSelect ay pinindot, magbigay ng lohika kung ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {kung (menuMode) {// Baguhin ang napiling pagpipilian // Sa ngayon, ito ay totoo lamang / maling // ngunit maaaring maging anumang bagay na toggle = ToggleOptionSelected (); kung (toggle) {menuNeedsPrint = totoo; } iba pa {Serial.print ("Nagkaproblema. Mangyaring subukang muli"); }} // Toggle state toggle lang kung pinakawalan at pinindot ulit menuSelectPreviousState = menuSelectPressed; } kung ((menuSavePressed == MATAAS) && (menuSavePreviousState == LOW)) {// Lumabas sa menu // Dito maaari mong gawin ang anumang pag-ayos // o i-save sa EEPROM menuMode = false; Serial.println ("Lumabas sa menu"); // Toggle state so menu only exits once menuSavePreviousState = menuSavePressed; }} // I-print ang kasalukuyang pagpipilian ng menu na aktibo, ngunit i-print lamang ito minsan kung (menuMode && menuNeedsPrint) {// Nai-print namin ang menu, kaya maliban kung may isang bagay // na nangyari, hindi na kailangang i-print muli ito menuNeedsPrint = false; char * optionsActive = ReturnOptionSelected (); char * optionsStatus = ReturnOptionStatus (); Serial.print ("Napili:"); Serial.print (optionsActive); Serial.print (":"); Serial.print (optionsStatus); Serial.println (); }}}

Magagamit ang circuit sa site na Tinkercad. Na-embed ko ang circuit sa ibaba para makita mo din!

Tulad ng dati, kung mayroon kang mga katanungan o isyu, mangyaring ipaalam sa akin!

Inirerekumendang: