Finite State Machine op een Arduino (6 / 7 stap)

Stap 6: Uw systeem brengen in de echte wereld


sc_timer_service.h

Oke, we rond geklikt, gebruikt een grafische editor (gewoonlijk geassocieerd met laag-niveau-talen), let's get dat ding tot leven. Eerste plaats moeten wij een codegenerator die onze toestandsdiagram in C-Code transformeert. Dat is verrassend eenvoudig, hoewel het zwarte magie kan lijken op het eerste.

Klik met de rechtermuisknop uw model-map en selecteer Nieuw -> Code Generator Model. Klik op jezelf in de wizard, en bevestig de codegenerator aan de toestandsdiagram die u hebt gemaakt voordat. Let op: In dat zelfde venster, er is een selector in de top, dat is gemakkelijk. Gebruik het om te selecteren van de C-Code generator in plaats van de Java een, en klik op Voltooien nadat u het selectievakje naast uw toestandsdiagram hebt gecontroleerd. Normaal gesproken, de generator zou nu moeten werken direct en automatisch de allertijden. Controleer of de twee mappen zijn gemaakt, src en src-gen. Als dat niet het geval, ga naar het Project in het hoofdmenu en check als bouwen automatisch wordt geactiveerd. Doen als het niet, en klik met de rechtermuisknop op uw project en selecteer Build Project. Een voortgangsbalk moet worden weergegeven naast de beide genoemde mappen. Wanneer u wijzigingen hebt aangebracht, kunt u ook met de rechtermuisknop op het bestand generator en selecteer Genereren Code artefacten.

De inhoud van de map src-gen is heel interessant. Het bestand LightCtrl.c bevat de uitvoeringvan de toestandsdiagram. Wanneer u het inspecteren, vindt u een functie LightCtrlIface_raise_button (LightCtrl * handle). U kunt deze functie aanroepen om te verhogen van de knop-event die wij verklaard eerder – bijvoorbeeld wanneer u van uw hardware knop pin controleren en ziet er op hoog niveau. Dan is er het bestand LightCtrlRequired.h, waartegen u nodig hebt om een kijkje te nemen. Het verklaart de functies die u moet implementeren. Voor deze toestandsdiagram, is er slechts twee functies: lightCtrl_setTimer en lightCtrl_unsetTimer. We moeten deze functies omdat onze toestandsdiagram de construct na 5s gebruikt. Dit is een erg handige functie, maar onze toestandsdiagram codegenerator levert niet een tijdbepalingsdienst, want dat is sterk platform afhankelijk-uw computer aankan timers anders dan de kleine Arduino, en timer handling op Mac & Linux anders dan op Windows werkt.

Gelukkig, ik zal u een tijdbepalingsdienst, zodat u niet hoeft uit te voeren uw eigen. In uw project, een nieuwe map maken, laten we noemen het scutils voor statechart utilities. U kunt het noemen wat je wilt of niet wilt maken van die map, het is gewoon een kwestie van organisatie. We zullen twee bestanden maken daar, sc_timer_service.c en sc_timer_service.h. Kopie de

code van GitHub binnen is er (u kunt ook het volledige project downloaden van GitHub hier):

sc_timer_service.h

sc_timer_service.c

Nu, kunnen we beginnen te werken aan de code van de Arduino in het *.ino-bestand dat de wizard is gegenereerd.

Bovendien aan de Arduino.h, ook avr/sleep.h, en natuurlijk onze statusmachine en de timerservice: LightCtrl.h, LightCtrlRequired.h en sc_timer_service.h. Nu, is de gewone Arduino spullen nodig: we definiëren de pinnen voor de knop en de LED, en deze instellen binnenkant van de setup-functie (dat is wat het voor werd gemaakt). Dan, we moeten definiëren van de functies die de toestandsdiagram verwacht we definiëren dat - lightCtrl_setTimer en lightCtrl_unsetTimer, zoals al eerder heb uitgelegd. Hier, we gewoon gebruik maken van de timerservice, en we zijn klaar. Nu moeten we reserveonderdelen een gedachte over hoe we eigenlijk de LED te activeren willen wanneer bereiken we de staat Licht op. Kortom, we hebben drie opties:

  1. We kunnen controleren of de statemachine is in de staat licht op, en activeren / deactiveren van de LED op basis van die informatie
  2. Wij kunnen naar onze toestandsdiagram gaan en een variabele wanneer bereiken we de Staten, die wij kunnen poll
  3. We kunnen een bewerking die worden beheerd met het licht dat wordt aangeroepen door de toestandsdiagram op een overgang toevoegen.

