Talaan ng mga Nilalaman:

Digital Watch sa Arduino Gamit ang isang Finite State Machine: 6 Mga Hakbang
Digital Watch sa Arduino Gamit ang isang Finite State Machine: 6 Mga Hakbang

Video: Digital Watch sa Arduino Gamit ang isang Finite State Machine: 6 Mga Hakbang

Video: Digital Watch sa Arduino Gamit ang isang Finite State Machine: 6 Mga Hakbang
Video: CS50 2014 - Week 9 2024, Nobyembre
Anonim
Digital Watch sa Arduino Gamit ang isang Finite State Machine
Digital Watch sa Arduino Gamit ang isang Finite State Machine

Hoy, ipapakita ko sa iyo kung paano malilikha ang isang digital na relo gamit ang YAKINDU Statechart Tools at patakbuhin ang isang Arduino, na gumagamit ng isang LCD Keypad Shield.

Ang orihinal na modelo ng digital na relo ay kinuha mula kay David Harel. Nag-publish siya ng isang papel tungkol sa

"[…] Malawak na pagpapalawak ng maginoo pormalismo ng mga machine ng estado at mga diagram ng estado."

Sa papel na ito, ginamit niya ang halimbawa ng digital na relo para sa kanyang pagsasaliksik. Ginamit ko ito bilang isang inspirasyon at itinayong muli ang relo gamit ang YAKINDU Statechart Tools (isang tool para sa paglikha ng mga graphic na modelo ng mga state machine at bumuo ng C / C ++ code kasama nito) at binuhay ko ulit ito sa isang Arduino.

Mga gamit

Hardware:

  • Arduino Uno o Mega
  • LCD Keypad Shield

Software:

  • YAKINDU Statechart Tools
  • Eclipse C ++ IDE para sa Arduino

Hakbang 1: Paano Gumagana ang Digital Watch

Image
Image

Magsimula tayo sa pamamagitan ng pagtukoy kung paano dapat gumana ang digital na relo. Naaalala mo ba ang mga ito … sabihin natin … "ultra cool" na mga digital na relo na lahat ay bumalik noong '90s? Isang pinagsamang stopwatch, iba't ibang mga alarma at nakakainis na beep bawat buong oras. Kung hindi, tingnan: digital na relo ng 90.

Kaya karaniwang ito ay isang nai-configure na relo na may iba't ibang mga mode. Pangunahin, ang kasalukuyang oras ay ipapakita, ngunit may ilang iba pang mga tampok. Bilang input, mayroon kang isang on / off, isang mode at isang set button. Bilang karagdagan, maaari mong i-on at i-off ang ilaw. Gamit ang pindutan ng mode maaari mong makilala ang pagitan ng mga mode at buhayin / huwag paganahin ang mga tampok na orasan:

  • Ipakita ang oras (Orasan)
  • Ipakita ang petsa (Petsa)
  • Itakda ang alarm (Alarm 1, Alarm 2)
  • Paganahin / huwag paganahin ang chime (Itakda ang Chime)
  • Gamitin ang stopwatch (Stop Watch)

Sa loob ng mga menu, maaari mong gamitin ang on / off button upang i-configure ang mode. Pinapayagan ka ng set button na itakda ang oras - hal. para sa orasan o mga alarma. Ang controlwatch ay maaaring makontrol - nagsimula at tumigil - sa pamamagitan ng paggamit ng ilaw na ilaw at ilaw na pindutan. Maaari mo ring gamitin ang isang integrated lap counter

Bukod dito, mayroong isang tunog ng tunog, na kung saan ang mga kampanilya bawat buong oras, at isang nakakontrol na backlight na isinama. Sa unang hakbang, hindi ko sila wire sa Arduino.

Hakbang 2: Ang State Machine

LCD Keypad Shield
LCD Keypad Shield

Ayokong pumunta sa detalyado para sa paliwanag ng halimbawang ito. Hindi ito dahil sa sobrang kumplikado, medyo napakalaki lamang nito. Susubukan kong ipaliwanag ang pangunahing ideya kung paano ito gumagana. Ang pagpapatupad ay dapat na nagpapaliwanag sa sarili, sa pamamagitan ng pagtingin sa modelo o i-download at gayahin ito. Ang ilang mga bahagi ng makina ng estado ay nabubuo sa mga sub rehiyon, tulad ng itinakdang rehiyon ng oras. Sa pamamagitan nito, ang pagiging madaling mabasa ng makina ng estado ay dapat na matiyak.

