Inhaltsverzeichnis:

Digitaluhr auf Arduino mit einer Finite State Machine - Gunook
Digitaluhr auf Arduino mit einer Finite State Machine - Gunook

Video: Digitaluhr auf Arduino mit einer Finite State Machine - Gunook

Video: Digitaluhr auf Arduino mit einer Finite State Machine - Gunook
Video: CS50 2014 - Week 9 2024, November
Anonim
Digitaluhr auf Arduino mit einer Finite State Machine
Digitaluhr auf Arduino mit einer Finite State Machine

Hey, ich zeige Ihnen, wie Sie mit YAKINDU Statechart Tools eine Digitaluhr erstellen und auf einem Arduino ausführen können, der ein LCD-Keypad-Shield verwendet.

Das Originalmodell der Digitaluhr stammt von David Harel. Er hat einen Artikel über die. veröffentlicht

„[…] breite Erweiterung des konventionellen Formalismus von Zustandsautomaten und Zustandsdiagrammen.“

In dieser Arbeit nutzte er das Beispiel der Digitaluhr für seine Forschungen. Ich habe es als Inspiration verwendet und die Uhr mit YAKINDU Statechart Tools (einem Tool zum Erstellen grafischer Modelle von Zustandsautomaten und zum Generieren von C/C++-Code damit) umgebaut und auf einem Arduino wieder zum Leben erweckt.

Lieferungen

Hardware:

  • Arduino Uno oder Mega
  • LCD-Tastaturschild

Software:

  • YAKINDU Statechart-Tools
  • Eclipse C++ IDE für Arduino

Schritt 1: So funktioniert die Digitaluhr

Image
Image

Beginnen wir damit, zu definieren, wie die Digitaluhr funktionieren soll. Erinnern Sie sich an diese… sagen wir… „ultra coole“Digitaluhren, die jeder in den 90ern hatte? Eine integrierte Stoppuhr, verschiedene Alarme und sein nerviger Piepton zu jeder vollen Stunde. Wenn nicht, schau mal: 90er Jahre Digitaluhr.

Im Grunde ist es also eine konfigurierbare Uhr mit verschiedenen Modi. Hauptsächlich wird die aktuelle Uhrzeit angezeigt, aber es gibt noch einige andere Funktionen. Als Eingang stehen ein Ein/Aus, ein Modus und ein Set-Knopf zur Verfügung. Außerdem können Sie das Licht ein- und ausschalten. Mit der Modustaste können Sie zwischen den Modi unterscheiden und die Uhrfunktionen aktivieren/deaktivieren:

  • Uhrzeit anzeigen (Uhr)
  • Datum anzeigen (Datum)
  • Stellen Sie den Alarm ein (Alarm 1, Alarm 2)
  • Gong aktivieren/deaktivieren (Gong einstellen)
  • Verwenden Sie die Stoppuhr (Stoppuhr)

Innerhalb der Menüs können Sie den Modus mit der Ein-/Aus-Taste konfigurieren. Mit der Set-Taste können Sie die Uhrzeit einstellen - z. B. für die Uhr oder den Wecker. Die Stoppuhr kann über den Licht-Ein- und Licht-Aus-Knopf gesteuert - gestartet und gestoppt - werden. Sie können auch einen integrierten Rundenzähler verwenden

Weiterhin ist ein Glockenspiel, das zu jeder vollen Stunde läutet, und eine steuerbare Hintergrundbeleuchtung integriert. Im ersten Schritt habe ich sie nicht mit dem Arduino verbunden.

Schritt 2: Die Zustandsmaschine

LCD-Tastaturschild
LCD-Tastaturschild

Ich möchte nicht zu sehr ins Detail gehen, um dieses Beispiel zu erklären. Es liegt nicht daran, dass es zu komplex ist, es ist nur ein bisschen zu groß. Ich werde versuchen, die Grundidee zu erklären, wie es funktioniert. Die Ausführung sollte selbsterklärend sein, indem Sie sich das Modell ansehen oder herunterladen und simulieren. Einige Teile des Zustandsautomaten werden in Unterregionen zusammengefasst, wie z. B. die eingestellte Zeitregion. Damit soll die Lesbarkeit des Zustandsautomaten sichergestellt werden.

Das Modell gliedert sich in zwei Teile - einen grafischen und einen textuellen. Im Textteil werden die Ereignisse, Variablen usw. definiert. Im grafischen Teil – dem Zustandsdiagramm – wird die logische Ausführung des Modells spezifiziert. Um eine Zustandsmaschine zu erstellen, die das angegebene Verhalten erfüllt, sind einige Eingabeereignisse erforderlich, die im Modell verwendet werden können: onoff, set, mode, light und light_r. Im Definitionsbereich wird ein internes Ereignis verwendet, das den Zeitwert alle 100 ms inkrementiert:

alle 100 ms / Zeit += 1

Aus den 100 ms Schritten wird die aktuelle Zeit im Format HH:MM:SS berechnet:

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

Anzeige. Sekunde = (Zeit / 600) % 60; Anzeige.dritte = (Zeit / 10) % 60;

Die Werte werden mit der Operation updateLCD bei jedem Aufruf der Zustandsmaschine mit dem LCD-Display verdrahtet:

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

Die grundsätzliche Ausführung der Zustandsmaschine ist bereits im Abschnitt Funktionsweise der Digitaluhr definiert. Innerhalb des Tools habe ich einige "spezielle" Modellierungselemente wie CompositeState, History, Sub-Diagrams, ExitNodes usw. verwendet. Eine detaillierte Beschreibung finden Sie im Benutzerhandbuch.

Schritt 3: LCD-Tastaturschild

Das LCD Keypad Shield ist ziemlich cool für einfache Projekte, die einen Bildschirm zur Visualisierung und einige Tasten als Eingabe benötigen - ein typisches, einfaches HMI (Human Machine Interface). Das LCD-Tastaturschild enthält fünf Benutzertasten und eine weitere zum Zurücksetzen. Die fünf Tasten sind alle zusammen mit dem A0-Pin des Arduino verbunden. Jeder von ihnen ist mit einem Spannungsteiler verbunden, der eine Unterscheidung der Tasten ermöglicht.

Mit analogRead(0) können Sie die spezifischen Werte ermitteln, die natürlich je nach Hersteller abweichen können. Dieses einfache Projekt zeigt den aktuellen Wert auf dem LCD an:

#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("Messwert"); aufrechtzuerhalten. Void Schleife () {lcd.setCursor (0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print (analogRead (0)); Verzögerung (200); }

Das sind meine Messergebnisse:

  • Keine: 1023
  • Wählen Sie: 640
  • Links: 411
  • Unten: 257
  • Oben: 100
  • Rechts: 0

Mit diesen Schwellenwerten ist es möglich, die Schaltflächen zu lesen:

#define NONE 0#define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5 static int readButton() { int result = 0; Ergebnis = analogRead(0); if (Ergebnis < 50) { return RECHTS; } if (Ergebnis < 150) { Return UP; } if (Ergebnis < 300) { Return DOWN; } if (Ergebnis < 550) { return LINKS; } if (Ergebnis < 850) { Return SELECT; } return KEINE; }

Schritt 4: Anbindung der Zustandsmaschine

Anbindung der Zustandsmaschine
Anbindung der Zustandsmaschine

Der generierte C++-Code der Zustandsmaschine stellt Schnittstellen bereit, die zur Steuerung der Zustandsmaschine implementiert werden müssen. Der erste Schritt besteht darin, die In-Ereignisse mit den Tasten des Keypad Shield zu verbinden. Ich habe bereits gezeigt, wie die Schaltflächen gelesen werden, aber um sie mit der Zustandsmaschine zu verbinden, ist eine Entprellung der Schaltflächen erforderlich - sonst würden die Ereignisse mehrmals ausgelöst, was zu unvorhersehbarem Verhalten führt. Das Konzept der Software-Entprellung ist nicht neu. Sie können sich die Arduino-Dokumentation ansehen.

In meiner Implementierung erkenne ich eine fallende Flanke (das Loslassen der Schaltfläche). Ich lese den Wert des Buttons, warte 80 ms (bekomme mit 80 bessere Ergebnisse als 50), speichere das Ergebnis und lese den neuen Wert aus. Wenn das alte Ergebnis nicht NONE (nicht gedrückt) war und das neue Ergebnis NONE ist, weiß ich, dass die Taste zuvor gedrückt und jetzt losgelassen wurde. Dann löse ich das entsprechende Eingabeereignis der Zustandsmaschine aus.

int oldState = NONE;static void raiseEvents() { int buttonPressed = readButton(); Verzögerung (80); oldState = buttonPressed; if (oldState != NONE && readButton() == NONE) { switch (oldState) { case SELECT: { stateMachine->getSCI_Button()->raise_mode(); brechen; } case LINKS: { stateMachine->getSCI_Button()->raise_set(); brechen; } case DOWN: { stateMachine->getSCI_Button()->raise_light(); brechen; } case UP: { stateMachine->getSCI_Button()->raise_light_r(); brechen; } case RECHTS: { stateMachine->getSCI_Button()->raise_onoff(); brechen; } Standard: { Pause; } } } }

Schritt 5: Dinge zusammen verdrahten

Das Hauptprogramm verwendet drei Teile:

  • Die Zustandsmaschine
  • Ein Timer
  • Ein Display-Handler (typisch lcd.print(…))

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

Die Zustandsmaschine verwendet einen Display-Handler und hat einen Timer, der aktualisiert wird, um die zeitgesteuerten Ereignisse zu steuern. Danach wird die Zustandsmaschine initialisiert und betreten.

Void setup () { stateMachine-> setSCI_Display_OCB (displayHandler); stateMachine->setTimer(timer_sct); stateMachine->init(); stateMachine->enter(); }Die Schleife macht drei Dinge:

  • Eingabeereignisse erhöhen
  • Berechnen Sie die verstrichene Zeit und aktualisieren Sie den Timer
  • Rufen Sie die Zustandsmaschine auf

lange aktuelle_Zeit = 0; lange letzte_Zyklus_Zeit = 0; Void Schleife () { raiseEvents (); last_cycle_time = aktuelle_time; aktuelle_zeit = millis(); timer_sct->updateActiveTimer(stateMachine, current_time - last_cycle_time); stateMachine->runCycle(); }

Schritt 6: Holen Sie sich das Beispiel

Das ist es. Wahrscheinlich habe ich nicht jedes Detail der Implementierung erwähnt, aber Sie können sich das Beispiel ansehen oder einen Kommentar hinterlassen.

Fügen Sie das Beispiel zu einer laufenden IDE hinzu mit: Datei -> Neu -> Beispiel -> YAKINDU Statechart Beispiele -> Weiter -> Arduino - Digital Watch (C++)

> Die IDE können Sie hier herunterladen <<

Sie können mit einer 30-tägigen Testversion beginnen. Danach müssen Sie eine Lizenz erwerben, die für die nicht-kommerzielle Nutzung kostenlos ist!

Empfohlen: