Machine à états finis sur un Arduino (6 / 7 étapes)

Étape 6: Mettre votre système dans le monde réel

sc_timer_service.h

Bon, nous avons cliqué autour, utilisé un éditeur graphique (normalement associé à low-level-langues), Let's get cette chose à la vie. Tout d’abord, nous avons besoin d’un générateur de code qui transforme notre statechart en Code C. C’est étonnamment simple, bien qu’il peut se présenter comme la magie noire dans un premier temps.

Faites un clic droit sur le dossier de votre modèle et sélectionnez Nouveau -> modèle de générateur de Code. Cliquez sur vous-même par le biais de l’Assistant et fixer le générateur de code pour les transitions que vous avez fait avant. ATTENTION : Dans cette même fenêtre, il est un sélecteur en haut qui est facilement assurée. Il permet de sélectionner le générateur de Code C au lieu de la Java et cliquez sur terminer après que vous avez activé la case à cocher à côté de vos transitions. Normalement, le générateur devrait maintenant fonctionner directement et automatiquement tout le temps. Vérifier si les deux dossiers ont été créés, CBC et src-gen. Si ce n’est pas le cas, allez au projet dans le menu principal et vérifiez si Build est automatiquement activé. Le faire si elle n’est pas et faites un clic droit de votre projet et choisissez Build Project. Une barre de progression doit apparaître ainsi que les deux dossiers mentionnés. Lorsque vous avez apporté des modifications, vous pouvez également cliquer droit sur le fichier générateur et sélectionnez Générer Code artefacts.

Le contenu de la dossier src-gen est assez intéressant. Le fichier LightCtrl.c contient la mise en œuvre de la statechart. Lorsque vous Inspectez il, vous trouverez une fonction LightCtrlIface_raise_button (LightCtrl * poignée). Vous pouvez appeler cette fonction pour déclencher l’événement du bouton que nous a déclaré plus tôt – par exemple, lorsque vous vérifiez la tige du bouton de votre matériel et voir qu'il y a un haut niveau. Il y a le fichier LightCtrlRequired.h, où vous devez jeter un coup d’oeil. Elle déclare en fonctions, que vous devez implémenter. Pour cette d’états transitions, il n’y a que deux fonctions : lightCtrl_setTimer et lightCtrl_unsetTimer. Nous avons besoin de ces fonctions car notre statechart utilise la construction après 5 s. Il s’agit d’une fonction très pratique, mais notre générateur de code statechart ne fournit-il pas un service de synchronisation, parce que c’est hautement dépendant de plate-forme – votre ordinateur peut gérer des minuteries différemment de l’Arduino minuscule et minuterie manipulation sur Mac & Linux fonctionne différemment que sur Windows.

Heureusement, je vais vous donner un service de synchronisation, donc vous n’avez pas besoin de mettre en œuvre vos propres. Dans votre projet, créez un nouveau dossier, appelons-le scutils pour statechart utilités. Vous pouvez le nommer tout ce que vous voulez, ou choisissez de ne pas créer ce dossier, c’est juste une question d’organisation. Nous allons créer deux fichiers là-dedans, sc_timer_service.c et sc_timer_service.h. Copie la

Code de GitHub là-dedans (vous pouvez également télécharger le projet complet de GitHub ici) :

sc_timer_service.h

sc_timer_service.c

Maintenant, nous pouvons commencer à travailler sur le code de l’Arduino dans le fichier *.ino généré de l’Assistant.

En outre Arduino.h, également inclure avr/sleep.het bien sûr notre machine de l’État et le service du minuteur : LightCtrl.h, LightCtrlRequired.h et sc_timer_service.h. Maintenant, les trucs de Arduino régulier sont nécessaire : nous définissons les broches de la LED et le bouton et ces mis en place à l’intérieur de la fonction de paramétrage (c’est ce qu’il a été fait). Puis, nous devons définir les fonctions du statechart attend de nous de définir - lightCtrl_setTimer et lightCtrl_unsetTimer, comme expliqué précédemment. Ici, nous venons d’utiliser le service du minuteur, et nous avons fini. Maintenant, nous devrions épargner une pensée sur la façon dont nous voulons en fait activer la LED quand nous atteignons l’état Allumé. Fondamentalement, nous avons trois options :

  1. Nous pouvons vérifier si la statemachine est dans l’état de lumière et activer / désactiver la LED basée sur cette information
  2. Nous pouvons aller à notre statechart et définir une variable lorsque nous atteindrons les États, que nous pouvons interroger
  3. Nous pourrions ajouter une opération qui gère la lumière qui est appelée par les transitions sur une transition.

