Table des matières:

Montre numérique sur Arduino à l'aide d'une machine à états finis : 6 étapes
Montre numérique sur Arduino à l'aide d'une machine à états finis : 6 étapes

Vidéo: Montre numérique sur Arduino à l'aide d'une machine à états finis : 6 étapes

Vidéo: Montre numérique sur Arduino à l'aide d'une machine à états finis : 6 étapes
Vidéo: Les bases de l'Arduino ! 2024, Novembre
Anonim
Montre numérique sur Arduino à l'aide d'une machine à états finis
Montre numérique sur Arduino à l'aide d'une machine à états finis

Salut, je vais vous montrer comment une montre numérique peut être créée avec YAKINDU Statechart Tools et fonctionner sur un Arduino, qui utilise un écran de clavier LCD.

Le modèle original de la montre numérique a été repris de David Harel. Il a publié un article sur la

"[…] large extension du formalisme conventionnel des machines à états et des diagrammes d'états."

Dans cet article, il a utilisé l'exemple de la montre numérique pour ses recherches. Je l'ai utilisé comme source d'inspiration et reconstruit la montre avec YAKINDU Statechart Tools (un outil pour créer des modèles graphiques de machines à états et générer du code C/C++ avec) et lui ai redonné vie sur un Arduino.

Fournitures

Matériel:

  • Arduino Uno ou Mega
  • Écran de clavier LCD

Logiciel:

  • Outils de diagramme d'états YAKINDU
  • Eclipse C++ IDE pour Arduino

Étape 1: Comment fonctionne la montre numérique

Image
Image

Commençons par définir comment la montre numérique doit fonctionner. Vous souvenez-vous de ces… disons… des montres numériques « ultra cool » que tout le monde avait dans les années 90 ? Un chronomètre intégré, différentes alarmes et son bip agaçant toutes les heures. Si ce n'est pas le cas, jetez un œil: montre numérique des années 90.

Donc, en gros, c'est une montre configurable avec différents modes. Principalement, l'heure actuelle sera affichée, mais il existe d'autres fonctionnalités. En entrée, vous disposez d'un bouton on/off, d'un mode et d'un bouton set. De plus, vous pouvez allumer et éteindre la lumière. Avec le bouton mode, vous pouvez distinguer les modes et activer/désactiver les fonctions de l'horloge:

  • Afficher l'heure (Horloge)
  • Afficher la date (Date)
  • Régler l'alarme (Alarme 1, Alarme 2)
  • Activer/désactiver le carillon (Définir le carillon)
  • Utilisez le chronomètre (Stop Watch)

Dans les menus, vous pouvez utiliser le bouton marche/arrêt pour configurer le mode. Le bouton de réglage vous permet de régler l'heure - par ex. pour l'horloge ou les alarmes. Le chronomètre peut être contrôlé - démarré et arrêté - en utilisant le bouton d'allumage et d'extinction de l'éclairage. Vous pouvez également utiliser un compteur de tours intégré

De plus, il y a un carillon, qui sonne toutes les heures, et un rétro-éclairage contrôlable intégré. À la première étape, je ne les ai pas câblés à l'Arduino.

Étape 2: La machine à états

Écran de clavier LCD
Écran de clavier LCD

Je ne veux pas entrer dans les détails pour l'explication de cet exemple. Ce n'est pas parce que c'est trop complexe, c'est juste un peu trop gros. Je vais essayer d'expliquer l'idée de base de son fonctionnement. L'exécution doit s'expliquer d'elle-même, en regardant le modèle ou en le téléchargeant et en le simulant. Certaines parties de la machine d'état sont résumées dans des sous-régions, comme la région temporelle définie. Avec cela, la lisibilité de la machine d'état doit être assurée.

Le modèle est divisé en deux parties - une graphique et une textuelle. Dans la partie textuelle les événements, variables, etc. seront définis. Dans la partie graphique - le diagramme d'état - l'exécution logique du modèle est spécifiée. Pour créer une machine à états, qui remplit le comportement spécifié, certains événements d'entrée sont nécessaires, qui peuvent être utilisés dans le modèle: onoff, set, mode, light et light_r. Dans la section de définition, un événement interne est utilisé, qui incrémente la valeur temporelle toutes les 100 ms:

toutes les 100 ms / temps += 1

Sur la base des pas de 100 ms, l'heure actuelle sera calculée au format HH:MM:SS:

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

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

Les valeurs seront câblées à l'écran LCD en utilisant l'opération updateLCD à chaque fois que la machine d'état sera appelée:

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

L'exécution de base de la machine d'état est déjà définie dans la section Fonctionnement de la montre numérique. Dans l'outil, j'ai utilisé des éléments de modélisation "spéciaux" tels que CompositeState, History, Sub-Diagrams, ExitNodes, etc. Une description détaillée peut être trouvée dans le Guide de l'utilisateur.

Étape 3: Écran de clavier LCD

Le LCD Keypad Shield est assez cool pour les projets simples, qui nécessitent un écran pour la visualisation et quelques boutons comme entrée - une HMI (interface homme-machine) simple et typique. L'écran LCD Keypad Shield contient cinq boutons utilisateur et un autre pour la réinitialisation. Les cinq boutons tous ensemble sont connectés à la broche A0 de l'Arduino. Chacun d'eux est connecté à un diviseur de tension, ce qui permet de distinguer les boutons.

Vous pouvez utiliser analogRead(0) pour trouver les valeurs spécifiques, qui peuvent bien sûr différer selon le fabricant. Ce projet simple affiche la valeur actuelle sur l'écran 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("Valeur mesurée"); } boucle vide() { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(analogRead(0)); retard (200); }

Voici mes résultats mesurés:

  • Aucun: 1023
  • Sélectionnez: 640
  • Gauche: 411
  • Bas: 257
  • Jusqu'à: 100
  • À droite: 0

Avec ces seuils il est possible de lire les boutons:

#define NONE 0#define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5 static int readButton() { int result = 0; result = analogRead(0); if (résultat < 50) { return RIGHT; } if (résultat < 150) { return UP; } if (résultat < 300) { return DOWN; } if (résultat < 550) { return LEFT; } if (résultat < 850) { return SELECT; } renvoie NONE; }

Étape 4: interfacer la machine d'état

Interfacer la machine d'état
Interfacer la machine d'état

Le code C++ généré de la machine d'état fournit des interfaces, qui doivent être implémentées pour contrôler la machine d'état. La première étape consiste à connecter les événements in avec les touches du Keypad Shield. J'ai déjà montré comment lire les boutons, mais pour les interfacer avec la machine d'état, il est nécessaire de neutraliser les boutons - sinon, les événements seraient déclenchés plusieurs fois, ce qui entraînerait un comportement imprévisible. Le concept de logiciel anti-rebond n'est pas nouveau. Vous pouvez consulter la documentation Arduino.

Dans mon implémentation, je détecte un front descendant (relâchement du bouton). J'ai lu la valeur du bouton, j'ai attendu 80 ms (obtenu de meilleurs résultats avec 80 au lieu de 50), j'ai enregistré le résultat et lu la nouvelle valeur. Si l'ancien résultat n'était pas AUCUN (non enfoncé) et que le nouveau résultat est AUCUN, je sais que le bouton a déjà été enfoncé et qu'il a maintenant été relâché. Ensuite, je déclenche l'événement d'entrée correspondant de la machine d'état.

int oldState = NONE;static void raiseEvents() { int buttonPressed = readButton(); retard (80); oldState = boutonAppuyé; if (oldState != AUCUN && readButton() == AUCUN) { switch (oldState) { case SELECT: { stateMachine->getSCI_Button()->raise_mode(); Pause; } case GAUCHE: { stateMachine->getSCI_Button()->raise_set(); Pause; } case DOWN: { stateMachine->getSCI_Button()->raise_light(); Pause; } case UP: { stateMachine->getSCI_Button()->raise_light_r(); Pause; } case DROITE: { stateMachine->getSCI_Button()->raise_onoff(); Pause; } par défaut: { pause; } } } }

Étape 5: câbler les choses ensemble

Le programme principal utilise trois parties:

  • La machine d'état
  • Une minuterie
  • Un gestionnaire d'affichage (typique lcd.print (…))

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

La machine d'état utilise un gestionnaire d'affichage et dispose d'un temporisateur, qui sera mis à jour pour contrôler les événements temporisés. Ensuite, la machine d'état est initialisée et entrée.

void setup() { stateMachine->setSCI_Display_OCB(displayHandler); stateMachine->setTimer(timer_sct); stateMachine->init(); stateMachine->enter(); }La boucle fait trois choses:

  • Déclencher des événements d'entrée
  • Calculer le temps écoulé et mettre à jour la minuterie
  • Appeler la machine d'état

long current_time = 0; long last_cycle_time = 0; boucle vide() { raiseEvents(); last_cycle_time = current_time; heure_actuelle = millis(); timer_sct->updateActiveTimer(stateMachine, current_time - last_cycle_time); stateMachine->runCycle(); }

Étape 6: Obtenez l'exemple

C'est ça. Probablement, je n'ai pas mentionné tous les détails de la mise en œuvre, mais vous pouvez jeter un œil à l'exemple ou laisser un commentaire.

Ajoutez l'exemple à un IDE en cours d'exécution avec: Fichier -> Nouveau -> Exemple -> Exemples YAKINDU Statechart -> Suivant -> Arduino - Digital Watch (C++)

> Vous pouvez télécharger l'IDE ici <<

Vous pouvez commencer par un essai de 30 jours. Ensuite, vous devez obtenir une licence, qui est gratuite pour une utilisation non commerciale !

Conseillé: