Sommario:

Orologio digitale su Arduino utilizzando una macchina a stati finiti: 6 passaggi
Orologio digitale su Arduino utilizzando una macchina a stati finiti: 6 passaggi

Video: Orologio digitale su Arduino utilizzando una macchina a stati finiti: 6 passaggi

Video: Orologio digitale su Arduino utilizzando una macchina a stati finiti: 6 passaggi
Video: Creare una macchina a stati con Arduino - parte 2 - #208 2024, Dicembre
Anonim
Orologio digitale su Arduino utilizzando una macchina a stati finiti
Orologio digitale su Arduino utilizzando una macchina a stati finiti

Ehi, ti mostrerò come creare un orologio digitale con YAkinDU Statechart Tools ed eseguirlo su un Arduino, che utilizza uno schermo LCD per tastiera.

Il modello originale dell'orologio digitale è stato preso da David Harel. Ha pubblicato un articolo sul

"[…] ampia estensione del formalismo convenzionale delle macchine a stati e dei diagrammi di stato."

In questo articolo, ha usato l'esempio dell'orologio digitale per la sua ricerca. L'ho usato come ispirazione e ho ricostruito l'orologio con YAKINDU Statechart Tools (uno strumento per creare modelli grafici di macchine a stati e generare codice C/C++ con esso) e l'ho riportato in vita su un Arduino.

Forniture

Hardware:

  • Arduino Uno o Mega
  • Schermo tastiera LCD

Software:

  • Strumenti per diagrammi di stato YAKINDU
  • Eclipse C++ IDE per Arduino

Passaggio 1: come funziona l'orologio digitale

Image
Image

Iniziamo definendo come dovrebbe funzionare l'orologio digitale. Ricordi questi… diciamo… orologi digitali "ultra cool" che tutti avevano negli anni '90? Un cronometro integrato, diversi allarmi e il suo fastidioso segnale acustico ogni ora intera. In caso contrario, dai un'occhiata: orologio digitale anni '90.

Quindi fondamentalmente è un orologio configurabile con diverse modalità. Principalmente, verrà visualizzata l'ora corrente, ma ci sono alcune altre funzionalità. Come input, hai un pulsante di accensione/spegnimento, una modalità e un pulsante di impostazione. Inoltre, puoi accendere e spegnere la luce. Con il pulsante modalità è possibile distinguere tra le modalità e attivare/disattivare le funzioni dell'orologio:

  • Visualizza l'ora (Orologio)
  • Visualizza la data (Data)
  • Imposta la sveglia (Sveglia 1, Sveglia 2)
  • Abilita/disabilita il suono (Imposta il suono)
  • Usa il cronometro (Cronometro)

All'interno dei menu, è possibile utilizzare il pulsante on/off per configurare la modalità. Il pulsante di impostazione consente di impostare l'ora, ad es. per l'orologio o le sveglie. Il cronometro può essere controllato - avviato e arrestato - utilizzando il pulsante di accensione e spegnimento della luce. Puoi anche utilizzare un contagiri integrato

Inoltre, c'è un campanello, che suona ogni ora intera, e una retroilluminazione controllabile integrata. Al primo passaggio, non li ho collegati ad Arduino.

Passaggio 2: la macchina a stati

Schermo tastiera LCD
Schermo tastiera LCD

Non voglio andare troppo nel dettaglio per la spiegazione di questo esempio. Non è perché è troppo complesso, è solo un po' troppo grande. Cercherò di spiegare l'idea di base di come funziona. L'esecuzione dovrebbe essere autoesplicativa, dando un'occhiata al modello o scaricandolo e simulandolo. Alcune parti della macchina a stati sono riassunte in sottoregioni, come la regione temporale impostata. Con ciò, dovrebbe essere garantita la leggibilità della macchina a stati.

Il modello è suddiviso in due parti: una grafica e una testuale. Nella parte testuale verranno definiti gli eventi, le variabili, ecc. Nella parte grafica - il diagramma di stato - è specificata l'esecuzione logica del modello. Per creare una macchina a stati, che soddisfi il comportamento specificato, sono necessari alcuni eventi di input, che possono essere utilizzati nel modello: onoff, set, mode, light e light_r. All'interno della sezione di definizione viene utilizzato un evento interno, che incrementa il valore del tempo ogni 100 ms:

ogni 100 ms / tempo += 1

Sulla base dei passi di 100 ms l'ora corrente sarà calcolata nel formato HH:MM:SS:

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

display.second = (tempo / 600) % 60; display.terzo = (tempo / 10) % 60;

I valori verranno cablati al display LCD utilizzando l'operazione updateLCD ogni volta che verrà chiamata la macchina a stati:

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

L'esecuzione di base della macchina a stati è già definita nella sezione Come funziona l'orologio digitale. All'interno dello strumento ho utilizzato alcuni elementi di modellazione "speciali" come CompositeState, History, Sub-Diagrams, ExitNodes, ecc. Una descrizione dettagliata può essere trovata nella Guida per l'utente.

Passaggio 3: schermo tastiera LCD

LCD Keypad Shield è abbastanza interessante per progetti semplici, che richiedono uno schermo per la visualizzazione e alcuni pulsanti come input: una tipica e semplice HMI (Human Machine Interface). Lo schermo della tastiera LCD contiene cinque pulsanti utente e un altro per il ripristino. I cinque pulsanti tutti insieme sono collegati al pin A0 di Arduino. Ciascuno di essi è collegato a un partitore di tensione, che consente di distinguere i pulsanti.

Puoi usare analogRead(0) per trovare i valori specifici, che possono, ovviamente, differire dal produttore. Questo semplice progetto mostra il valore corrente sul display 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("Valore misurato"); } void loop() { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(analogRead(0)); ritardo(200); }

Questi sono i miei risultati misurati:

  • Nessuno: 1023
  • Seleziona: 640
  • Sinistra: 411
  • Giù: 257
  • Su: 100
  • Destra: 0

Con queste soglie è possibile leggere i pulsanti:

#define NONE 0#define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5 static int readButton() { int result = 0; risultato = analogRead(0); if (risultato < 50) { return DESTRA; } if (risultato < 150) { return UP; } if (risultato < 300) { return GI; } if (risultato < 550) { return SINISTRA; } if (risultato < 850) { return SELECT; } restituisce NESSUNO; }

Passaggio 4: interfacciare la macchina a stati

Interfacciamento con la macchina a stati
Interfacciamento con la macchina a stati

Il codice C++ generato della macchina a stati fornisce interfacce, che devono essere implementate per controllare la macchina a stati. Il primo passo è connettere gli eventi in con i tasti del Keypad Shield. Ho già mostrato come leggere i pulsanti, ma per interfacciarli alla macchina a stati è necessario eseguire il debouncing dei pulsanti, altrimenti gli eventi verrebbero generati più volte, il che si traduce in un comportamento imprevedibile. Il concetto di software antirimbalzo non è nuovo. Puoi dare un'occhiata alla documentazione di Arduino.

Nella mia implementazione, rilevo un fronte di discesa (rilasciando il pulsante). Leggo il valore del pulsante, attendo 80 ms (ottengo risultati migliori con 80 anziché 50), salvo il risultato e leggo il nuovo valore. Se il oldResult non era NONE (non premuto) e il nuovo risultato è NONE, so che il pulsante è stato premuto prima e ora è stato rilasciato. Quindi, sollevo il secondo evento di input della macchina a stati.

int oldState = NONE;static void raiseEvents() { int buttonPressed = readButton(); ritardo(80); oldState = buttonPressed; if (oldState != NONE && readButton() == NONE) { switch (oldState) { case SELECT: { stateMachine->getSCI_Button()->raise_mode(); rottura; } case SINISTRA: { stateMachine->getSCI_Button()->raise_set(); rottura; } case DOWN: { stateMachine->getSCI_Button()->raise_light(); rottura; } case UP: { stateMachine->getSCI_Button()->raise_light_r(); rottura; } case DESTRA: { stateMachine->getSCI_Button()->raise_onoff(); rottura; } predefinito: { pausa; } } } }

Passaggio 5: cablaggio delle cose insieme

Il programma principale utilizza tre parti:

  • La macchina dello stato
  • un timer
  • Un Display Handler (tipico lcd.print(…))

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

La macchina a stati utilizza un gestore di visualizzazione e ha un timer, che verrà aggiornato per controllare gli eventi a tempo. Successivamente, la macchina a stati viene inizializzata e inserita.

void setup() { stateMachine->setSCI_Display_OCB(displayHandler); stateMachine->setTimer(timer_sct); stateMachine->init(); stateMachine->enter(); }Il ciclo fa tre cose:

  • Aumenta gli eventi di input
  • Calcola il tempo trascorso e aggiorna il timer
  • Chiama la macchina dello stato

long current_time = 0;long last_cycle_time = 0; void loop() { raiseEvents(); last_cycle_time = current_time; ora_corrente = millis(); timer_sct->updateActiveTimer(stateMachine, current_time - last_cycle_time); stateMachine->runCycle(); }

Passaggio 6: ottenere l'esempio

Questo è tutto. Probabilmente, non ho menzionato ogni dettaglio dell'implementazione, ma puoi dare un'occhiata all'esempio o lasciare un commento.

Aggiungi l'esempio a un IDE in esecuzione con: File -> Nuovo -> Esempio -> Esempi di diagrammi di stato YAKINDU -> Avanti -> Arduino - Digital Watch (C++)

> Puoi scaricare l'IDE qui <<

Puoi iniziare con una prova di 30 giorni. Successivamente, devi ottenere una licenza, che è gratuita per uso non commerciale!

Consigliato: