Prof Creative Commons License 2018.10.08 0 0 3448

Szia,

Végtelenül leegyszerűsítve az állapotgép: vannak feltételek, amelyek lehetnek simán binárisak (igaz/hamis), vagy lehetnek analógok (adott érték alatt vagy felett, de ebből is bináris eredmény lesz). Az események a feltételek változásait jelentik. Egy állapotgépnek annyi konkrét állapota van, ahány kombináció előfordulhat a feltételekben.
A legegyszerűbb állapotgép a villanykapcsoló--villanykörte kombináció. Ha a villanykapcsoló "BE" állapotban van, akkor a lámpa világít, ha "KI" állapotban van, akkor nem világít. Az állapotváltozás a kapcsoló átbillentése egyik állapotból a másikba.
Beágyazott fejlesztésnél az állapotok változását vizsgáljuk, és a régi feltételcsomagból az új feltételcsomagba történő átmenet pillanatában egy szándékolt új állapotot hozunk létre. Ha a villanykapcsoló mikrokontrolleres vezérlést kapna, akkor azt vizsgálnánk, hogy mikor kerül át egyik állapotból a másikba a kapcsoló, és ennek megfelelően kapcsolnánk ki és be azt a bemenetet, amelyen a relémodul van.

A kódodban deklarálva és definiálva van már az elején néhány állapot:

boolean alarm=true;  // kezdéskor aktív
boolean ido=false;   
boolean idolejart=false;

Ez már eleve több, mint ami a legtöbb kezdő kódjában alapból megtalálható. A villanykapcsolós részt most nem írom le teljes egészében, az 5 perc ELEKTRONIKA facebook oldalán van erről egy elég hosszú jegyzet kódrészletekkel, példákkal egyetemben.
A te esetedben az van, hogy:
-- van egy esemény, az ajtó nyitása (ez egy feltétel változását jelenti),
-- az ajtó nyitása indukál egy állapotot, amikor a rendszer a riasztásig 30 másodpercig vár,
-- ebből az állapotból két további állapot elérése lehetséges:
1. ha beírod 30 mp-en belül a kódot, akkor kikapcsol az élesítés,
2. ha nem írod be a kódot vagy rossz kódot ütsz be vagy későn ütöd be, akkor riasztani kezd.
A 30 mp-es várakozási idő alatt tehát alapvetően két dolgot kell figyelned: beütötted-e a jó kódot vagy lejárt-e a 30 mp.
Az elsőt hagyjuk most, nem erre vonatkozott a kérdés. A második, az idő lejáratához kettő dolog kell: valami, amivel időt mérünk és valami, amivel megakasztjuk a program futását úgy, hogy közben ezt-azt tudunk csinálni. Az elsőre a megoldás a millis() függvény, ami eredményül a reset óta eltet időt adja vissza unsigned long formátumú változóban, milliszekundumokban. A másik a while() ciklus, ami addig fut, amíg a while utáni zárójelben lévő feltétel igaz.
A kódot nem fogom neked megírni, de a funkcionális kódvázlat így kellene kinézzen:
1. kezdeti állapot: ajtó zárva, riasztó éles, állapotfigyelés: nyílik-e az ajtó.
1--2. trigger: kinyílt az ajtó, indul a számláló.
2. állapot: ajtó nyitva, riasztó éles, állapotfigyelés: beírtad-e a jó kódot vagy lejárt-e az idő.
2--3. trigger: beírtad a jó kódot, kikapcsol a riasztó. [erre nem térünk ki]
2--4. trigger: lejárt az idő: bekapcsol a sziréna.
4. állapot: szól a sziréna (hogy meddig, az már részletkérdés, nyilván ez is egy állapot lesz).
Minden vizsgálandó dologhoz tartozik egy feltétel (egy-egy boolean), és minden triggervizsgálathoz kell egy-egy while utasítás.

A delay() függvény egy while, de semmi mást nem csinál, mint hogy azt figyeli, hogy lejárt-e az idő, nem tudod meghatározni, hogy közben mit csináljon. Ha a delay() helyett a while()-ba ágyazod bele azt a vizsgálatot, hogy lejárt-e az idő és hogy sikerült-e a jó kódot beírnod, akkor pont azt éred el, ami a célod (és remélhetőleg megérted az állapotgépek működését).
A BlinkWithoutDelay pontosan ezt demonstrálja, csak ott egyetlen feltétel van (letelt-e az idő), és egyetlen állapotot vált (világít-e a led).

Előzmény: Gergö86 (3444)