La première solution est vraiment mauvaise. Nous aurions logique concernant les transitions en dehors de celui-ci. Si nous voudrais renommer nos États, elle cesserait de fonctionner correctement ; mais ces noms sont censés être prosaïques et pas logique associés. À l’aide de variables est correct, surtout si vous travaillez avec des applications de bureau. Nous pouvions synchroniser avec eux toutes les millisecondes x ou presque. Ici, nous voulons utiliser une opération. Ajouter ce qui suit à la déclaration d’interface de la statechart :

 operation setLight(LightOn: boolean): void 

Il déclare une fonction qui accepte une valeur booléenne comme argument et ne renvoie rien (void). Cela ne devrait pas être nouveau pour vous, seule la syntaxe ici est différente. N’oubliez pas – les diagrammes ne sont pas liés à une langue particulière, la syntaxe est générique. Cette fonction s’affiche automatiquement dans LightCtrlRequired.h . Si il n’est pas le cas, enregistrez votre statechart, faites un clic droit sur votre projet et générez-le.

La fonction déclarée ici ressemble à ceci :

 extern void lightCtrlIface_setLight(const LightCtrl* handle, const sc_boolean lightOn); 

La poignée de paramètre d’entrée est du type LightCtrl, il est le référent pour les transitions. Si vous n’êtes pas qu’expérimenté dans C: l’étoile désigne un pointeur de ce qu’on appelle, si la variable contient l’adresse de la variable d’états transitions. Cela nous aide car nous peut fonctionner sur l’objet d’origine et que vous n’avez pas à créer une copie de celui-ci. Donc, nous allons mettre en œuvre cette fonction :

 void lightCtrlIface_setLight(const LightCtrl* handle, const sc_boolean lightOn) { if(lightOn) digitalWrite(LED_PIN, HIGH); else digitalWrite(LED_PIN, LOW); } 

Comme vous pouvez le voir, cette fonction est sanglant simple-nous n’utilisons pas même la poignée pour les transitions, nous seulement écrire un sommet sur la broche LED si l’argument de l’opération est true et faible autrement.

Nous changeons la statechart lui-même afin qu’il ressemble à la première photo.

N’oubliez pas l’étape 1 ? Gauche de la barre oblique est l’apport nécessaire pour la transition, droite est la sortie de la machine d’État si cette transition n’est prise. Le résultat ici est d’appeler l’opération spécifiée avec ces arguments.

 #include "Arduino.h"#include "avr/sleep.h" #include "src-gen/LightCtrl.h" #include "src-gen/LightCtrlRequired.h" #include "scutil/sc_timer_service.h"#define BUTTON_PIN 3 #define LED_PIN 6 #define MAX_TIMERS 20 //number of timers our timer service can use #define CYCLE_PERIOD 10 //number of milliseconds that pass between each statechart cyclestatic unsigned long cycle_count = 0L; //number of passed cycles static unsigned long last_cycle_time = 0L; //timestamp of last cycle static LightCtrl lightctrl; static sc_timer_service_t timer_service; static sc_timer_t timers[MAX_TIMERS];//! callback implementation for the setting up time events void lightCtrl_setTimer(LightCtrl* handle, const sc_eventid evid, const sc_integer time_ms, const sc_boolean periodic){ sc_timer_start(&timer_service, (void*) handle, evid, time_ms, periodic); }//! callback implementation for canceling time events. void lightCtrl_unsetTimer(LightCtrl* handle, const sc_eventid evid) { sc_timer_cancel(&timer_service, evid); }void lightCtrlIface_setLight(const LightCtrl* handle, const sc_boolean lightOn) { if(lightOn) digitalWrite(LED_PIN, HIGH); else digitalWrite(LED_PIN, LOW); }//The setup function is called once at startup of the sketch void setup() { pinMode(BUTTON_PIN, INPUT); pinMode(LED_PIN, OUTPUT); sc_timer_service_init( &timer_service, timers, MAX_TIMERS, (sc_raise_time_event_fp) &lightCtrl_raiseTimeEvent ); lightCtrl_init(&lightctrl); //initialize statechart lightCtrl_enter(&lightctrl); //enter the statechart }// The loop function is called in an endless loop void loop() { unsigned long current_millies = millis(); if(digitalRead(BUTTON_PIN)) lightCtrlIface_raise_button(&lightctrl); if ( cycle_count == 0L || (current_millies >= last_cycle_time + CYCLE_PERIOD) ) { sc_timer_service_proceed(&timer_service, current_millies - last_cycle_time); lightCtrl_runCycle(&lightctrl); last_cycle_time = current_millies; cycle_count++; } } 