Ang modelo ay nahahati sa dalawang bahagi - isang grapiko at isang pangkonteksto. Sa tekstuwal na bahagi ang mga kaganapan, variable, atbp ay matutukoy. Sa grapikong bahagi - ang diagram ng estado - ang lohikal na pagpapatupad ng modelo ay tinukoy. Upang lumikha ng isang machine ng estado, na natutupad ang tinukoy na pag-uugali, kinakailangan ang ilang mga kaganapan sa pag-input, na maaaring magamit sa modelo: onoff, set, mode, light, at light_r. Sa loob ng seksyon ng kahulugan ay ginagamit ang isang panloob na kaganapan, na kung saan ay nagdaragdag ng halaga ng oras bawat 100 ms:

tuwing 100 ms / oras + = 1

Batay sa mga hakbang na 100 ms ang kasalukuyang oras ay makakalkula sa format ng HH: MM: SS:

display.first = (oras / 36000)% 24;

display.second = (oras / 600)% 60; display.third = (oras / 10)% 60;

Ang mga halaga ay mai-wire sa display ng LCD sa pamamagitan ng paggamit ng pag-update ngLCLC sa tuwing tatawagin ang makina ng estado:

display.updateLCD (display.first, display.second, display.third, display.text)

Ang pangunahing pagpapatupad ng makina ng estado ay natukoy na sa seksyon Kung paano gumagana ang Digital Watch. Sa loob ng tool na ginamit ko ang ilang mga "espesyal" na elemento ng pagmomodelo tulad ng CompositeState, History, Sub-Diagrams, ExitNodes, atbp. Ang isang detalyadong paglalarawan ay matatagpuan sa Patnubay ng Gumagamit.

Hakbang 3: LCD Keypad Shield

Ang LCD Keypad Shield ay medyo cool para sa mga simpleng proyekto, na nangangailangan ng isang screen para sa visualization at ilang mga pindutan bilang input - isang tipikal, simpleng HMI (Human Machine Interface). Naglalaman ang LCD Keypad Shield ng limang mga pindutan ng gumagamit at isa pa para i-reset. Ang limang mga pindutan nang magkakasama ay konektado sa A0 pin ng Arduino. Ang bawat isa sa kanila ay konektado sa isang divider ng boltahe, na nagbibigay-daan sa pagkilala sa pagitan ng mga pindutan.

Maaari mong gamitin ang analogRead (0) upang hanapin ang mga tukoy na halaga, na maaari, syempre, naiiba ng gumagawa. Ipinapakita ng simpleng proyekto na ito ang kasalukuyang halaga sa LCD:

# isama ang "Arduino.h"

# isama ang "LiquidCrystal.h" LiquidCrystal lcd (8, 9, 4, 5, 6, 7); void setup () {lcd.begin (16, 2); lcd.setCursor (0, 0); lcd.write ("Sinusukat na Halaga"); } void loop () {lcd.setCursor (0, 1); lcd.print (""); lcd.setCursor (0, 1); lcd.print (analogRead (0)); pagkaantala (200); }

Ito ang aking sinusukat na mga resulta:

  • Wala: 1023
  • Piliin ang: 640
  • Kaliwa: 411
  • Pababa: 257
  • Pataas: 100
  • Kanan: 0

Sa mga threshold na ito posible na basahin ang mga pindutan:

#define WALA 0 # tukuyin ang PUMILI 1 # tukuyin ang KALIWAN 2 # tukuyin ang Pababang 3 # tukuyin UP 4 # tukuyin ANG KARAPATAN 5 static int read Button () {int resulta = 0; resulta = analogRead (0); kung (resulta <50) {bumalik TAMA; } kung (resulta <150) {return UP; } kung (resulta <300) {bumalik sa BAWAL; } kung (resulta <550) {ibalik ang KALIWAN; } kung (resulta <850) {return SELECT; } bumalik WALA; }

Hakbang 4: Interfacing ng State Machine

Ang pagitan ng Makina ng Estado
Ang pagitan ng Makina ng Estado

Ang nabuong C ++ code ng makina ng estado ay nagbibigay ng mga interface, na dapat ipatupad upang makontrol ang makina ng estado. Ang unang hakbang ay ang pagkonekta sa mga kaganapan sa mga susi ng Keypad Shield. Ipinakita ko na kung paano basahin ang mga pindutan, ngunit para sa pag-interfaced ang mga ito sa machine ng estado, kinakailangan ang pag-debon ng mga pindutan - kung hindi man, ang mga kaganapan ay itataas nang maraming beses, na nagreresulta sa hindi mahuhulaan na pag-uugali. Ang konsepto ng pag-debug ng software ay hindi bago. Maaari kang tumingin sa dokumentasyon ng Arduino.

Sa aking pagpapatupad, nakita ko ang isang bumabagsak na gilid (bitawan ang pindutan). Nabasa ko ang halaga ng pindutan, maghintay para sa 80 ms (nakakuha ng mas mahusay na mga resulta na may 80 sa halip na 50), i-save ang resulta at basahin ang bagong halaga. Kung ang oldResult ay hindi WALA (hindi naka-compress) at ang bagong resulta ay WALA, alam ko, na ang pindutan ay pinindot nang dati at ngayon ay pinakawalan. Pagkatapos, taasan ko ang naaangkop na kaganapan sa pag-input ng makina ng estado.

int oldState = NONE; static void pagtaasEvents () {int buttonPressed = read Button (); pagkaantala (80); oldState = buttonPressed; kung (oldState! = WALA && read Button () == WALA) {switch (oldState) {case SELECT: {stateMachine-> getSCI_Button () -> pagtaas_mode (); pahinga; } case LEFT: {stateMachine-> getSCI_ Button () -> pagtaas_set (); pahinga; } case Down: {stateMachine-> getSCI_ Button () -> pagtaas_light (); pahinga; } case UP: {stateMachine-> getSCI_ Button () -> pagtaas_light_r (); pahinga; } case RIGHT: {stateMachine-> getSCI_ Button () -> pagtaas_onoff (); pahinga; } default: {break; }}}}

Hakbang 5: Mga bagay na Magkabit ng Kable

Ang pangunahing programa ay gumagamit ng tatlong bahagi:

  • Ang Machine ng Estado
  • Isang Timer
  • Isang Display Handler (karaniwang lcd.print (…))

DigitalWatch * stateMachine = bagong DigitalWatch (); CPPTimerInterface * timer_sct = bagong CPPTimerInterface (); DisplayHandler * displayHandler = bagong DisplayHandler ();

Gumagamit ang makina ng estado ng isang handler sa pagpapakita at kumuha ng isang timer, na maa-update upang makontrol ang mga nag-time na kaganapan. Pagkatapos, ang makina ng estado ay napasimulan at ipinasok.

void setup () {stateMachine-> setSCI_Display_OCB (displayHandler); stateMachine-> setTimer (timer_sct); stateMachine-> init (); stateMachine-> ipasok (); }Gumagawa ang loop ng tatlong bagay:

  • Taasan ang mga kaganapan sa pag-input
  • Kalkulahin ang lumipas na oras at i-update ang timer
  • Tumawag sa makina ng estado

mahabang kasalukuyang_time = 0; mahaba last_cycle_time = 0; void loop () {pagtaasEvents (); last_cycle_time = kasalukuyang_time; kasalukuyang_time = millis (); timer_sct-> updateActiveTimer (stateMachine, current_time - last_cycle_time); stateMachine-> runCycle (); }

Hakbang 6: Kunin ang Halimbawa

Ayan yun. Marahil, hindi ko nabanggit ang bawat detalye ng pagpapatupad, ngunit maaari kang tumingin sa halimbawa o mag-iwan ng komento.

Idagdag ang halimbawa sa isang tumatakbo na IDE na may: File -> Bago -> Halimbawa -> Mga Halimbawa ng YAKINDU Statechart -> Susunod -> Arduino - Digital Watch (C ++)

> Maaari mong i-download ang IDE dito <<

Maaari kang magsimula sa isang 30 araw na pagsubok. Pagkatapos, kailangan mong makakuha ng isang lisensya, na libre para sa hindi pang-komersyal na paggamit!

Inirerekumendang: