Spisu treści:

Cyfrowy zegarek na Arduino przy użyciu maszyny skończonej: 6 kroków
Cyfrowy zegarek na Arduino przy użyciu maszyny skończonej: 6 kroków

Wideo: Cyfrowy zegarek na Arduino przy użyciu maszyny skończonej: 6 kroków

Wideo: Cyfrowy zegarek na Arduino przy użyciu maszyny skończonej: 6 kroków
Wideo: Programujemy Arduino w C++ 2024, Listopad
Anonim
Cyfrowy zegarek na Arduino przy użyciu maszyny skończonej
Cyfrowy zegarek na Arduino przy użyciu maszyny skończonej

Hej, pokażę ci, jak można stworzyć zegarek cyfrowy za pomocą YAKINDU Statechart Tools i uruchomić na Arduino, który wykorzystuje osłonę klawiatury LCD.

Oryginalny model zegarka cyfrowego został zaczerpnięty od Davida Harela. Opublikował artykuł na temat

„[…] szerokie rozszerzenie konwencjonalnego formalizmu maszyn stanowych i diagramów stanów”.

W tym artykule wykorzystał do swoich badań przykład cyfrowego zegarka. Wykorzystałem go jako inspirację i przebudowałem zegarek za pomocą YAKINDU Statechart Tools (narzędzie do tworzenia graficznych modeli maszyn stanowych i generowania za jego pomocą kodu C/C++) i przywróciłem go do życia na Arduino.

Kieszonkowe dzieci

Sprzęt komputerowy:

  • Arduino Uno lub Mega
  • Osłona klawiatury LCD

Oprogramowanie:

  • Narzędzia wykresów stanu YAKINDU
  • Eclipse C++ IDE dla Arduino

Krok 1: Jak działa zegarek cyfrowy

Image
Image

Zacznijmy od zdefiniowania, jak powinien działać zegarek cyfrowy. Czy pamiętasz te… powiedzmy… „bardzo fajne” cyfrowe zegarki, które wszyscy mieli w latach 90.? Zintegrowany stoper, różne alarmy i denerwujący dźwięk co godzinę. Jeśli nie, spójrz: cyfrowy zegarek z lat 90-tych.

Więc w zasadzie jest to konfigurowalny zegarek z różnymi trybami. Głównie będzie wyświetlany aktualny czas, ale są też inne funkcje. Jako wejście masz przycisk włączania/wyłączania, tryb i przycisk ustawiania. Dodatkowo możesz włączać i wyłączać światło. Za pomocą przycisku trybu możesz rozróżnić tryby i aktywować/dezaktywować funkcje zegara:

  • Wyświetl czas (zegar)
  • Wyświetl datę (Data)
  • Ustaw alarm (Alarm 1, Alarm 2)
  • Włącz/wyłącz dzwonek (Ustaw dzwonek)
  • Użyj stopera (Stop Watch)

W menu możesz użyć przycisku włączania/wyłączania, aby skonfigurować tryb. Przycisk set umożliwia ustawienie godziny – np. na zegar lub alarmy. Stoper można kontrolować - uruchamiać i zatrzymywać - za pomocą przycisku włączania i wyłączania światła. Możesz również użyć zintegrowanego licznika okrążeń

Ponadto jest dzwonek, który dzwoni co pełną godzinę, oraz zintegrowane kontrolowane podświetlenie. W pierwszym kroku nie podłączyłem ich do Arduino.

Krok 2: Maszyna stanowa

Osłona klawiatury LCD
Osłona klawiatury LCD

Nie chcę wchodzić zbyt szczegółowo w wyjaśnienie tego przykładu. Nie dlatego, że jest zbyt złożony, tylko trochę za duży. Postaram się wyjaśnić podstawową ideę, jak to działa. Wykonanie powinno być zrozumiałe, poprzez obejrzenie modelu lub pobranie go i zasymulowanie. Niektóre części automatu stanu są sumowane w podregionach, jak np. ustawiony region czasu. Dzięki temu należy zapewnić czytelność maszyny stanowej.

Model podzielony jest na dwie części - graficzną i tekstową. W części tekstowej zostaną zdefiniowane zdarzenia, zmienne itp. W części graficznej - diagramie stanów - określone jest logiczne wykonanie modelu. Aby stworzyć maszynę stanów spełniającą określone zachowanie, wymagane są pewne zdarzenia wejściowe, które można wykorzystać w modelu: onoff, set, mode, light i light_r. W sekcji definicji używane jest zdarzenie wewnętrzne, które zwiększa wartość czasu co 100 ms:

co 100 ms / czas += 1

Na podstawie kroków 100 ms aktualny czas zostanie obliczony w formacie GG:MM:SS:

wyśw.pierwszy = (czas / 36000) % 24;

sekunda wyśw. = (czas / 600) % 60; wyśw.trzeci = (czas / 10) % 60;

Wartości zostaną podłączone do wyświetlacza LCD za pomocą operacji updateLCD za każdym razem, gdy maszyna stanu zostanie wywołana:

display.updateLCD(wyświetl.pierwszy, wyświetl.drugi, wyświetl.trzeci, wyświetl.tekst)

Podstawowe wykonanie maszyny stanowej zostało już zdefiniowane w rozdziale Jak działa zegarek cyfrowy. W narzędziu użyłem kilku "specjalnych" elementów modelowania, takich jak CompositeState, History, Sub-Diagrams, ExitNodes, itp. Szczegółowy opis można znaleźć w Podręczniku użytkownika.

Krok 3: Osłona klawiatury LCD

LCD Keypad Shield jest całkiem fajny do prostych projektów, które wymagają ekranu do wizualizacji i kilku przycisków jako wejścia - typowy, prosty HMI (Human Machine Interface). Osłona klawiatury LCD zawiera pięć przycisków użytkownika i jeden do resetowania. Pięć przycisków razem jest podłączonych do pinu A0 Arduino. Każdy z nich podłączony jest do dzielnika napięcia, co pozwala na rozróżnienie przycisków.

Możesz użyć analogRead(0), aby znaleźć konkretne wartości, które oczywiście mogą się różnić w zależności od producenta. Ten prosty projekt wyświetla aktualną wartość na wyświetlaczu LCD:

#include "Arduino.h"

#include "LiquidCrystal.h" LiquidCrystal lcd(8, 9, 4, 5, 6, 7); void setup() { lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.write("Wartość zmierzona"); } void loop() { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(analogRead(0)); opóźnienie(200); }

Oto moje zmierzone wyniki:

  • Brak: 1023
  • Wybierz: 640
  • Po lewej: 411
  • Dół: 257
  • W górę: 100
  • Prawo: 0

Przy tych progach możliwy jest odczyt przycisków:

#define NONE 0#define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5 static int readButton() { int wynik = 0; wynik = analogRead(0); if (wynik < 50) { zwróć PRAWO; } if (wynik < 150) { return UP; } if (wynik < 300) { return DOWN; } if (wynik < 550) { return LEFT; } if (wynik < 850) { return SELECT; } zwróć BRAK; }

Krok 4: Podłączanie maszyny stanowej

Podłączanie maszyny stanowej
Podłączanie maszyny stanowej

Wygenerowany kod C++ automatu stanów udostępnia interfejsy, które należy zaimplementować, aby sterować automatem stanów. Pierwszym krokiem jest połączenie zdarzeń in z klawiszami osłony klawiatury. Pokazałem już, jak odczytywać przyciski, ale do połączenia ich z maszyną stanów wymagane jest odbicie przycisków - w przeciwnym razie zdarzenia byłyby wywoływane wielokrotnie, co skutkuje nieprzewidywalnym zachowaniem. Koncepcja debouncingu oprogramowania nie jest nowa. Możesz zajrzeć do dokumentacji Arduino.

W mojej implementacji wykrywam opadającą krawędź (zwolnienie przycisku). Odczytuję wartość przycisku, czekam 80 ms (lepsze wyniki uzyskałem przy 80 zamiast 50), zapisuję wynik i odczytuję nową wartość. Jeśli stary Wynik nie był BRAK (nienaciśnięty), a nowy wynik to BRAK, wiem, że przycisk został naciśnięty wcześniej, a teraz został zwolniony. Następnie podnoszę odpowiednie zdarzenie wejściowe automatu stanu.

int oldState = BRAK;static void raiseEvents() { int buttonPressed = readButton(); opóźnienie(80); stary stan = buttonPressed; if (oldState != BRAK && readButton() == BRAK) { switch (oldState) { case SELECT: { stateMachine->getSCI_Button()->raise_mode(); przerwa; } case PO LEWEJ: { stateMachine->getSCI_Button()->raise_set(); przerwa; } case DOWN: { stateMachine->getSCI_Button()->raise_light(); przerwa; } case UP: { stateMachine->getSCI_Button()->raise_light_r(); przerwa; } case PRAWY: { stateMachine->getSCI_Button()->raise_onoff(); przerwa; } domyślnie: { przerwa; } } } }

Krok 5: Łączenie rzeczy razem

Główny program składa się z trzech części:

  • Maszyna państwowa
  • Zegar
  • Obsługa wyświetlacza (typowy lcd.print(…))

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

Automat stanów używa obsługi wyświetlania i ma zegar, który zostanie zaktualizowany w celu kontrolowania zdarzeń czasowych. Następnie maszyna stanów zostaje zainicjowana i wprowadzona.

void setup() { stateMachine->setSCI_Display_OCB(displayHandler); stateMachine->setTimer(timer_sct); stateMachine->init(); stateMachine->enter(); }Pętla robi trzy rzeczy:

  • Podnieś zdarzenia wejściowe
  • Oblicz czas, który upłynął i zaktualizuj timer
  • Zadzwoń do maszyny stanowej

długi czas_bieżący = 0;długi czas_ostatniego_cyklu = 0; void loop() { raiseEvents(); czas_ostatniego_cyklu = czas_bieżący; aktualny_czas = mili(); timer_sct->updateActiveTimer(stanMachine, aktualny_czas - ostatni_czas_cyklu); stateMachine->runCycle(); }

Krok 6: Zdobądź przykład

Otóż to. Zapewne nie wspominałem o każdym szczególe implementacji, ale możesz rzucić okiem na przykład lub zostawić komentarz.

Dodaj przykład do działającego IDE za pomocą: Plik -> Nowy -> Przykład -> Przykłady wykresów stanu YAKINDU -> Dalej -> Arduino - Cyfrowy zegarek (C++)

> Możesz pobrać IDE tutaj <<

Możesz zacząć od 30-dniowego okresu próbnego. Następnie musisz uzyskać licencję, która jest bezpłatna do użytku niekomercyjnego!

Zalecana: