Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine

Onderdelen en benodigdheden

OnderdeelAantal
Arduino UNO (of Mega, compatibel met LCD Shield)1
LCD Keypad Shield1

Apps en online diensten

Over dit project

Hey! Ik laat je zien hoe je een digitale horloge kunt maken met YAKINDU Statechart Tools en het op een Arduino draait met een LCD Keypad Shield.

Het oorspronkelijke model stam van David Harel, die een paper publiceerde over de „brede uitbreiding van de conventionele formalisme van toestandsmachines en toestandsdiagrammen“. Hij gebruikte de digitale horloge als voorbeeld. Ik heb het nabouwd met YAKINDU (een tool voor grafisch modelleren van toestandsmachines en C/C++-code genereren) en het op de Arduino tot leven gewekt.

Hoe de digitale horloge werkt

Herinner je die „ultra coole” digitale horloges uit de jaren '90? Met stopwatch, alarmen en die irriterende piep elk heel uur. Zo niet, bekijk: 90's digital watch.

Het is een configureerbare horloge met modi. Hoofdscherm toont de tijd. Invoeren via knoppen: on/off, mode, set. Daarnaast een backlight aan/uit.

Met de mode-knop schakel je tussen modi:

  • Tijd weergeven (Clock)
  • Datum weergeven (Date)
  • Alarm instellen (Alarm 1, Alarm 2)
  • Uuursignaal in/uitschakelen (Set Chime)
  • Stopwatch gebruiken (Stop Watch)

In menu's configureer je met on/off. Met set stel je tijden in (klok, alarmen). De stopwatch bedien je met light on/off (start/stop) en heeft een lus-teller.

Er is een uuursignaal (chime) en een instelbare backlight. In deze eerste versie zijn die nog niet aangesloten op de Arduino.

De Toestandsmachine

Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine

Het model is te groot om volledig uit te leggen, maar de uitvoering is zelfverklarend als je het diagram bestudeert of downloadt en simuleert. Delen zijn samengevat in sub-regio's (zoals set time) voor leesbaarheid.

Het model heeft een grafische (staatendiagram) en tekstuele (definities) kant. In de tekstuele definitie worden events, variabelen, etc. gedefinieerd. In het diagram de logica.

Benodigde invoer-events: onoff, set, mode, light, light_r. Een intern event verhoogt de tijd elke 100 ms:

every 100 ms / time += 1

Op basis van 100 ms stappen wordt de tijd berekend in UU:MM:SS:

display.first  = (time / 36000) % 24;   // uren
display.second = (time / 600) % 60;     // minuten
display.third  = (time / 10) % 60;      // seconden

Waarden worden via de operatie updateLCD naar het LCD geschreven bij elke aanroep van de toestandsmachine:

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

De basisuitvoering is al beschreven in „Hoe de digitale horloge werkt”. Het model gebruikt geavanceerde elementen: CompositeState, History, Sub-Diagrams, ExitNodes, etc. Zie de User Guide voor details.

LCD Keypad Shield

De LCD Keypad Shield is ideaal voor simpele projecten met scherm en knoppen – een typische HMI. Hij heeft 5 gebruikersknoppen + 1 reset-knop. Alle 5 knoppen zitten op A0 via een spanningsdeler per knop.

Met analogRead(0) meet je de waarden (kunnen per fabrikant afwijken). Testcode:

#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("Measured Value");
}
void loop() {
  lcd.setCursor(0,1);
  lcd.print(" ");
  lcd.setCursor(0,1);
  lcd.print(analogRead(0));
  delay(200);
}

Mijn gemeten waardes:

  • Geen: 1023
  • Select: 640
  • Left: 411
  • Down: 257
  • Up: 100
  • Right: 0

Bouw een Digitale Horloge op Arduino met een Finitie Toestandsmachine

Met deze drempels lees je de knoppen uit:

#define NONE 0
#define SELECT 1
#define LEFT 2
#define DOWN 3
#define UP 4
#define RIGHT 5

static int readButton() {
  int result = analogRead(0);
  if (result < 50) return RIGHT;
  if (result < 150) return UP;
  if (result < 300) return DOWN;
  if (result < 550) return LEFT;
  if (result < 850) return SELECT;
  return NONE;
}

Interfacing de Toestandsmachine

De gegenereerde C++-code biedt interfaces die geïmplementeerd moeten worden. Stap 1: knoppen koppelen aan events. Debouncing is vereist, anders worden events meerdere keren geactiveerd.

Mijn implementatie detecteert een valflank (loslaten knop). Lees knop, wacht 80 ms (beter dan 50), sla op, lees opnieuw. Als oldResult != NONE en nieuwe waarde NONE is, was de knop ingedrukt en is nu losgelaten → activeer bijbehorend event.

int oldState = NONE;
static void raiseEvents() {
  int buttonPressed = readButton();
  delay(80);
  oldState = buttonPressed;
  if (oldState != NONE && readButton() == NONE) {
    switch (oldState) {
      case SELECT: stateMachine->getSCI_Button()->raise_mode(); break;
      case LEFT:   stateMachine->getSCI_Button()->raise_set(); break;
      case DOWN:   stateMachine->getSCI_Button()->raise_light(); break;
      case UP:     stateMachine->getSCI_Button()->raise_light_r(); break;
      case RIGHT:  stateMachine->getSCI_Button()->raise_onoff(); break;
      default: break;
    }
  }
}

Alles samenvoegen

Hoofdprogramma gebruikt drie delen:

  • De Toestandsmachine
  • Een Timer
  • Een Display Handler (gewone lcd.print(...))
DigitalWatch* stateMachine = new DigitalWatch();
CPPTimerInterface* timer_sct = new CPPTimerInterface();
DisplayHandler* displayHandler = new DisplayHandler();

De toestandsmachine krijgt een display handler en een timer (voor getimede events). Daarna initialiseren en activeren:

void setup() {
  stateMachine->setSCI_Display_OCB(displayHandler);
  stateMachine->setTimer(timer_sct);
  stateMachine->init();
  stateMachine->enter();
}

De loop() doet drie dingen:

  • Events opwekken (raiseEvents())
  • Verstreken tijd berekenen en timer updaten
  • Toestandsmachine cyclus uitvoeren (runCycle())
long current_time = 0;
long last_cycle_time = 0;
void loop() {
  raiseEvents();
  last_cycle_time = current_time;
  current_time = millis();
  timer_sct->updateActiveTimer(stateMachine, current_time - last_cycle_time);
  stateMachine->runCycle();
}

Voorbeeld ophalen

Dat is het. Misschien niet elk detail genoemd, maar je kunt het voorbeeld bekijken of een reactie achterlaten.

Toevoegen aan een draaiende IDE:

File → New → Example → YAKINDU Statechart Examples → Next → Arduino - Digital Watch (C++)

> Download de IDE hier <

Je start met een 30-daagse proefversie. Daarna heb je een licentie nodig, die gratis is voor non-commercieel gebruik!

Productieproces

  1. Bouw een indrukwekkend monitor Ambilight-systeem met Arduino
  2. Arduino Digitale Dobbelsteen: Bouw Je Eigen LCD-willekeurige Getalgenerator
  3. Bouw een Ultrasonische Zweefapparaat met Arduino – Stap-voor-stap Handleiding
  4. Een slimme voltmeter bouwen met Arduino en smartphone – Eenvoudig DIY-project
  5. Real-time IoT hartslagmonitor met Arduino en MAX30100
  6. Arduino Uno WiFi Webserver: LED aan/uit schakelen via browser
  7. Bouw Je Eigen Arduino Tamagotchi: Een Digitale Huisdier DIY Project
  8. DIY Arduino Smartwatch: Bouw Je Eigen Apple Watch-stijl Tijdwijzer
  9. Bouw een geautomatiseerde Google Chrome Dino Game met Arduino
  10. Bouw een compacte FM-radio met Arduino Nano en RDA5807M
  11. Eindige Toestandsmachines Ontwerpen: Van Concept naar Implementatie