De eerste oplossing is echt slecht. Wij hadden logica betreffende de toestandsdiagram daarbuiten. Als wij zou de naam van onze staten, zou het ophouden te werken correct; maar die namen zijn bedoeld om te worden prozaïsche en niet logica gerelateerde. Met behulp van variabelen is oke, vooral bij het werken met desktop applicaties. We kunnen synchroniseren met hen elke x milliseconden of zo. Wij willen hier een bewerking gebruiken. Voeg het volgende toe van de toestandsdiagram interface verklaring:

 operation setLight(LightOn: boolean): void 

Dit verklaart een functie die accepteert een boolean-waarde als argument en retourneert de waarde nothing (void). Dit moet niet nieuw voor u, alleen de syntaxis hier anders is. Vergeet niet-statecharts zijn niet gebonden aan een bepaalde taal, zodat de syntaxis is generiek. Deze functie wordt automatisch weergegeven in LightCtrlRequired.h . Als dit niet het geval is, uw toestandsdiagram opslaan, klik met de rechtermuisknop op uw project en bouwen.

De functie verklaard hier ziet er zo uit:

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

Het handvat van de invoerparameter is van het type LightCtrl, is het de verwijzer op de toestandsdiagram. Bent u niet die ervaren in C: de ster duidt een zogenaamde pointer, zodat de variabele het adres van de variabele toestandsdiagram bevat. Dit helpt ons omdat we van het oorspronkelijke object bedienen kunt en hoeft te maken van een kopie van het. Dus, laten we de uitvoering van deze functie:

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

Zoals u zien kunt, schrijven deze functie is bloedige eenvoudig-wij niet zelfs gebruik maken van de ingang naar de toestandsdiagram, alleen we een hoog op de LED-pin als van de operatie argument waar, en weinig anders is.

We wijzigen de toestandsdiagram zelf zodat het lijkt in de eerste foto.

Onthouden stap 1? Links naar de slash is de benodigde input voor de overgang, rechts is de output van de machine staat als deze overgang is genomen. De output hier is om te bellen van de opgegeven bewerking met deze argumenten.

 #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++; } } 

Ook, Controleer de code in deze kern met regelnummers.

  • Regels 1-6 bevatten bevat zoals eerder is besproken.
  • Lijnen 8 en 9 define hardware pinnen die wij zult willen gebruiken voor onze arduino.
  • Lijnen 11 en 12 definiëren hoeveel timers onze toestandsdiagram kunt gebruiken, en hoeveel milliseconden tussen elke computing cyclus van de toestandsdiagram moeten doorgeven.
  • Lijnen 15 en 16 Declareer variabelen die we gebruiken kunnen om te tellen de cycli en voor het beheer van de tijd van de laatste cyclus.
  • Lijnen 17, 19 en 21 belangrijke variabelen voor het gebruik van de toestandsdiagram declareren: de toestandsdiagram zelf, de timerservice en een array van timers.
  • Regels 24 en 33 definiëren functies die de toestandsdiagram nodig voor de timer heeft en lijn 33 is de functie voor het instellen van de LED die we eerder hebben besproken.
  • In lijn 41 is void setup een standaard functie van de Arduino. Het heet een keer bij het opstarten. We gebruiken het om te initialiseren spullen-onze LED en knop pinnen krijgen hun richting geconfigureerd (INPUT is standaard, wij doen dat voor de duidelijkheid), de timerservice wordt geïnitialiseerd, de toestandsdiagram is geïnitialiseerd en ingevoerd. Het invoeren van middelen om te starten van de machine staat, zodat de eerste staat is geactiveerd-dit is de staat de ingangspunten van de staat op. Dus, bij het opstarten, het licht is weg.
  • In lijn 59 volgt de loop-functie, die heet de hele tijd door de Arduino.
  • In lijn 61 vangen we de huidige tijd met de millis() functie, die is gedefinieerd in de bibliotheek van de Arduino.
  • In lijn 63, wij controleren als onze knop is ingedrukt, en verhogen van de knop-event als het is.
  • In lijn 66 controleren wij als meer dan CYCLE_PERIOD milliseconden verstreken sinds we laatst onze toestandsdiagram gefietst.
  • Dit neemt enkele laden uit onze arduino en betekent dat we kunnen maximaal 10 milliseconden betrouwbaar gebruiken voor onze eigen functies.
  • In lijn 68, wij vertellen de timerservice hoeveel tijd is verstreken sinds de laatste aanroep, vertellen de toestandsdiagram te lopen één cyclus in lijn 70, opslaan van de huidige tijd in lijn 72, en verhogen de telling van de cyclus in lijn 73.

Met behulp van de arduino plugin, kunt u nu de arduino aansluit met de LED en de knop aangesloten op uw computer en gebruik de knop in de bovenste werkbalk het programma uploaden naar je arduino.

Het circuit is afgebeeld in foto's twee en drie.

De LED is aangesloten op een digital pin (6) met een weerstand van rotonde 200 Ohm. De kathode is gekoppeld aan GND.

Drukknoppen hebben vier pinnen, kijk welke van deze altijd zijn verbonden en die zijn verbonden wanneer u op de knop. Vervolgens koppelt u de digitale pin (3 wordt hier gebruikt) aan de ene kant, en een pulldown weerstand aan GND. Hiermee stopt u de pin uit "drijvende", een ongedefinieerde staat en houdt het op 0 volt. Wanneer de knop wordt ingedrukt en de andere kant is bevestigd aan de VCC, dat kant "stronger" is, omdat er geen weerstand en de spanning gaat tot 5 volt – in principe een voltage divider waar één weerstand 0 Ohm is. Gebruik een vrij hoge weerstand hier, omdat het beperkt de huidige gaan via de knop. 1 kR is minimaal.

Zoals u zien kunt, is de logica van dit programma volledig onafhankelijk van de werkelijke grootte van onze toestandsdiagram. Het maakt niet uit als onze toestandsdiagram 2 of 20 staten heeft – natuurlijk, als we iets doen willen, moeten we hier en daar een functie te implementeren. Maar de belangrijkste code binnenkant void loop altijd blijft vrij klein en voorziet in een modulair programma-architectuur. We hoeven maar te zorgen dat de interfaces van de toestandsdiagram van onze Arduino hardware binnenkant van onze code, de automatisch gegenereerde toestandsdiagram omgaat met haar interne logica. Herinner me hoe we besproken om te herstellen van de timer, wanneer de knop wordt ingedrukt weer? U kan nu een overgang van de Light On staat aan zichzelf toevoegt met "button" als bewaker van de gebeurtenis, en u zou niet moeten wijzigen of toevoegen van één regel in uw code. Probeer het uit!

Gerelateerde Artikelen

How to Make een Arduino Powered CNC Machine

How to Make een Arduino Powered CNC Machine

Stapsgewijze instructies over het bouwen van een low-cost CNC machine beheerd met behulp van een Arduino Uno!Stap 1: Een basis en een x-as slee fabricerenRoller skate wielen worden gebruikt voor het maken van de slee van de x-as. Een combinatie van 2
YouTube Stats weergeven op een 320 x 240 Pixel LCD-scherm met een Arduino Uno

YouTube Stats weergeven op een 320 x 240 Pixel LCD-scherm met een Arduino Uno

Deze kleine Instructable zal u tonen hoe te een 320 x 240 pixel LCD scherm aangesloten op een Arduino Uno met een schild netwerk ook gebruiken, om te tonen stats voor Youtube-kanalen.Ik heb dit gemaakt als ik wilde om te zien hoeveel abonnees en stan
Hoe een arduino gebaseerde 3-axis CNC machine draad

Hoe een arduino gebaseerde 3-axis CNC machine draad

Ik heb een aantal tutorials over hoe te bouwen van het platform voor een 3-assige CNC freesmachine.  Ik heb niet gezien dat iemand het lastig onderwerp van de elektronica aan te pakken.Hier nu is mijn poging om dit te doen.Stap 1: onderdelenHebt u no
Sleutels toe te voegen aan een Arduino Synth de harde manier-het Blacklord: het Organ Donor Project deel 2

Sleutels toe te voegen aan een Arduino Synth de harde manier-het Blacklord: het Organ Donor Project deel 2

(Opmerking-Dit is mijn 20e instructable! Dank aan iedereen volgende en commenting.on mijn projecten en aan de medewerkers die dit mogelijk maken. Deze site heeft zeker maakte me brengen mijn A game aan de workbench.)De Auduino granulaire synth door P
Maak een Web aangesloten Robot (voor ongeveer $500) (met behulp van een Arduino en Netbook)

Maak een Web aangesloten Robot (voor ongeveer $500) (met behulp van een Arduino en Netbook)

dit Instructable zal u tonen hoe te bouwen van uw eigen Web aangesloten Robot (met behulp van een Arduino micro-controller en de Asus eee pc).Waarom zou u een Web aangesloten Robot willen? Om mee te spelen natuurlijk. Rijd uw robot van hele kamer of
Beheersing van een karakter-LCD met een Arduino

Beheersing van een karakter-LCD met een Arduino

Hallo! Vandaag zal ik introduceren karakter LCD's en laten zien hoe ze op een Arduino aansluiten.Het is allemaal heel eenvoudig en gebruikt slechts 6 PINS met interface!Opmerking: het beeld is niet de mijne en komt uit http://www.micro-examples.com/p
De wijzerplaat van een roterende telefoon aan een Arduino interface

De wijzerplaat van een roterende telefoon aan een Arduino interface

een oude roterende telefoon kan worden gebruikt voor een aantal doeleinden in uw projecten Arduino - het als een roman als invoerapparaat gebruiken, of gebruik van de Arduino interface een roterende telefoon naar uw computer.Dit is een zeer basisgids
Beheersing van een MIDI-CC in Ableton Live met een Arduino Uno

Beheersing van een MIDI-CC in Ableton Live met een Arduino Uno

In dit instructable zullen we gebruiken een potentiometer op een Arduino Uno om controle van een MIDI-CC in Ableton Live. Een MIDI CC staat voor continue Controller, dat wil zeggen een getal in het bereik van 0 tot 127 inclusieve te moduleren iets me
Bijhouden van uw auto met een Arduino gebaseerde Lojack

Bijhouden van uw auto met een Arduino gebaseerde Lojack

De autodiefstal van de is een echte slepen! Verhoog uw kansen van het herstellen van uw auto door het installeren van deze eenvoudige Arduino gebaseerde tracker in uw auto.Dit project is vrij eenvoudig, en zou een goed project voor een nieuwe Arduino
Het laden van programma's op een Arduino UNO van Atmel Studio 7

Het laden van programma's op een Arduino UNO van Atmel Studio 7

In deze korte Instructable gaan we om te leren hoe om een programma aan de Raad van een Arduino UNO met behulp van Atmel Studio in plaats van de Arduino IDE te laden. Dit is handig wanneer u wilt ontwikkelen een programma met meer vooruitgangseigensc
Online grafieken met niets, maar een Arduino, Ethernet-Shield en Sensor

Online grafieken met niets, maar een Arduino, Ethernet-Shield en Sensor

Tot slot heb ik besloten om enkele van mijn bestaande projecten opgemaakt op instructables. Dit is aangepast van mijn project Super Graphing datalogger.Wat is de Super Graphing Data Logger (SGDL)? Het is een Arduino project dat integreert gegevensreg
Controle van uw Robot met behulp van een Wii Nunchuck (en een Arduino)

Controle van uw Robot met behulp van een Wii Nunchuck (en een Arduino)

na het dragen van mezelf spelen van Wii Boksen, ik kreeg aan het denken zou het niet geweldig als ik zou kunnen dit gebruiken om te controleren mijn robot, (op zoek naar mijn linkerhand).Op zoek rond het internet vond ik een schare van mensen die soo
Hoe maak je een Arduino web Server

Hoe maak je een Arduino web Server

In dit voorbeeld, zal u uw Ethernet-Shield en je Arduino te maken van een eenvoudige webserver gebruiken. Met behulp van de Ethernet-bibliotheek zal uw apparaat hebben de capaciteit om het antwoord van een HTTP-aanvraag met uw Ethernet-shield. De Eth
TL verlichting met een Laser Pointer en een Arduino

TL verlichting met een Laser Pointer en een Arduino

een paar leden van de Alpha één Labs Hackerspace hou niet van de harde licht weggegeven door tl armaturen.  Ze wilden een manier om te kunnen gemakkelijk te controleren de afzonderlijke armaturen, misschien met een laserpointer?Ik heb recht op.  Ik e