Régen egy hasonló problémára készítettem két körös PID szabályzót. A fűtőtest egy nagy tömegű közeget fűtött, ami hőátadással tartotta a "mag" hőmérsékletét stabilan.
A nagy tömegű közeg, és a mag hőmérséklete is mérve volt. A míg a mag hőmérséklete 1°C-nál alacsonyabb hőfokú, addig a nagy tömegű közeg hőmérséklete +3-4°C-al magasabb a szükségesnél. Amint a mag hőmérséklete kezdett közeledni a szükségeshez, a nagy tömegű közeg hőmérséklete fokozatosan csökkentve van a beállítottra. Ha jól van hangolva a rendszer, akkor a nagy tömegű közeg, és a mag hőmérséklete egyszerre éri el a kívánt értéket. Innentől kezdve csak a nagy tömegű közeg hőmérsékletét kell tartani a kívánt értéken.
if ((second - idopont) > 30) { // 30 másodpercenként vizsgálja, hogy a hőmérséklet hogyan alakul
Ha a kilépési időpontot előre meghatározod, akkor csak a millis aktuális visszatérő értékével kell összehasonlítani bármiféle matek nélkül. Nyilván "kényelmetlen" három nagyságrenddel eltérő számokkal számolni és van benne kis hibázási lehetőség is, de szoftver optimalizálás tekintetében nem mindegy. Ráadásul jóval áttekinthetőbb.
Ami a "hiba" jelenséget illeti. Képzelj el egy extrém szélsőértéket, a belső épp 28 fok felett egy tizeddel, a külső épp 26 felett egy tizeddel. Ha valamelyik eléri az aktiválási feltételt, akkor a külső 1,3 óránként 1 fokkal kezd el nőni, vagyis 1 óra 20 perc elteltével 27, 2 óra 40 perc elteltével 28 fok lesz, de vajon ez idő alatt mennyire hűl vissza a mag? 26,5? 27,5? 28,5?
Amit LyPapa írt, pont erre ad egy lehetséges, a PID-nél egyszerűbb megoldást. Csak ehhez kellenek elég jó historikus adatsorok, hogy optimalizálni lehessen, különben vaktába lövöldözöl.
Állapotgépként ezt a rendszert nem lehet egyszerűen leírni, mert több analóg érték nem feltétlenül direkt összefüggéséből áll és csak egy ideális egyensúlyi pontja van, mégpedig az, amikor minden, a mag, a tartály és a külső levegő is 28 fokos. Ezt úgy szokták megoldani, hogy nem az állapotot és a határt figyelik, hanem a határtól való távolságot és az azt befolyásoló értékek változási irányát és sebességét (ez a PID szabályozás). Ha cseppet egyszerűsítünk rajta, akkor historikus adatsorok alapján lehet csinálni egy olyan mátrixot, amely a külső és a belső hőmérséklet arányai alapján kiadja, hogy ha kell, akkor mennyi időre kell bekapcsolni a fűtőelemet, hogy a mag viszonylag stabilan (mondjuk +/- 0,5 fok) 28 fokon maradjon.
A fenntartó jellegű fűtés is szakaszos, de a be és kikapcsolási határokat nem fix értékekkel határozod meg, hanem a puffer víz - táptalaj mért értékei alapján felvett hőátadási görbe szerint. Azaz, lehet, hogy nem 28 fokos táptalaj esetén kapcsolsz, hanem pl. 29 fokos víz, és 27 fokos táptalaj ponton kikapcsolod a fűtést - és hűlési görbe szerint pótolod, ha kell. Így a fűtővíz hőmérséklet ingadozása kisebb lesz, mint mostani, on-off vezérlés során, következésképp a táptalaj is a kezdeti felfűtési szakasztól eltekintve, egyenletesebb hőmérsékletű lesz.
Asszem a pid-el kapcsolatban igazad van, nem lenne értelme. A sok víz miatt akkora a rendszer tehetetlensége, hogy az elvárt határokon belül tudom tartani a mostani rendszerrel.
A változókat javítgatom. Az idő átváltása az én lustaságom miatt van, nekem így egyszerűbb volt a kalkuláció.
"Az if vizsgálatnál matekozol (ciklusonként egyszer, feleslegesen)."
Mire gondolsz? Illetve melyikre?
Állapotgép:
A HIBA részben kétféle állapot lehet: ( a belső hőmérséklet 28 fok felett tehát nincs hőigénye, csak a külső víz hőntartása a cél)
- vagy hűl, hiszan az if (kulso>28) igaz=false; lefutott, nincs fűtés.
- vagy melegszik, mert az if (kulso <26) igaz= true; lefutott, hiszen meg kell gátolni a környezet lehűlését.
Megszaladni, a tehetetlenség és a 28 fokos korlát miatt nem tud.
Ezt hogyan lehetne állapotgépbe betenni? hiszen mindkét állapot előfordulhat.
Ami az elvet illeti. Egy kis tehetetlenségű, nagy pontosságú pid szabályozó (pl. kávégépekben, pákában, stb.) van ilyen, adott esetben másodpercenként többször kapcsol. Azt, hogy ne legyen szükség sűrű kapcsolgatásra, azt a teljes rendszer hőtehetetlenségének növelésével tudod elérni (feltételezve, hogy nem akarsz engedni a +/- 1 fokos maximális tűrésből). Nagyobb tömeg = jobb hőtartás (pontosabban több tárolt hő) = ritkább kapcsolgatás. Már feltéve, hogy egyéb környezeti feltételek és/vagy a szigetelés ezt lehetővé teszik. Segíthet a közeg direkt áramoltatása is, mert sok esetben a gravitációs áramlás nem ad megfelelő homogenitást a közegnek, még a viszonylag jó vezető víz esetében sem.
A nagy kérdés, hogy mennyire akarsz a lehetséges legjobb megoldásig elmenni? Mert ahhoz nem biztos, hogy önmagában a kód nyegletése elegendő lesz.
Nézzük a kóddal kapcsolatos nehézségeket.
Változók
A millis() visszatérő értéke unsigned long. A kód elején három változót deklarálsz float-ként, amiből az idopont tuti nem jó, helyette:
unsigned long idopont = 0;
Az időben én nem kínlódnék a másodpercekkel, minden olvasásnál/írásnál az ezerrel való osztás sok-sok órajelciklus, feleslegesen.
A felirat kiírása így kissé faramuci, sem jó, sem rossz, van előnye, van hátránya, én nem bíbelődnék vele így (valószínű: állapotgép-státus alapján lenne, menüt terveztem így i2c kijelzőre, kiválóan működött).
Általában: a változók elnevezései abszolúte nem beszédesek. Ezek elengedhetetlenek a jól olvasható (és így jól karbantartható) programhoz.
Logika
Itt is bejön a változó-elnevezés, mivel az idopont nevű változóra azt írod, hogy "előző vezérlés időpontja", pedig nem erről van szó, hanem arról, hogy mikor volt utoljára ellenőrzés.
Az if vizsgálatnál matekozol (ciklusonként egyszer, feleslegesen).
A fűtés szükségességét (teljesen jól) kiszervezted egy belső függvénybe, de az speciel nem azt csinálja, ahogy hívják, hanem ellenőrzi, hogy kell-e fűteni (konkrétan a kapcsolást a loop()-ban lévő két állapotú if kapcsolja).
A futes() függvényben van egy érdekesség, ha a táptalaj hőmérséklete 28 fok felett van és a külső hőmérséklet 26 fok alatt, akkor bekapcsolja a fűtést. Viszont van olyan állapot, amikor semmit sem csinál:
A bal oldalon a külső, a felső sorban a belső hőmérséklet. Ha a belső hőmérséklet 28 fok felett van ÉS a külső hőmérséklet kisebb vagy egyenlő, mint 28 ÉS nagyobb vagy egyenlő, mint 26, akkor az állapot nem változik. Nyilván valószerűtlen, hogy ez a helyzet előforduljon, mert a rendszer 29 fokos külső hőmérsékletnél és a felett mindenképp kikapcsol, de ettől ez még ettől eltérő esetben egy csúnya megfutás eredménye lehet (vagyis a rendszer fűt, mint a veszedelem, de nincs rá szükség, viszont nem alakul ki olyan helyzet a feltételek ellenőrzési láncolatában, ami indukálná a kikapcsolást).
A futes() függvényben ez a boolean igaz = true; azért erős. (Ismét: változó-elnevezés.) Az egész kódra igaz, hogy "meg kell fejteni", ahelyett, hogy simán végigolvasná az ember.
Egyebek
Én kitettem volna az adatok kiíratását egy külső függvénybe (lcd.print sorozat).
Ha nem muszáj, elengedném a Serial.print-eket, ha feltétlen kell debug-információ, azt pár számmal a kijelzőre ki tudod írni.
Külső hőmérsékletben max 3 fok ingás lehet, így azzal érdemben nem foglalkoznék.
A külső vízköpeny elég komoly puffert jelent, az 50 liter víz 1 fokkal való emelése egy 75W-os cekász esetében 1 óra 20 perc, figyelmen kívül hagyva a külső veszteséget és a belső tartály hőnyelését.
Közben átírtam egy kicsit a kódot, leginkább a hőfokvezérlés részét az elmúlt időszak tapasztalata alapján:
boolean futes(){
boolean igaz = true; if (belso > 28) // nincs fűtésigény { if (kulso>28) igaz=false; if (kulso <26) igaz= true; } else // van fűtés igény { if (kulso < 29) igaz = true; else igaz = false; }
Serial.println(igaz); return igaz; }
Ezzel nem engedem túlhűlt állapotba se, és az eredeti 32 fok is soknak bizonyult.
A 75W felét ha elpocsékolom az csak 250Ft. Ezért nem éri meg megmozdulni, lévén ez a fűtési ciklus csak 1 hétig tart. (És ez csak akkor jönne össze ha végig fűtene, de ugye nem megy folyamatosan). Utána is kell majd fűteni, de ott 25 fokkal még kevesebb költség.
Ezzel az átírt kóddal jobbnak tűnik. A fűtési igénybe kellene még beletennem egy olyan hiszterézist ami biztosítja, hogy ne legyen félpercenként ki-be kapcsolgatás.
A benne lévő portéka olyan 20-30.000 Ft értékű. Megvehetném a piacon, de fontos a fajta (sőt a klón) azonosság, ezért inkább szaporítok.
Három mérési ponton (környezeti, táptalaj, temperáló medence) kellene mérni és logolni a hőmérsékletet pár percenként (sűrűbben szerintem felesleges), illetve mellé logolni, hogy mikor ment és nem ment a fűtés. A fűtés kapcsolgatására a mostani eljárás helyett egy egyszerűbb szabály kellene: HA a táptalaj hőmérséklete 27,5 fok alatt van ÉS a temperáló tartály hőmérséklete 29 fok alatt van ÉS a külső hőmérséklet (mondjuk) 22 fok alatt van, akkor kapcsoljon be fix időre (fél óra), és ez idő alatt is végig naplózni kell.
3-4 nap adatgyűjtés után lesz egy görbéd, amit aztán lehet elemezgetni, hogy a hőmérsékletek különböző lefutások mellett hogyan hatnak egymásra. Enélkül csak szanaszét durrogtatsz.
75 W fűtőteljesítményre 50 százalék feletti veszteség borzalmasan sok. Valahogy meg kellen oldani, hogy zártabb legyen a rendszer hőveszteség tekintetében. Ne menjen el szanaszét, mert nincs az a szőlő, amiért ennyi energiát megéri pocsékba rakni.
Ilyen rossz hővezető képességű anyagban +/- 1 fokot tartani szép mutatvány, nem vagyok benne biztos, hogy ilyen peremfeltételek mellett egyáltalán megvalósítható.
Viszont. Nem tudom, hogy hány ilyen cuccod van összesen, viszont az elég valószínű, hogy ha kicsit megnöveszted a teret és beteszed az egészet egy többé-kevésbé hermetikusan zárt cuccba, akkor ott jóval egyszerűbb lesz stabil 28 fokot tartani. Télikert, pálmaház stb. kicsiben. Mert pl. a levegőt jó keringetés mellett jóval egyszerűbb +/- 1 fokon belül stabilan tartani, mint egy kétes hővezető képességű keveréket tisztán kontakt hőátadással.
ha a víz hőmérséklete lényegesen magasabb mint a tápföldé, valamint túlfűtés esetében a hűlési karakterisztika felvételéhez.
Első esetben azt vizsgálod, hogy a víz és a tápföld közti hőátadás fűtés irányban, a kikapcsolt fütőelem mellett hogyan folyik, a második eset egyértelmű.
- én biztosan abból indulnék ki, hogy a kis tartályt körülvevő víz és a kis tartály földje közti hőmérséklet különbség legyen a vezérlés alapja. Ezzel, ha jól értelmeztem a megcélzott 'kitöltési tényező' alapú fűtés programozást, meg tudod támogatni. Elengedhetetlen lenne legalább két dolog naplózása:
- a fűtővíz hőmérséklete
- a tápföld hőmérséklete
akkor, ha a víz hőmérséklete lényegesen magasabb mint a tápföldé, valamint túlfűtés esetében a hűlési karakterisztika felvételéhez.
Ekkor a szakaszos fűtés hőmérséklet jelenlegi 'fűrészfogas' ábrájára rá tudnál húzni egy burkológörbét - azaz, fenntartó jellegű fűtést tudnál programozni. Feltételeztem, hogy a külső hőmérséklet változása nem lényeges mértékű (!), egyébként azt is figyelembe kellene venni.
Hasonló lenne a vezérlés, mint a kazánok előremenő és visszatérő fűtővíz hőmérséklet különbség alapú szivattyú sebesség és láng moduláció vezérléséhez.
Mivel nem vagyok programozó tudom, hogy sok hiba van benne. Ha van hozzá energiád örülnék ha megmutatnád a főbb hibákat.
PID:
Ami probléma, hogy a talaj nem talaj, hanem fűrészpor és perlit keveréke, persze nedvesen. A hővezető képessége töredéke a külső hordó falának. Ez az indulásnál gond, illetve a nemfűtés időszakában.
Most, hogy figyelem a fűtés ideje alatt viszonylag jól követi a fűtővíz hőmérsékletét a maghőmérséklet. De a hűlése sokkal gyorsabb. (Erre számítottam is, az energetikai számításaim során látszott, hogy sokkal kisebb a hővesztesége a belső hordónak mint a külsőnek.)
A 28 fok +-1 fokos hiszterézissel lenne jó.
A cekász 75 wattos, a hordó vesztesége 35-50W között mozog hőmérséklet függvényében.
Ebből nem lehetne kiindulni? Ha egy órás fűtési ciklust alkalmaznék és annak a kitöltési tényezőjét módosítanám?
A kód nem igazán következetes, de így nagyon hirtelen első blikkre úgy néz ki, hogy működik, még ha nagyon messze is van az elegánstól (plusz egy rahedli alapvető ellentmondás, illetve hiba is van benne pl. változótípusok viszonylatában).
PID
Engedd el!
Ez egy közvetett rendszer, ráadásul elég nagy külső kitettséggel. A PID olyan rendszerek szabályozására való, ahol nagyon direkt és a körülményekhez képest viszonylag zárt a visszacsatolás, továbbá nagyon alacsony hiszterézis mellett viszonylag magas precizitás (vagy alacsony tűrés) elérése a cél. Műszaki oldalról a legnagyobb kihívást az jelenti, hogy kellően zárttá kell tenni a rendszert: ez azt jelenti, hogy a szabályzás beavatkozása direkt, közvetlen és pozitív korrelációban kell legyen a beavatkozásból fakadó eseménnyel. Vagyis, ha fűteni kezded a rendszert, akkor a változás (nagyjából azonnal) a hőmérséklet emelkedésében nyilvánuljon meg. A másik, hogy viszonylag kicsi legyen a kitettsége a környezetre, így a te esetedet alapul véve, ne legyen egy szigetelő és közvetítő közeg a konkrét temperálandó közeg és az aktuálisan fűtött (vagy hűtött) közeg között. Mechanikailag ezt úgy lehet elképzelni, mint egy olyan önegyensúlyozó robotot, amelyben van egy teljesen véletlenszerűen billegyő rugalmas rész. Hiába avatkozik be (elvileg) jól a motor, ha a rugalmas rész a beavatkozást negligálja. Ilyen borzalmas nagy rendszerben, mint a tiéd (mert felteszem, hogy nem 1-2 decis hordóról és maximum fél literes külső hordóról van szó, a PID működéséhez komoly hőszigetelés, borzalmas (kW-os) fűtőteljesítmény kellene, az áramoltatásról és egyéb úri huncutságokról nem is beszélve.
A jó megoldáshoz kellene tudni a táptalaj hőmérsékleti lefutását 4-5 napon keresztül, összevetve a sima környezeti hőmérséklet és a temperáló medence hőmérsékletével. Ebből lehetne kiókumlálni, hogy hol a hiba. Kiderülne az is, hogy milyen késéssel hat a temperáló medence hőmérsékletének változása a belső hordó földje hőmérsékletének változására. [Megjegyzem, ennek az összefüggésnek az ismerete nélkül gyakorlatilag lehetetlen normálisan paraméterezett PID szabályozást csinálni.]
Látatlanban az biztos, hogy a fűtőteljesítmény kevés (1 kW-tal 100 l vizet is fel lehet fűteni belátható időn belül 20-ról 29 fokra). Aztán ki kellene találni, hogy a 28 fok mennyire sarkalatos, +/-0,5 kell vagy +/-2 fok is belefér.
Rengetegféle szabályozási algoritmus van, mindnek van előnye és hátránya, viszont az összes alapvetően a hardver tulajdonságain alapszik. Gyenge hardverrel nem fogsz tudni jól szabályozni. Lásd a folyamatosan felfővő Skodákat és Zaporozseceket. Pl.
Először is köszi a videót, egy futó projektnél pont segített.
De persze jön a de:
A projekt egy szőlővessző gyökereztető hordó fűtésvezérlése. Elkészült, működik, de mivel sima proporcionális vezérlést alkalmaztam, a külső részeken túl nagy a hőingás. (Több órás a felfűtés és a lehűlés is.).
A technika nem túl bonyolult: egy nagyobb hordóban víz, abban egy kisebb hordó és abban van a szőlővessző.
A vízben van egy fűtőszál az melegít. Mérem a víz hőfokát és a szőlővesszők "földjének" is a hőfokát. Ez utobbi a lényeges 28 fok kellene.
A kód az abszolút mezitlábas minimum és alapvetően az elvek bemutatásán túl igazából semmilyen sztenderdnek nem felel meg, mert nem kezel különleges helyzeteket, illetve nincsenek benne olyan funkciók, hogy pl. a prellt kivédje. Ez egy kicsit komplikáltabb, pár nap múlva lesz róla film.
Ha a filmben említett 2-es fázisban szempont a gomb figyelése, akkor teljesen más eljárás szerint kell megcsinálni, mert itt elágazás kerül a kódba. A 2-es fázisból vissza tud menni az 1-es fázisba is. Ennek a kiváltó eseménye az 1-es gomb megnyomása. Emiatt a 2-es állapothoz hozzá kell rendelni két, párhuzamosan futó vizsgálatot: az idő leteltét és a gomb1 benyomását. Ha akkor ebből az állapotból az idő letelte triggereli ki a gépet, akkor a 0 állapotba, ha a gomb megnyomása, akkor az 1 állapotba kerül. Több lehetséges módon lehet implementálni, mindegyiknek van előnye és hátránya, de szerencsére delay() ezekhez sem kell. Például:
Itt már azért észnél kell lenni, hogy mit és hogyan figyelünk, mert ha pl. az állapot vizsgálatát kifelejtjük (bízva abban, hogy a while úgyis kiléptet), akkor bajban leszünk, mert úgy is kikapcsoljuk a 2-es relét, hogy azt nem kellene.
A delay() használata ilyen hosszú távú kivárásokra teljesen indolokatlan, sőt, alapvetően káros, ezt elmondtam a filmben. Rövidebb kivárásokat (ahogy itt lent javasolták), pl. a prellből fakadó nemkívánatos események elkerülésére lehet használni, de csak ügyes programszervezéssel (bár ezt is inkább hardveresen érdemes megoldani).
A 2-es gomb figyelése egy teljesen másik irány. Tisztázni kell, hogy mikor fordulhat elő, hogy valaki megnyomja, milyen befolyása van arra, hogy az 1-es gomb be van-e nyomva, illetve milyen befolyása van az állapotokra. Ki lehet-e lépni abból a szekvenciából, amit a 2-es gomb megnyomása indít, illetve az pontosan mikor (a megnyomáskor vagy az elengedéskor) indul-e.
Alapszabályként: -- minden állapotban csak azt vizsgáljuk, ami az állapotból való kilépést indukálhatja. A példában ez csak az 1-es gomb vagy az idő lejárta volt, de ahogy komplikálódik a helyzet, más is lehet (1-es gomb ÉS az idő együtt, 2-es gomb stb.),
-- delay()-t csak néhány esetben érdemes használni (lásd a korábbi példát erre a prellmentesítésnél),
-- egy bizonyos bonyolultságon túl a sok-sok egymásba ágyazott feltétel elkerülésére érdemes szétválasztani és saját beágyazott függvénybe kiszervezni magát az állapotváltozáshoz kapcsolódó cselekményt (pl. a relék behúzását vagy elengedését), a loop-ban pedig kizárólag az állapotváltozások triggereinek ellenőrzését bennehagyni (abból is csak a legkevesebbet),
-- az elágazások kezeléséhez több lehetséges eljárás van (elágazáskezelés), a while zárt ciklus, a do/while elöl nyitott ciklus, az if egyedi elágazás, a switch/case többpontos strukturált ellenőrzés, mindegyiknek más előnye és hátránya van,
-- alapvetően időkritikus bemenet-érzékeléshez megszakítást használunk, ami aztán az egészet alapjaiban átstrukturálja, mert teljesen jelentősen más logika mentén kell kezelni, ekkor be tud jönni a kvázi többszálúság, sőt, az is, hogy pl. idővezérelt megszakítással váltsunk bizonyos állapotok között. Ezzel létrehozható kvázi multitasking is, mert az MCU végzi a maga dolgát (valamit), és a gombnyomásokhoz kapcsolódó állapotváltozásokkor csak az ahhoz tartozó változtatást csinálja meg egy második állapotgépben, ami aztán újabb külső (gombnyomás) vagy belső (lejáró idő) interruptok alapján teszi a dolgát. A delay() és egy belső interrupt között annyi a differencia, hogy a delay() alatt még akkor sem tudsz semmit csinálni, ha szeretnél, a belső idővezérelt interrupttal viszont azt csinálsz, amit csak akarsz. Erre az Atmega328p elfogadhatóan alkalmas, de nem az Arduino keretrendszerben.
Már mindenki más hozzászólt, csak a kérdező nem... :)
Nem gondoltam volna, hogy egy, az én általam csak felvetett kérdésből egyszer születik egy magyarázó videó, amiben gyönyörűen fel van építve és le van vezetve lépésről-lépésre mi, és miért van, ahogy az állapotgépek szerinti összefoglalás leírja. Köszönöm és ígérem, nem maradok "adósod"...
Természetesen az elkészült project-ben hiba nincs, csak a feltöltés után derült ki, hogy amit én nem említettem soha, hogyha viszont újra megnyomjuk gomb1-et, míg mielőtt letelne a beállított 16s, akkor relé1 ismételten meg tudjon húzni és elengedés után elenged és indul a 16s-os késletetett elengedés relé2-őn.
Gondolom itt egy "millis" függvény alkalmazása gomb1-en, megoldja a problémát?
Illetve gomb2 megnyomásakor használhatom továbbra is delay-t?
Vagy van más mód arra, hogy gomb2 megnyomásának lefutását ne tudja befolyásolni gomb1?
Meggyőztél, legyen a neve: 'are_you_sure_time', vagy inkább magyarosan: 'nyomvatartasi_ido'. Szerencsére a mai fejlesztő rendszerek szövegbeviteli felületének szövegrész cserélési képességei nagyon jók :)
Szóval nyitott a kérdés és lesz róla vagy jegyzet vagy video.
Az 50 ms egyébként egész jó érték, itt (ez egy sima mikrokapcsoló) gyakorlatilag 50 us (0,05 ms) lefut a prell, de van felvételem ennél csekély mértékben hosszab lefutásról is. Az ötlet egyébként nagyon jó, de ha ezeket is beleveszem (elmélet és gyakorlat szintjén is), akkor 1-2 órás videók lennének. :-D És ugye (elvileg) 5 perc a terv. :-D
Ja, és egy apró megjegyzés a következetességre: az areyousure „változónévként” nem túl beszédes. ;-) Mert pl. arra a kérdésre, hogy „Biztos vagy benne [hogy forrón kéred a búzasöröd]?” az 50 nem túl adekvát válasz. :-D
Csak egy apróság: nagyon klassz a film, de az Arduino elég gyors ahhoz, hogy sokszor tudjon 16 másodperces bekapcsolt relét eredményezni, szándékaink ellenére. Oka: a gomb prellezés kezelésének hiánya. Tehát valamilyen pergésmentesítés kezelést célszerű lehet alkalmazni. Ekkor viszont a prell megelőzésben alkalmazott késleltetés implicite a mintavételezési rács időzítésévé válik. (ha programozott és nem HW a megoldás)
Igaz, a filmbeli felvezetés és megoldás könnyebben átlátható és megérthető a fentiek nélkül (!).
1. Relét így nem kapcsolunk. Normális modul kell, mert hiába 5V-os a relé kapcsolófeszültsége, a felvett árama bőven több, mint amit a Nano kimenete elbírna. Megoldás: egyrészt rendes, galvanikusan leválasztott relét kell használni, másrészt a relé behúzó feszültségét lehetőleg külső áramforrásról kell megtápolni, ellenkező esetben nagyon gyorsan ki fogod nyírni a panelt.
2. A relé fordított logikára van bekötve, akkor lesz aktív, amikor a kimenet alacsony jelszinten van. Bajnak nem baj, a kódban kell figyelni erre (lásd film elejét).
3. A gombok így jók lennének, HA és amennyiben a kódban nem INPUT_PULLUP mód lenne generálva. Ez ugyanis a belső felhúzóellenállással a bemenet jelszintjét magasra húzza, te viszont egy 10k-s ellenállással lehúzod negatívba (illetve lényegében egy feszültségosztóval lebegteted valahol), és amikor megnyomod a gombot, akkor adsz rá +5V-ot. A videoban látható kód ennek pont az ellenkezője szerint működik. Ehhez a két ellenállást ke kell venni a gombok mellől, a gombok egyik pólusát a GND-re, a másik pólust az adott bemenetre kell kötni.
A többi jó, de ezzel a felállással fura lesz a kód (nem fog működni). A reléket cseréld ki egyelőre ledekre (bár most asszem eleve úgy van).