State-machine
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.
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
