State-machine

Fra HTX Arduino
Spring til navigation Spring til søgning

En god metode til at holde styr på hvad en PIC skal lave i forskellige situationer er ved at etablere det der i softwaren kaldes for en state-machine.

Princippet

Det grundlæggende princip i en state-machine er, at den kan være i en række tilstande, alt afhængigt af hvad programmet er i gang med at udføre, og at en række hændelser kan få den til at skifte tilstand.

En state-machine fungerer godt sammen med et simpelt styresystem, der er etablere med et hurtigt Forever Loop.

En god måde at dokumentere en state-machine på er ved at starte med et tilstands-diagram, hvor en række boller illustrerer de forskellige tilstande som state-machinen kan være i, og pilene mellem bollerne illustrerer hvordan man kan komme mellem de forskellige tilstande, og hvad det er der skal til for at få den til at skifte tilstand (teksten ved pilene)

Eksempel på state-machine

Et godt eksempel til at illustrere hvordan en state-machine kan fungere er typisk noget med indtastning og visning af noget i et display.

Eksempel på State-machine

Den viste state-machine skal kunne vise en aktuel temperatur, indtaste et nyt setpunkt, og vise hvad det aktuelle setpunkt er. Systemet skal samtidigt kunne håndtere en temperatur-regulering.

En god måde at starte state-machinen er ved at definere en hvile-tilstand, og i dette tilfælde vil det være rimeligt, at visningen i hviletilstanden er den aktuelle temperatur. Det kan måske også være praktisk allerede på nuværende tidspunkt at definere om temperatur-reguleringen kun skal foregå når den er i hvile-tilstand, eller om det også skal ske i de andre tilstande. Jeg vil her vælge at der kun skal reguleres i hvile-tilstanden.

Indtastning af setpunkt

Hvis man vil indtaste et nyt setpunkt, så skal man fra hvile-tilstanden taste #-tasten, så man kommer ind i tilstanden med indtastning af setpunkt.

Inde i den tilstand sker selve indtastningen af tallet der skal være det nye setpunkt, og som state-machinen er defineret kan man kun taste cifre, og så skal man afslutte med #-tasten, hvorved man kommer over i visningen af setpunktet.

Der er en anden mulighed for at komme ud af indtastningen på, nemlig ved timeout. Den mulighed er indført for at man ikke skal kunne blive hængende i indtastningen, uden at man kommer tilbage og regulerer på temperaturen.
Der er ikke defineret hvor lang timeout skal være, men den skal være fornuftig lang, så brugeren har god tid til at orientere sig på tastaturet, og det kan også være en god ide at tiden nulstilles hver gang brugeren indtaster et nyt ciffer. Et rimeligt timeout kunne være 5 - 10 sekunder.
Der er heller ikke defineret hvad der skal ske med setpunktet, hvis der kommer timeout, men det ville sikkert være bedst om den brugte det oprindelige setpunkt, for ikke at reguleringen skal gå helt i skoven.

Visning af setpunkt

Denne tilstand er etableret, for at brugeren kan se hvilket setpunkt der reguleres efter. Setpunktet skal blot vises i displayet.

Man kommer i denne tilstand når man har indtastet et nyt setpunkt, eller hvis man har trykket på *-tasten i hviletilstanden.

Man kan kun komme tilbage til hvile-tilstanden herfra, og det kan ske ved at man taster *-tasten eller ved at man venter på timeout. I denne tilstand vil timeout være besdt omkring 1 - 2 sekunder.

Problemer med denne state-machine

Ud fra den måde som state-machinen er defineret, så kan der komme et problem.

Hvis tasterne er en type der blot registreres når de holdes nede, så vil man få et problem både med #-tasten og med *-tasten.

Problemet med * tasten vil være at når man i hviletilstanden taster den, så vil den gå i Vis setpunkt, men hvis man stadig registrerer tasten her, så vil den gå tilbage i hvile-tilstanden.

I praksisi vil det betyde at når brugeren trykker på tasten, så vil den vippe lynhurtigt mellem de to tilstande, og det vil virke som en tilfældighed om den ender i Vis setpunkt eller i hvile.

Samme problematik kan være gældende for #-tasten i Indtast setpunkt, men resultatet vil her være lidt anderledes, nemlig at den altid vil løbe direkte gennem indtastningen og over i visningen, altså vil man ikke kunne komme til at at taste cifre, med mindre man er lynhurtig.

Pseudokode til state-machine

For at illustrere hvordan koden kunne laves, så er der her vist pseudokode for eksemplet.

For at state-machinen skal fungere fornuftigt, så kræves det at den er placeret i et loop, hvor den kommer forbi tit (princippet er polling).

De 3 tilstande navngives Hvile, Indtast og Vis

Pseudokoden kan laves som følger:

Hvis Hvile
   Vis aktuel temperatur
   Hvis #
      Tilstand = Indtast
      NytSetpunt = 0
   Hvis *
      Tilstand = Vis
Hvis Indtast
   Hvis ciffer
      NytSetpunkt = NytSetpunkt * 10 + ciffer
   Hvis #
      Setpunkt = NytSetpunkt
      Tilstand = Vis
   Hvis Timeout
      Tilstand = Hvile
Hvis Vis
   Vis Setpunkt
   Hvis *
      Tilstand = Hvile
   Hvis Timeout
      Tilstand = Hvile
Reguler temperatur

Implementering i Arduino

Her er der et forslag til hvordan den beskrevne state-machine er blevet implementeret pakket i en ZIP-fil.

I implementeringen anvender jeg Keypad-modulet til indtastning af tal - det kunne lige så godt gøres med RC-tast eller med simple kontakter for demoformålet. Til visningen har jeg anvendt LiquidCrystal-modulet med et 2 x 16 karakters display - det kunne selvfølgelig også være et 2 x 8, hvor man så begrænsede teksten, eller helt simpelt kunne man få noget ud på nogle lysdioder.

Der er regulering, og der er 3 forskellige display-visninger, alt efter hvilket state den befinder sig i.

Den øverste linie i displayet skifter alt efter hvilket state den er i, og den nederste linie viser om der varmes - der er plads til flere informationer.

I hvile-tilstanden er der bare en udlæsning af den aflæste temperatur. Man skal have en LM35 på A0 indgangen, og have 1,024V på AD-ref. Der skal forbindes til relæ med et varmelegeme på ben 13.

visningen er som følger:

Temperatur: nn.nn
ON

I Indtastnings-tilstanden er visningen:

Indtast: nn
OFF

I Indtastnings-tilstanden er visningen:

Setpoint: nn.nn
ON

Tasterne med # og * har den beskrevne opførsel.

I indtastningen timeoutes efter 20 sekunder

I visningen af setpunktet timeoutes efter 2 sekunder

Der er ligeledes understøttet en visning i Serial monitor

Implementering i JAL

Her er der et forslag til hvordan den beskrevne state-machine er blevet implementeret pakket i en ZIP-fil.

I implementeringen anvender jeg AD-tast-modulet til indtastning af tal - det kunne lige så godt gøres med RC-tast eller med simple kontakter for demoformålet. Til visningen har jeg anvendt ALCD-modulet med et 2 x 16 karakters display - det kunne selvfølgelig også være et 2 x 8, hvor man så begrænsede teksten, eller helt simpelt kunne man få noget ud på nogle lysdioder.

Der er ikke lavet nogen regulering, men der er 3 forskellige display-visninger, alt efter hvilket state den befinder sig i.

Den øverste linie i displayet skifter alt efter hvilket state den er i, og den nederste linie er anvendt til debug-oplysninger, med state og timeout-counter

I hvile-tilstanden er der bare en udlæsning af et AD-tal. Man kan forbinde et potentiometer til den aktuelle kanal, og se at tallet følger spændingen på indgangen. visningen er som følger:

AD nnnn
ST x T nnnn

I Indtastnings-tilstanden er visningen:

SET  nnn
ST x T nnnn

I Indtastnings-tilstanden er visningen:

SETPOINT  nnn
ST x T nnnn

Tasterne med # og * har den beskrevne opførsel.

I indtastningen timeoutes efter 20 sekunder

I visningen af setpunktet timeoutes efter 2 sekunder

Programmering
Programmeringsbegreber Initialisering - Sekvens - Algoritme - Hexadecimal - Det Binære Talsystem - HEX-fil - ASCII - Interrupt - Events - Styresystem - Autocomplete - Selvstudie Programmering - Hour Of Code - Stepwise Improvement - Syntaks - Prog-links - Microcontroller - ChatGPT
Grundlæggende C C float - C double - C-løkker - Datatyper - Konstanter - Regnearter - Funktioner - Return - Returværdi - Rekursion - Semikolon
Variabel Typer boolean - byte - int - unsigned int - word - long - unsigned long - short - float - double - char - unsigned char - string - char array - String - object - Array - 2-dimensionelt Array - void
Program-klassikere Polling - State-machine - Trykknap - Forkant - Bagkant - Prel
Arduino Arduino til Programmering - C til Arduino - Programmering Shield - Arduino PC-software - Arduino Udviklingsmiljø - Arduino Pin Library - Funktion - Arduino Seriel - Arduino String - Arduino String Split - Arduino StateChangeDetection - setup() - loop() - Compilerdirektiver - Asynkron kommunikation - millis() - micros() - Scratch for Arduino - Send fra Arduino til Excel - [[]] - [[]]
Processing Grafik i Processing‎ - Keyboard i Processing - Mus i Processing‎ - Tid i Processing‎ - Draw() - Setup() - Tal Input til Processing - Syntaksfarvning - Kommunikation fra Arduino til Processing - Kommunikation fra Processing til Arduino
javaScript Javascript input‎ - Javascript output‎ - Javascript strukturer‎ - Javascript syntaks‎ - Tid i javaScript - Objekt‎ - AJAX
Serverprogrammering PHP - MySQL - Task Scheduler - WeMOS
PIC JAL - [[]]
Scratch for Arduino S4A Installation - S4A programmering - S4A undervisningsforløb - S4A begrænsninger
Program Dokumentation Algoritme - Flowchart - Pseudokode - Datastruktur - Dataabstraktion - Pulsplaner - Program-kommentar - Teori - Test - UML