Aussi, consultez le code dans cet essentiel avec les numéros de ligne.

  • Lignes 1-6 contiennent comprend comme discuté plus tôt.
  • Lignes 8 et 9 définissent pins matériel que nous voulons utiliser pour notre arduino.
  • Lignes 11 et 12 définissent minuteries combien notre statechart peut utiliser, et combien de millisecondes doivent passer entre chaque cycle de calcul de la statechart.
  • Lignes 15 et 16 déclarent des variables que nous pouvons utiliser pour compter les cycles et de gérer le temps du dernier cycle.
  • Lignes 17, 19 et 21 déclarent des variables importantes pour l’utilisation de la d’états transitions : le statechart lui-même, le service du minuteur et un tableau de minuteries.
  • Lignes 24 et 33 définissent les fonctions requises par les transitions pour la minuterie, et la ligne 33 est la fonction pour définir la LED que nous avons discuté plus tôt.
  • En ligne 41, void setup() est une fonction standard de l’Arduino. Elle est appelée une fois au démarrage. Nous l’utilisons pour initialiser stuff-nos goupilles LED et bouton obtenir leur direction configurée (entrée est standard, nous faisons cela pour plus de clarté), le service du minuteur est initialisé, le statechart est initialisé et est entré. Entrer dans moyens pour démarrer l’ordinateur d’État, alors le premier État est activé – voilà les points d’entrée État à l’État. Ainsi, au démarrage, le voyant est éteint.
  • En ligne 59, suit la fonction de boucle, qui s’appelle tout le temps de l’Arduino.
  • En ligne 61, nous capturons l’heure actuelle avec la fonction millis(), qui est définie par la bibliothèque de l’Arduino.
  • Ligne 63, nous vérifier si notre touche et déclenche l’événement du bouton si c’est.
  • En ligne 66, nous vérifions si plus de millisecondes CYCLE_PERIOD écoulés depuis que nous avons pédalé dernière notre statechart.
  • Cela prend une charge de notre arduino et signifie que nous pouvons utiliser de manière fiable jusqu'à 10 millisecondes pour nos propres fonctions.
  • En ligne 68, nous dire le service du minuteur de combien de temps s’est écoulé depuis le dernier appel, dites-le statechart d’executer un programme en ligne 70, enregistrer le temps courant en ligne 72 et incrémenter le compteur de cycle en ligne 73.

En utilisant le plugin de l’arduino, vous pouvez maintenant brancher l’arduino avec la LED et le bouton connecté à votre ordinateur et utilisez le bouton dans la barre d’outils en haut de la page pour télécharger le programme sur votre arduino.

Le circuit est indiqué dans les photos 2 et 3.

La LED est reliée à un axe numérique (6) avec une résistance de rond-point 200 Ohms. La cathode est attachée au GND.

Boutons poussoirs ont quatre épingles, veuillez vérifier lequel de ces sont toujours connectés et qui sont connectés lorsque vous appuyez sur le bouton. Puis, vous fixez la broche numérique (3 est utilisé ici) d’un côté et une résistance de menu déroulant à GND. Cela arrête la broche « flottant », un État indéfini et continue sur 0 volt. Lorsque le bouton est enfoncé et l’autre côté est attachée à VCC, que côté est « plus forte » parce qu’il a sans résistance et la tension va jusqu'à 5 Volts – essentiellement un diviseur de tension où une résistance est 0 Ohms. S’il vous plaît utiliser une résistance assez élevée ici, car il limite le courant passant par le bouton. 1 kR est le minimum.

Comme vous pouvez le voir, logique de ce programme est totalement indépendant de la taille réelle de notre statechart. Il n’importe pas si notre statechart a 2 ou 20 États – bien sûr, si nous voulons faire quelque chose, nous devons implémenter une fonction ici et là. Mais le code principal à l’intérieur de void loop() toujours reste assez petit et permet une architecture modulaire de programme. Il suffit de prendre en charge les interfaces de la transitions vers un matériel de notre Arduino à l’intérieur de notre code, le statechart auto-généré gère sa logique interne. Rappelez-vous comment nous avons discuté pour réinitialiser le minuteur lorsque le bouton est enfoncé à nouveau ? Vous pouvez maintenant ajouter une transition de la lumière sur l’État à lui-même avec « bouton » comme événement de garde, et vous devrez pas changer ou ajouter une seule ligne dans votre code. L’essayer !

Articles Liés

Machine à états finis Arduino et multitâches

Machine à états finis Arduino et multitâches

Une machine à états finis est diagramme utilisé pour organiser les tâches pour contrôler plusieurs systèmes insdustrial (production, radiateur, pompe, convoyeurs...).Tous ces systèmes comprennent des États (associé à une « action », c'est à dire: Dém
Bateau pilote automatique - basée sur l’Arduino

Bateau pilote automatique - basée sur l’Arduino

Voici comment construire un pilote automatique qui peut diriger un RC bateau à waypoints ! Il est facile à construire, basé sur la populaire plate-forme Arduino et idéal pour les amateurs qui veulent certaine pratique soudure ! Avec ce pilote automat
Calculatrice simple basée sur l’Arduino MEGA

Calculatrice simple basée sur l’Arduino MEGA

De nos jours, faire des calculs n'est pas un problème du tout. Calculatrices puissants peuvent être achetés pour quelques euros ou faciles à installer sur les téléphones et les ordinateurs. Cependant, nous avons décidé de transformer notre Arduino en
Tachymètre optique axée sur l’Arduino

Tachymètre optique axée sur l’Arduino

plus de dix ans, j'ai mis en place une page web avec des instructions détaillées sur la construction d'un moteur électrique simple basé sur l'un de monde télévisé de le Beakman. Je l'ai appelé la page "moteur électrique de Beakman" et au fil des
Suivre votre voiture avec un Lojack axée sur l’Arduino

Suivre votre voiture avec un Lojack axée sur l’Arduino

Vol de voiture est un frein réel ! Augmentez vos chances de récupérer votre voiture en installant ce tracker simple axée sur l'Arduino dans votre voiture.Ce projet est assez simple et serait un bon projet pour un nouveau programmeur Arduino vous cher
Présentation Climaduino - Thermostat axée sur l’Arduino vous contrôler depuis votre téléphone !

Présentation Climaduino - Thermostat axée sur l’Arduino vous contrôler depuis votre téléphone !

Mise à jour :Il y a une nouvelle version de la Climaduino et le contrôleur Climaduino avec des changements très importants.Prend en charge plusieurs zonesUtilise la Arduino YúnFonctionne avec a/c centraleCommunique à l'aide du protocole MQTT (peut in
Animation sur un Arduino et K.K. Bossa chanson

Animation sur un Arduino et K.K. Bossa chanson

Que fait-elle ?Joue la chanson K.K. Bossa de Animal Crossing et une animation à l'aide d'un Arduino Uno, un piezo et un 16 X 2 LCD.L'animation est basée sur des Animal Crossing New Leaf.Le top vidéo est avec les villageois masculins et bas vidéo avec
Chronométrage sur ESP8266 & arduino uno sans un RTC (Real Time CLock) ?

Chronométrage sur ESP8266 & arduino uno sans un RTC (Real Time CLock) ?

Comme le titre l'indique, j'ai testé le suivi des temps sur mon arduino uno et l'ESP8266 / conseils Wemos D1 (programmés avec arduino) sans l'utilisation de bibliothèques, internet ou une unité de CCF. Beaucoup de grands instructables ici sur le site
Vous vérifier l’état de wifi avec Arduino Yun

Vous vérifier l’état de wifi avec Arduino Yun

Dans ce tutoriel, vous apprendrez comment obtenir votre Arduino Yun vers le haut et en cours d'exécution afin que vous puissiez exécuter des croquis d'exemple pour le Yun. Dans ce cas, je vais vous montrer comment faire pour exécuter l'exemple WiFiSt
CONDUIT comme lightsensor sur l’arduino

CONDUIT comme lightsensor sur l’arduino

je vous écris cette instructable comme une réponse à certaines des questions de Paolo.[J'ai fait quelques expériences plus sur ce sujet dans ce : Ible]Il n'est pas difficile à utiliser une une LED comme un capteur sur l'Arduino. Il suffit de mettre u
Utilisez vos capteurs de Téléphone android sur l’arduino !

Utilisez vos capteurs de Téléphone android sur l’arduino !

Bonjour, ceci est mon tout premier étape par étape instructable et aujourd'hui, nous allons apprendre comment les capteurs dans votre smartphone android peuvent communiquer avec votre arduino.Dans les smartphones modernes, il y a beaucoup de capteurs
Verre les ordinateurs basés sur l’Arduino Uno

Verre les ordinateurs basés sur l’Arduino Uno

Pour mon projet diplômés de masters ("Gowing ordinateurs, connexion corps, Cutting the Cord") de Konstfack Collège d'artisanat et de Design (céramique et verre/CRAFT), j'ai fait 3 verre ordinateurs basés sur les spécifications de l'Arduino Uno.
Une horloge de QR-code axée sur l’arduino

Une horloge de QR-code axée sur l’arduino

J'ai eu cette idée pendant un certain temps, mais j'ai jamais eu la chance de l'essayer. Vendredi, un collègue m'a donné un écran LCD pour Arduino, et j'ai pensé que c'était le bon moment pour construire une horloge qui communiquent à la fois par le
Plusieurs LED clignotant sur l’Arduino

Plusieurs LED clignotant sur l’Arduino

dans ce tutoriel, je vais vous montrer comment faire plusieurs LEDs clignotent avec Arduino.  Vous aurez besoin de trois LEDs, fils de raccordement, maquette et Arduino.Étape 1: Programmer l'Arduino Maintenant vous devez coller le code suivant dans l