Hirdetés

Arduino konyhapult világítás

Egy Arduino Nano, egy MOSFET meghajtó, led szalagok, alu profilok, kábelcsatornák, 20m vezeték és egy hét szabadidő.

loop() - nyomógomb

Ez kicsit hosszú lesz... Az első sorokat sajnos behúzza a formázás, de a cikk végén mellékelem majd a teljes kódot vágatlanul.
void loop() {
wdt_reset(); //reset watchdog timer

//touch sensing
touch_value = ADCTouch.read(touch, 100) - touch_ref; //érintő szenzor
if (touch_value > 25 && !button) { //megérintve
timer = millis(); //időszámláló nullázása, ez méri a gombnyomások lent- és fenntartásának idejét
button = true; //gomb megnyomva
ack = false; //nincs feldogozva még ez a gombnyomás
}
else if (touch_value <= 25) { //nem érintve
button = false; //gombnyomás nullázása
}

Hirdetés

Elől a "kutya etetése": minden loop ciklusban meghívjuk ezt a függvényt, ami nullázza a Watchdog időzítőjét. Ha ezt nem tennénk, akkor az időzítő lejár és resetel a mikrovezérlő. Innen tudjuk, hogy megakadt a program, ha nem nullázzuk időben az időzítőt.
Ezután jön az érintés érzékelése. A referencia értékhez viszonyítva tudjuk megállapítani, hogy hozzáért-e valaki az érzékelőhöz.

Alább látható mi történik akkor, ha felengedjük a gombot kevesebb, mint 700 ms idő alatt. E határidő felett nyomva tartásként értelmezné a program, de ezt a funkciót kivettem. Eredetileg nyomva tartásra elkezdett "lélegezni" a szalag és azon a fényerőn állt meg, ahol elengedtem. Viszont a fokozatmentes szabályozásra végül nem volt igény.

if ((millis() - timer) <= 700 && !button && !ack) { //a gomb felengedése, annak feldolgozása előtt: nem járt még le a 700 ms és nincs lenyomva a gomb és "nincs feldolgozva"
if (mode != 1) { //ha nincs manuálisan bekapcsolva a világítás
mode = 1; //manuális bekapcsolás
dim = false; //eco mód alaphelyzetbe állítása (erről később)
}
else pressing++; //minden egyéb esetben gombnyomások száma +1
timer = millis(); //időzítő nullázása
ack = true; //feldolgozva. Ez azért kell, hogy a következő ciklusban ne hajtsa végre ugyanezt, amíg nem történik újabb gombnyomás
}

A mode változó egy állapotgéphez tartozik. Ha értéke 1, akkor világít minden szalag a kézi bekapcsolást követően.

Az alábbi meg kiértékeli a gombnyomásokat. (Azért írok folyton gombnyomást, mivel ha kicseréljük az ADCTouch-hoz fűződő sorokat egyszerű digitalRead()-re, akkor érintés érzékelő helyett használhatunk nyomógombot is. Persze a prell mentesítésről ilyenkor gondoskodni kell!)
Miután felengedtük a gombot, 500 ms türelmi idő után kiértékeljük. Vagyis gyors ismétlések kellenek a többszöri lenyomáshoz, mint az egéren a dupla kattintás.

if ((millis() - timer) > 500 && !button && ack) { //ismétlésre hagyott idő letelt és gomb felengedve és feldolgozva
if (pressing == 2) { //ha kétszer nyomták meg
light_tl = light_tl > 160 ? 150 : max_light; //nagy fényerőről kis fényerőre váltás és vice versa
light_bl = light_bl > 160 ? night_light : max_b_light; //ugyanez az alsó szalagokon
if (light_tl == max_light) dim = false; //itt egy bool változóval követjük a manuális váltásokat, ez az eco módhoz kell, hogy ne bíráljon felül
else dim = true;
}
else if (pressing == 1) mode = 0; //ha egyszer nyomták meg kikapcsol a világítás
else if (pressing >= 3 && PIR) { //háromszori (vagy többszöri) lenyomásra ki- vagy bekapcsoljuk a mozgásérzékelőt
PIR = false; //mozgásérzékelő kikapcsolása
EEPROM.put(1, PIR); //eeprom első címére elmenti a PIR változót
dimming();
}
else if (pressing >= 3 && !PIR) {
PIR = true; //mozgásérzékelő bekapcsolása
EEPROM.put(1, PIR);
dimming();
}
pressing = 0; //gombnyomások számának nullázása
}

Az EEPROM használata:
Ahogy azt láthattuk három különböző formában szerepelt eddig az EEPROM. Volt egy #include <EEPROM.h> a program elején, amivel elérhetővé tettük az EEPROM függvényeket. Majd a setup()-ban volt egy EEPROM.get(address, variable), feljebb meg két EEPROM.put(address, variable).
A Nano-n ha jól emlékszem 1 KB EEPROM áll a rendelkezésünkre amit beállítások, esetleg adatok tárolására használhatunk amik áramtalanítás után sem vesznek el. E két függvénnyel lényegében teljes mértékben ki is aknáztuk ezt a lehetőséget. Használatuk egyszerű, a get kiolvassa a változóba, míg a put beleírja az EEPROM-ba a függvénynek átadott változót a megadott címen.
A címzés egyszerű, de figyelni kell az adat méretére! Egy cím egy bájtot jelöl, vagyis az 1 KB tárterület 0-999 között címezhető kilobájtonként. A változó típusa határozza meg hány bájtot fogunk írni vagy olvasni. Ha 8 bites változónk van, akkor csak egy címen ír/olvas a függvény. Ha mondjuk 16 bites integer, akkor két bájton tárolja el, ahol minden további bájt a megcímzett terület után kerül lefoglalásra. Vagyis ha két bájtot adunk át a függvénynek: EEPROM.put(1, integer), akkor az 1. és 2. címekre fog írni.
Ilyenkor úgy kell megválasztani a címeket, hogy ne legyenek átfedések különben korrupt lesz az adat! A fenti példánál a következő adatot már csak a 3. címre tehetjük, mert az első kettőn lenne eltárolva a 16 bites integer.

A cikk még nem ért véget, kérlek, lapozz!

Azóta történt

Előzmények