(Szennyvíz szivattyú működésének megfigyelése)
Tartalom:
- Szennyívszivattyú rendellenes működésének felfedezési lehetőségei
- Megtervezett monitorozó kapcsolás kipróbálása áramkör szimulátorban
- Szivattyú motoráramának figyelése olcsó áramváltóval, teljes galvanikus leválasztással
- Minimál működési animációk egy hétszegmenses LED kijelzőn
Az áramkör fejlesztését és megépítését azért kezdtem el, mert tönkrement a házunk átemelő szennyvíz szivattyúja. Nem vettük észre, hogy egy visszacsapó szelep eltömődése miatt a szennyvíz hálózatból visszafolyt a víz, és a szivattyú pár percenként újra és újra ürítette a tartályt. A folyamat kb. egy-két hónapig tartott. A villanyszámlán jelent meg az első árulkodó nyom (kb. duplájára nőtt a fogyasztás). Aztán a rengeteg indításól végképp megadta magát a motor, és elárasztott minket a visszafolyó szennyvíz. Az egész folyamatból semmit nem vettünk észre, mivel a szivattyú egy földalatti aknában üzemelt. Visszajelzés nem volt sehol arról, hogy éppen mikor jár a motor, egy nap hányszor indul el stb.. Pedig ha láttam volna, mi történik a föld alatt, a visszacsapó szelepbe beszorult ágdarab kipiszkálásával meg tudtam volna menteni a szivattyút. Az elfogyasztott felesleges energia is kb. 10.000-20.000Ft-ba került.
A ritkán (naponta néhány alkalommal) működő folyamatok megfigyelése egyébként is nehéz feladat. Ha egy gépnek normális esetben naponta egy-két alkalommal kell beindulnia, nagyon nehéz észre venni, ha ennél többször működik. Pedig a beindulások számának növekedése mindig valamilyen meghibásodásra, rendellenességre utal. Az én szennyvíz szivattyúm kb. 25.000Ft-os érték. Szerintem már ezt is érdemes „védeni” egy 2000Ftos áramkörrel!
Azt találtam ki, hogy az utolsó 24 óra indításszámát jelzem ki. Ennek a kijelzési módnak nagy előnye, hogy nem kell a rendszerbe óra. Dönthettem volna úgy is, hogy pl. az aktuális nap indításszámait jelzem ki, és éjfélkor nullázom az értéket, de ekkor órát kellet volna beépíteni. Lehetett volna az összes indításszámot kijelezni, akkor viszont több számjegy kijelzésére alkalmas eszközt (pl LCD, vagy több darab hétszegmenses kijelzőt) is kellett volna építeni az áramkörbe. Ha nem teszek be órát, csak a szumma indításszámot jelzem ki, az nem jó megoldás. Ki tudná megjegyezni, mennyi is volt tegnap a számláló állása. Így viszont az egész kütyü egy fiókból előkerült „hulladék” telefontöltővel kb. 2000Ft-ból elkészült! Egy kicsit azért lódítok, mert volt abban a fiókban némi nyáklemez, nyomógombok, és végül külön tápegységet is csináltam, mert nem telefontöltőm volt, csak egy 12V-os konnektorba dugható trafó. Mondjuk 3000Ft!
Az áramkör kapcsolási rajza:
A rajzot a SimulIDE nevű áramkör és Arduino szimulátor programmal készítettem. Ennek a programnak a működését megismerheted itt! Ha érdekel a részletes működés, akkor töltsd le magadnak a szimulátort, és töltsd be ezt az állományt: letöltés
Van azonban néhány tudnivaló ezzel a kapcsolási rajzzal kapcsolatban. Mivel ez egy szimulátor programmal készült, nem tartalmazza a tápegység rajzát. Ezt balra fent egy narancssárga kocka jelképezi, ide egy USB telefontöltőt, vagy bármilyen más 5V tápegység megoldást kell képzelni. Található a rajzon két potenciométer. Valójában csak egy van a megépített kapcsolásban, mert a „Motor.Á” jelű potencióméter csak a szimulátorban szerepel. A valóságban a vezérlő bemenetére egy áramváltó egyenirányított feszültségjelét kötöttem (lásd később), de mivel a szimulátorban azt nem tudtam megrajzolni, egy potival helyettesítettem. Így viszont ha virtuálisan kipróbálod a kapcsolást, ennek a potinak a tekergetése ugyanazt az eredményt éri el, mintha a szivattyú beindul, és egy feszültség jelet állít elő a hozzá vezető villanyvezetéken átfolyó áramból az áramváltó kapcsolás. A valós áramkörben a „Reset” gomb is sima nyomógomb, de mivel a szimulátorban az egérrel kattintva nyomom meg az indítógombot, és közben a nyomógombot is az egérrel kellene nyomva tartani, inkább egy előre bebillenthető kapcsolót raktam be a kapcsolásba. Részletesebb magyarázatok később! A hétszegmenses kijelző kivezetései és a vezérlő kivezetéseinek összeköttetésében nincs semmi logika. Egyszerűen csak így sikerült bedugdosni a drótokat, és ehhez igazítottam a programot. Később meg már nem volt kedvem átírni a programot, hogy sorban egymás után következő kivezetések kapcsolódjanak a kijelző sorban következő kivezetéseihez.
Az áramkör működése:
- Amikor a szivattyú beindul a a később ismertetett áramváltó feszültség jelét érzékeli a program méri a működési időt és eggyel növeli az indítások számlálóját.
- A szivattyú működése közben az alsó négy szegmens „forgó” mozgást szimulálva jelzi a működést (ez nem kell, csak látványosabb, ha az ismerősöknek dicsekedni akarok).
- Egy hétszegmenses kijelzőn jelzi az utolsó 24 óra indításainak számát. Az én esetemben az a normális, ha maximum 2-3-at látok. (átlagos víz használattal maximum kétszer háromszor kell ürítenie egy nap). Ha a szivattyú indítás száma ennél nagyobb, pl. 4, akkor már valami baj van. Ha az ürítések száma több mint 8, akkor a kijelzett 8-as számjegyet a program feltűnően villogtatja. Azért a 8-at villogtatom és nem a 9-et, mert szerintem a 8-as számjegy elegánsabb hibajelzésre. (Ez volt a marketing, valójában így sikerült, és nem írtam át a programot utólag, mikor észrevettem).
- Többször előfordult az a szivattyúnkkal, hogy a visszacsapó szelep „ideiglenesen” fennakadt. Ekkor a szivattyú többször is leürített. Aztán a szennyeződés átvergődött a rendszeren, és visszaállt a normális állapot, a visszacsapó szelep nem engedte vissza a szennyvizet, és nem kellett a továbbiakban a szivattyúnak sokszor ürítenie. Ha netán nem vennénk észre a villogó „8”-as jelzést és eltelik egy nap, megszűnik a villogó kijelzés, hiszen egy nap elteltével a régebbi indításokat „elfelejti” a rendszer. Engem megnyugtat (illetve ekkor szoktam benézni az aknába) ha az ilyen abnormális esetekről utólag is tudok, ezért a kijelző tizedespontja folyamatosan villog egy kijelző “túlcsordulás” után, ezzel memorizálja a sok szivattyú beindulást. A villogás bármelyik lekérdező nyomógomb megnyomásával megszűnik. Természetesen egy áramszünet hatására is eltűnik a jelzés.
- Figyeli a program a szivattyú túláramát is. Erre azért lehet szükség, mert ha a szivattyú daráló részébe beakad egy keményebb szennyeződés, vagy feltekeredik rá hajszál, madzag amit véletlenül a WC-ba dobtunk, akkor nehezebben forog a tengely, és megnő az áramfelvétel. Ekkor az áramváltó is nagyobb feszültséget állít elő. Ha ez a feszültség meghaladja a vezérlő másik analóg bemenetére kötött potméter feszültségét, akkor kigyullad a tizedespont és egy lekérdező nyomógomb megnyomásáig úgy is marad. Ha tehát azt látom, hogy világít a tizedespont, akkor érdemes kiszerelni a szivattyút és tisztogatni a daráló részét. Trutyis egy munka, de ez van. Egyébként enélkül is szétszedem évente, mert a szennyvíz akna aljából célszerszámokkal ki szoktam söprögetni illetve emelgetni a behullott szennyeződéseket. A szivattyú két téglán üzemel, hogy a kövek nehogy besodródjanak a daráló részbe, így kb. 5-7 cm helye van a leülepedett szennyeződésnek, ezt kell néha kitakarítani. Másik megoldás, hogy néhány évente venni kell egy új szivattyút, és akkor takarítani, amikor jó pénzért beszerelem az újat. Ennyire nem vagyok gazdag, évente trutyizok!
- Az áramkör üzembe helyezését követően az indításszámot és az összes működési időt eeprom-ban tárolja a program. Ezeknek az értékeknek a lekérdezésére két nyomógomb szolgál. Az egyiket lenyomva az egy darab hétszegmenses kijelzőn négy egymás utáni számjegy felvillantással kijelzi az indítás számot, a másik nyomógomb megnyomásával pedig az összesített szivattyú működési időt percekben. A maximális kijelezhető indítás szám 9999, a működési idő pedig 9999 perc vagyis 166 óra. Feltételezve, hogy normális esetben napi maximum 2 indítás fordul elő, ezek az értékek 13 év működést tesznek lehetővé gyári alapbeállítás, vagyis tároló törlés nélkül (nálunk a szivattyú kb. fél perc alatt ürít le).
- Található egy bemenet, melyen egy reset gomb segítségével gyári alapbeállítást, azaz számláló törlést lehet végezni. Erre az én estemben kb. 10 évente lesz szükség. A reset gombot a bekapcsolás közben kell nyomva tartani mindaddig, amíg a hétszegmenses kijelző tizedespontja kb. egy másodpercig villogni kezd. Később a program már nem vizsgálja a nyomógombot, véletlen megnyomás nem törli az adatokat. Illetve mégis figyeli a program a reset gombot, mert ha működés közben nyomom meg, az előzőekben leírt módon levillogtatja az áramváltó felől érkező feszültségjel értékét. A kapott számot milivoltban kell értelmezni. Kijelzés előtt a ADC-ből kapott számot szorozgatom egy kicsit, hogy volt-ban kapjam meg az eredményt. Ennek egyébként csak az áramkör bemérésekor volt szerepe, a reset gomb csak szétszedett állapotban érhető el.
- A szivattyú indításokat a program eeprom-ba összegzi. Az én esetemben az eeprom élettartama (100.000 írás) kb. 100 év élettartamot jósol, ezért írok minden szivattyú leállást követően. Azonban segítségül azoknak, akik gyakoribb folyamatot akarnak monitorozni, beépítettem egy algoritmust, ami csak minden 5. esetben írja ki az adatokat eeprom-ba (lehetne akár 100 is, bár ennek a vezérlő sram memóriája határt szab). Ez az üzemmód a programban egy konstans átállításával kapcsolható be (eepromvedelem=1). Ha ezt használjuk, akkor azonban az áramkört elemmel kell védeni az áramkimaradástól, különben az utolsó öt indítás adatai elvesznek, vagy el kell fogadni, hogy elvesznek.
- Van az áramkörnek még egy bemenete, amit a program folyamatosan figyel. Ha ezen LOW szintet talál, akkor a kijelzőn az indításszámot, és egy vészjelzést jelenít meg felváltva 2,4 másodperces ciklusokban. Miért pont 2.4 másodperc? Csak úgy!! A vészjelzés a három vízszintes szegmens egymást követő felvillantása. Esetemben van a szennyvíz tartályban egy vízszint jelző, ami akkor kapcsol be, ha a vízszint elér egy magasságot. Ez csak akkor történhet meg, ha a szivattyú nem tudja szennyvizet leüríteni, és a vízszint a normális magasság fölé emelkedik. Nálunk a vészjelzés észrevételére kb. egy nap áll rendelkezésre, ezt követően, már folyik a trutyi az udvaron.
A program felépítése és működése:
A program nagyon egyszerű, de kicsit nehezen követhető a működése, mert megoldásomban nem használtam delay() függvényt az időzítésekre. A szivattyú működését jelző bemenetet a program 1 másodpercenként figyeli. Ha a bemeneten LOW szintet talál, az jelzi, hogy a szivattyú éppen működik. Illetve mintát vesz az A1 analóg bemenetből, és ha itt nagyobb feszültséget talál, mint egy előre beállított érték, az a szivattyú működése, a nyomógomb csak szimulálja a szivattyút és a fejlesztéshez kellett! Amikor a reset gombbal alaphelyzetbe állítom az áramkört, 5 másodperc alatt 10 mintát vesz az áramváltó feszültségéből, és ennek az úgynevezett offset (nyugalmi) feszültségből, határozom meg az érzékelési küszöböt, amikortól a szivattyút működőnek tekintem. Sajnos az áramváltónak akkor is van kimenő feszültsége, amikor nem jár a szivattyú.
Természetesen delay() függvényt nem használhattam, mert összesen 4 bemenetet kell figyelni folyamatosan. Annyira lassúak a folyamatok, hogy nem okozott volna nagy hibát az időmérésben, indításszám számlálásban az sem, ha egyszerre csak egy folyamattal foglalkozik a program, de így szebb a megoldás. Ha jár a szivattyú, akkor is lehet indításszámot vagy működési időt lekérdezni, és a lekérdezések alatt is működhet a szivattyú figyelése, és a működési idő mérése.
A fő ciklus a nyomógomb lenyomásokat és állapotokat figyelgeti, és szükség esetén meghívja a megfelelő függvényeket.
A két legfontosabb függvény:
- inditas_szamalalo()
Három 10 elemű tömbben tárolja az utolsó 9 indítás adatait:
- Működési idő: bekapcsolva[]
- A bekapcsolások között eltelt időt: ido[]
- Segéd változó az eeprom kímélés céljából: tarolasjelzes[]
A 0. tömbelem az „ido” változóban a két indítás közötti időt tárolja, értéke másodpercenként nő eggyel. Ha a motor épp elindul, akkor az ido[0] változóba találjuk az utolsó bekapcsolás óta eltelt időt és elindítjuk a szivattyú működési idő mérését (bekapcs_ido). Amikor a szivattyú leáll, akkor a bekapcs_ido változó tartalmát (ami szintén másodpercekben tartalmazza a működési időt) beleírjuk a bekapcsolva[0] tömbelembe. Ezt követően minden tömbelemet átírunk az eggyel nagyobb indexű tömbelembe. Gyakorlatilag az értékek minden indításkor egyel feljebb lépnek a tömbökben. Ebben a mini adatbázisban tehát az ido nevű tömbünkben az egyes indítások közötti időt találjuk másodperces felbontásban. Amikor a függvény másodpercenként lefut, sorban összeadja (0 tömbindextől kezdve) az eltelt időket. Ha ezek együtt meghaladják a 24 órát (86400 másodpercet), akkor befejezzük az összegzést és az a tömbindex ahol éppen járunk, megadja az utolsó 24 óra indításainak számát. Ezt az inditas_db változóba frissíti a függvény minden lefutáskor.
a tarolasjelzes[] tömbbe minden 5. indításkor 1-et írunk és ha ez az „1” érték eléri az utolsó tömbelemet (tarolasjelzes[9]=1), akkor eepromba írjuk az adatokat. Persze csak akkor, ha az eeprom kímélés be van kapcsolva (#define eepromkimels 1). Ha az eeprom kímélés nincs bekapcsolva, akkor minden motor leállításkor írjuk az új adatokat az eeprom-ba. Az eeprom írás és olvasás okozott fejtörést, míg valaki a TavIr fórumban segített az EEPROMWritelong és EEPROMReadlong függvényekkel. A probléma az volt, hogy long változókat kell tárolni és kiolvasni. A tárolható működési idő másodperc alapon így elegendően hosszú lehet.
- lekerdezes()
Ez a függvény a két lekérdező nyomógomb megnyomásakor fut le. Kiolvassa az eeprom-ból az indításszámot vagy a működési időt, átalakítja a számértékeket 4 jegyű szöveges számértékké (pl.: „0123”), és a négy karakteres számjegyet sorban kijelzi a hétszegmenses kijelzőn. A setup() részben a szegmens[] tömbben tulajdon képen egy mini karaktergenerátort töltök fel, minden számjegynek és egyéb kijelzett jelzés állapotnak van egy 7 jegyből álló szegmens érték blokkja. A setup() részben ezt azt hiszem érthető módon kommenteztem. Mivel közös anódos a kijelzőm, a 0 érték jelzi a világító szegmenst.
Remélem a kommentek alapján megérthető a működés. Persze ez csak akkor kell, ha valamiért változtatni kell a programon. Pl. ha valakinek lényegesen gyorsabb folyamatot kell monitoroznia, akkor az időmérő tömb elemeit növelni kell. Lehet azonban úgy is gondolkodni, hogy pl. az utolsó egy óra indításszámát jelezzük ki. Ehhez csak a 86400 másodperc értékét kell 3600-ra csökkenteni. Teszteléskor én ezt az értéket 60-ra állítottam, és így „gyorsítottam” fel az időt. Vadul nyomkodtam a szivattyú működését jelző nyomógombot, és ezzel növeltem a kijelzett számértéket, miközben a program azokat az indításokat, melyek már több mint egy perce voltak sorban ejtette ki az összeszámolt indítás számból. Természetesen kipróbáltam 24 órás idővel is a tesztelési időszakban.
Külön kapcsolási rajzot nem készítettem, mert nincs ilyen programom. Annyira egyszerű a kapcsolás, hogy nincs is szükség rá. A programban a kommentekben leírtam, mit hová kell kapcsolni. Ha most kezdeném el az építést, akkor nem ATmega328P chip-et használnék, hanem Arduino nano-t. Ott meg a kivezetések számozása más mint a chip kivezetések számozása, így a kapcsolási rajz végképp értelmetlen. A fotókból azért némi segítség kapható.
#include <EEPROM.h> #define tombmeret 10 //mekkora legyen a ramban tárolt adaok mennyisége #define eepromkimeles 0 //ha értéke egy, akkor csak minde 5. indítás után tárolunk az eepromban, ha 0 akkor minden indításkor #define felejtes_ido 86100 //ennyi idon belüli szivattyú indítások számát jelezzük ki. 86100sec=24 óra byte hossz=0; long kijelzes=millis(); byte lekerdezes_fazis=0; //lekérdezést indítottak ha nagyoibb mint nulla. egyben a lekérdezés fázisait is jelzi byte lekerdezes_tipus=0; //darablekérdezés jelzésére char szamjegy_db[]={'0','0','0','0'}; byte szamjegy_db_num[]={0,0,0,0}; char szamjegy_ido[]={'0','0','0','0'}; byte l=0; byte motor_on=0; byte motor_on_state=0; byte szintjelzes=0; long s1=0; //eeprom-ból kiolvasottértékek átmeneti tárolása long s2=0; //eeprom-ból kiolvasottértékek átmeneti tárolása long s3=0; //eeprom-ból kiolvasottértékek átmeneti tárolása byte k=0; int inditas_db=0; int korrekcio=0; long ido_tmp=millis(); //a másodpercenkénti figyeléshez long ido_tmp2=millis(); //a 100msec-es figyeléshez long ido_tmp3=millis(); //a 100msec-es figyeléshez long ido_tmp4=millis(); //a 100msec-es figyeléshez long bekapcs_ido=0; //az aktuális szivattyú működés időtartama long ido[tombmeret]; //ebben mérjük a bekapcsolások között eltelt időt long bekapcsolva[tombmeret]; //az egyes bekapcsolások ideje (szivattyú működési idő byte tarolasjelzes[tombmeret]; //a tartalmában levo 1-es hatasara taroljuk az adatokat az epromban byte sw_elozo_allapot=LOW; //szivattyú működés előző ciklusban érzékelt állapota long o_ido=0; //tömb elemek összeadásakor használt változó int tombindex=0; byte villogas=0; byte veszjelzesmemo=0; long veszjelz_ido=millis(); byte veszjelz_tmp=0; byte motor_megy=LOW; //szivattyú működéseklor HIGH, ha nem működik, akkor LOW int aram_kuszob=0; //szivattyú áramküszöb értéke, mely felett működőnek tekintjük (áramváltó alap feszültsége+3+alapfesz/5) byte motor_tularam=LOW; //szivattyú tuláram esetén HIGH, alatta LOW, Bármilyen lekérdezés LOW-ba billenti byte szintjelzo_alapertek=0; //ha nincs vészjelzés, akkor LOW vagy HIGH értéket vesz fel. byte szintjelzo_on=0; //hétszegmenses kijlző kimenetek // szegmens betüjele: A, F, B, G, E, C , D //ATmega328chip kivezetés: 13, 14, 15, 16, 17, 18, 19 //Arduino kivezetés: 7, 8, 9, 10, 11, 12, 13 // - A Szegmensek: 1 - B,C // | | F B 2 - A,B,G,E,D // - G 3 - 1,3,4,6,7 // | | E C 4 - F,B,G,C // - D 5 - A,F,G,C,D // 6 - A,F,G,E,C,D // 7 - A,B,C // 8 - A,F,B,G,E,C,D // 9 - A,F,B,G,C,D // 0 - A,F,B,E,C,D // forgas1 - G // forgas2 - C // forgas3 - D // forgas4 - E // telijelzés1 - D // telijelzés2 - G // telijelzés3 - A // A F B G E C D byte szegmens[]= {0,0,0,1,0,0,0, //0, 0 1,1,0,1,1,0,1, //1, 7 0,1,0,0,0,1,0, //2, 14 0,1,0,0,1,0,0, //3, 21 1,0,0,0,1,0,1, //4, 28 0,0,1,0,1,0,0 , //5, 35 0,0,1,0,0,0,0, //6, 42 0,1,0,1,1,0,1, //7, 49 0,0,0,0,0,0,0, //8, 56 0,0,0,0,1,0,0, //9, 63 1,1,1,0,1,1,1, //f1, 70 1,1,1,1,1,0,1, //f2, 77 1,1,1,1,1,1,0, //f3, 84 1,1,1,1,0,1,1, //f3, 91 1,1,1,1,1,1,0, //s1, 98 1,1,1,0,1,1,1, //s2, 105 0,1,1,1,1,1,1, //s3, 112 1,1,1,1,1,1,1}; //ures, 119 byte pin_szegmens[] = {7, 8, 9, 10, 11, 12, 13}; // szegmens betüjele: A, F, B, G, E, C , D //chip kivezetés: 13, 14, 15, 16, 17, 18, 19 void setup() { //tömbök indulú értékének feltöltése for (byte i=0;i<5;i++) { ido[i]=0;bekapcsolva[i]=0;tarolasjelzes[i]=0;} tarolasjelzes[0]=1; pinMode(2,INPUT); //motor működés érzékelő bemenet //4. chip kivezetés pinMode(3,INPUT); //"teli" szintjelző érzékelő bemenet //5. chip kivezetés pinMode(4,INPUT); //indításszám lekérdezés gomb //6. chip kivezetés pinMode(5,INPUT); //működési idő lekérdezés gomb //11. chip kivezetés pinMode(6,OUTPUT); // kijelző tizedespont 12. chip kivezetés pinMode(7,OUTPUT); //13. chip kivezetés pinMode(8,OUTPUT); //14. chip kivezetés pinMode(9,OUTPUT); //15. chip kivezetés pinMode(10,OUTPUT); //16. chip kivezetés pinMode(11,OUTPUT); //17. chip kivezetés pinMode(12,OUTPUT); //18. chip kivezetés pinMode(13,OUTPUT); //19. chip kivezetés digitalWrite(6,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(9,HIGH); digitalWrite(10,HIGH); digitalWrite(11,HIGH); digitalWrite(12,HIGH); digitalWrite(13,HIGH); pinMode(0,INPUT); //2. chip kivezetés gyári alapbeállítás, ha lenyomjuk a gombot, törlődnek az eeprom tartalmak if (digitalRead(0)==LOW) { //eeprom törlés, gyári alapbeállítás EEPROM.write(0,0); EEPROM.write(1,0); EEPROM.write(2,0); EEPROM.write(3,0); EEPROM.write(4,0); EEPROM.write(5,0); EEPROM.write(6,0); EEPROM.write(7,0); EEPROM.write(9,digitalRead(3)); //szintjelző alapállapotának lekérdezése szintjelzo_alapertek=digitalRead(3); //szintjelző alapállapot változó feltöltése for (byte i=0;i<10;i++) { aram_kuszob=aram_kuszob+analogRead(A2); //összegezzük a 10 mérés eredményét delay(500); } aram_kuszob=aram_kuszob/10; //egyenirányitó átlagos nyugalmi offszet feszültségének számítása aram_kuszob=aram_kuszob+3+(aram_kuszob/5);//nyugalmi offszetnél kicsival nagyobb áramküszöb számítása EEPROM.write(8,aram_kuszob); //áramküszöb tárolása //tizedespont villogtatás, ami a gyári alapbeállítást jelzi digitalWrite(6,LOW); delay(200); digitalWrite(6,HIGH); delay(200); digitalWrite(6,LOW); delay(200); digitalWrite(6,HIGH); delay(200); digitalWrite(6,LOW); delay(200); digitalWrite(6,HIGH); } else { digitalWrite(6,LOW); delay(1000); digitalWrite(6,HIGH); aram_kuszob=EEPROM.read(8); //tárolt áramküszöb kiolvasása szintjelzo_alapertek=EEPROM.read(9); //tárolt szintjelző alapállapot kiolvasása } } void loop() { if (motor_tularam==HIGH) {digitalWrite(6,LOW);} else {digitalWrite(6,HIGH);} //lenyomták a db lekérdezést és éppen nem fut db vagy ido lekérdezés if (digitalRead(4)==LOW && lekerdezes_fazis==0) {lekerdezes_fazis=1;lekerdezes_tipus=1;motor_tularam=LOW;kijelzes=millis();} //lenyomták az ido lekérdezést és éppen nem fut db vagy ido lekérdezés if (digitalRead(5)==LOW && lekerdezes_fazis==0) {lekerdezes_fazis=1;lekerdezes_tipus=2;motor_tularam=LOW;kijelzes=millis();} //lenyomták az gyári alapbeállítás gombot és éppen nem fut db vagy ido lekérdezés if (digitalRead(0)==LOW && lekerdezes_fazis==0) {lekerdezes_fazis=1;lekerdezes_tipus=3;motor_tularam=LOW;kijelzes=millis();} //lenyomták a db lekérdezést és éppen nem fut db vagy ido lekérdezés if (lekerdezes_fazis>0 && millis()>kijelzes) {lekerdezes(lekerdezes_tipus);} //egy másodpercenként ellenőrizzuk, hogy megy e a motor és adminisztrálunk if (millis()>ido_tmp+1000) {inditas_szamlalo();ido_tmp=millis();} //1,2 másodpercre beállítjuk a vizszint vészjelzést ha bekapcsolt a vész vizszintjelző if (millis()>ido_tmp3+1200) {if (motor_on!=1) {szintjelzes=1;}} if (millis()>ido_tmp3+2400) { ido_tmp3=millis();szintjelzes=0;k=0;} //Szintjelző tárolt alapértéke alapján a vészjelzés detektálása szintjelzo_on=HIGH jelzi a magas folyadékszintet szintjelzo_on=LOW; if (szintjelzo_alapertek==LOW) {if (digitalRead(3)==HIGH) {szintjelzo_on=HIGH;}} else {if (digitalRead(3)==LOW) {szintjelzo_on=HIGH;}} //bekapcsolt a vész szintjelző kapcsoló, sorban villogtatjuk a függőleges pálcikákat 3 másodpercenként if (szintjelzes==1 && szintjelzo_on==HIGH && lekerdezes_fazis==0) { if (millis()>ido_tmp2+200) { for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[98+(k*7)+i]);} k++;if(k==3) {k=0;} ido_tmp2=millis(); } } //éppen működik a motor, sorban körbe villogtajuk az alsó 4 szegmenst if (motor_on==1 && szintjelzes==0 && lekerdezes_fazis==0) { if (millis()>ido_tmp2+200) { //motor működik for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[70+(motor_on_state*7)+i]);} motor_on_state++;if (motor_on_state==4) { motor_on_state=0;} ido_tmp2=millis(); } } //sem a motor nem működik, sem vész vizszint kijelzés nincs //kijelezzük az utolsó 24 óra indításainak számát if (motor_on==0 && szintjelzes==0 && lekerdezes_fazis==0) { if (millis()>ido_tmp2+200) { if (inditas_db==8) {villogas++;} else {villogas=1;} if (villogas==2) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[119+i]);}} if (villogas==1) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[inditas_db*7+i]);}} // for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[inditas_db*7+i]);} if (villogas==2){villogas=0;} ido_tmp2=millis(); } } } void lekerdezes(byte lek_tip) { lekerdezes_fazis++; veszjelzesmemo=0; if (lekerdezes_fazis==11) {lekerdezes_fazis=0;} //10.fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==10) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[119+i]);} kijelzes=kijelzes+1000;} //9.fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==9) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[szamjegy_db_num[3]+i]);}kijelzes=kijelzes+600;} //8.fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==8) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[119+i]);} kijelzes=kijelzes+300;} //7.fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==7) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[szamjegy_db_num[2]+i]);}kijelzes=kijelzes+600;} //6. fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==6) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[119+i]);} kijelzes=kijelzes+300;} //5. fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==5) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[szamjegy_db_num[1]+i]);}kijelzes=kijelzes+600;} //4. fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==4) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[119+i]);} kijelzes=kijelzes+300;} //3. fazis kikapcsoljuk a szegmenseket if (lekerdezes_fazis==3) {for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[szamjegy_db_num[0]+i]);}kijelzes=kijelzes+600;} //első fázis, kiolvassuk az értéket és előkészítjük a megjelenítés változóit if (lekerdezes_fazis==2) { for (byte i=0;i<7;i++) {digitalWrite(pin_szegmens[i],szegmens[119+i]);} kijelzes=kijelzes+1000; o_ido=0; l=0; if (eepromkimeles==1) { for (byte i=0;i<10;i++) { if (bekapcsolva[i]>0) {o_ido=o_ido+bekapcsolva[i];l++;} } } if (lekerdezes_tipus==1) {s2=EEPROMReadlong(4);s2=s2+l;} if (lekerdezes_tipus==2) {s2=EEPROMReadlong(0);s2=(s2+o_ido)/60;} if (lekerdezes_tipus==3) {s2=analogRead(A2);s2=s2*488;s2=s2/100;} char_konv(s2); for (byte i=0;i<4;i++) { if (szamjegy_db[i]=='0'){szamjegy_db_num[i]=0;} if (szamjegy_db[i]=='1'){szamjegy_db_num[i]=7;} if (szamjegy_db[i]=='2'){szamjegy_db_num[i]=14;} if (szamjegy_db[i]=='3'){szamjegy_db_num[i]=21;} if (szamjegy_db[i]=='4'){szamjegy_db_num[i]=28;} if (szamjegy_db[i]=='5'){szamjegy_db_num[i]=35;} if (szamjegy_db[i]=='6'){szamjegy_db_num[i]=42;} if (szamjegy_db[i]=='7'){szamjegy_db_num[i]=49;} if (szamjegy_db[i]=='8'){szamjegy_db_num[i]=56;} if (szamjegy_db[i]=='9'){szamjegy_db_num[i]=63;} } } } void inditas_szamlalo() { //idő számlálók növelése. Másodperc alapon mérünk időt bekapcs_ido++;ido_tmp=millis(); ido[0]=ido[0]+1; o_ido=0; s3=0; // sorban összeadjuk a tömbben tárolt időt, ha elértük a 24 órát (86400 másodperc), akkor megállunk //az utolsó 24 óra szivattyú indításainak számára vagyunk kíváncsiak while (o_ido<felejtes_ido && s3<tombmeret-1 && ido[s3]!=0) { o_ido=o_ido+ido[s3]; s3++; } inditas_db=s3-1; if (inditas_db==8) {veszjelzesmemo=1;} if (tarolasjelzes[tombmeret-1]==1 && eepromkimeles==1) //tarolásjelzés, tehát az utolsó 5 adatot összgezni és tárolni kell //de csak akkor, ha az eeprom kimélés be van kapcsolva { //Összeadjuk a tömbben tárolt bekapcsolási időket, és közben töröljük az összeadottakat //a törlés csak a működés nyomnkövethetősége miatt lett beépítve o_ido=0; for (byte j=0;j<5;j++) { o_ido=o_ido+bekapcsolva[tombmeret-j-1];bekapcsolva[tombmeret-j-1]=0;} //osszes szivattyú működési idő kiolvasása az eeprom-ból és hozzáadjuk az utóbbi tárolt bekapcsolási időket s1=EEPROMReadlong(0); s1=s1+o_ido; //Összes eddigi indításszám kiolvasása eeprom-ból és hozzáadjuk az utóbbi tárolt indítás számot s2=EEPROMReadlong(4); EEPROMWritelong(0,s1); EEPROMWritelong(4,s2+5); //értékek írása az eeprom-ba tombindex=0; tarolasjelzes[tombmeret-6]=1; tarolasjelzes[tombmeret-1]=0; } //if vége motor_lekerdezes(); //a szivattyú indítás felfutó éle, tároljuk a tömbb 0-as indexén az utolsó indítás óta //eltelt időt és tároljuk ennek változóját, töröljuk a bekapcsolási idő változóját if (motor_megy && !sw_elozo_allapot) { bekapcs_ido=0;motor_on=1;} //szivattyú kikapcsolása (lefutó él). Minden értéket lejjebb másolunk a tömbben és //tároljuk a bekapcsolási idő számlálást if (!motor_megy && sw_elozo_allapot) { bekapcsolva[0]=bekapcs_ido; motor_on=0; for (byte j=tombmeret-1;j>0;j--) { bekapcsolva[j]=bekapcsolva[j-1]; ido[j]=ido[j-1]; tarolasjelzes[j]=tarolasjelzes[j-1]; } bekapcsolva[0]=0;ido[0]=0;tarolasjelzes[0]=0; if (eepromkimeles==0) //eeprom kimélés kikapcsolva, így minden motor működés után beírjuk az adatokat az eeprom-ba { //Összes eddigi működési idő kiolvasása eeprom-ból és hozzáadjuk a legutóbbi működési időt s1=EEPROMReadlong(0); s1=s1+bekapcs_ido; EEPROMWritelong(0,s1); //Összes eddigi indításszám kiolvasása eeprom-ból és hozzáadunk egyet s2=EEPROMReadlong(4); EEPROMWritelong(4,s2+1); //értékek írása az eeprom-ba } } sw_elozo_allapot=motor_megy; //fel és lefutó él érzékeléséhez } //Ez a funkció kiír egy 4 byte (32bit) long változót az eeprom-ba void EEPROMWritelong(int address, long value) { //szétszedjük byte-okra a long-ot byte four = (value & 0xFF); byte three = ((value >> 8) & 0xFF); byte two = ((value >> 16) & 0xFF); byte one = ((value >> 24) & 0xFF); //A 4 byte-os adat epromba �r�sa EEPROM.write(address, four); EEPROM.write(address + 1, three); EEPROM.write(address + 2, two); EEPROM.write(address + 3, one); } //Ez a funkció visszaolvas 4 byte (32bit) long változót az eeprom-ból long EEPROMReadlong(long address) { //4 bytes olvasása az eeprom-ból. long four = EEPROM.read(address); long three = EEPROM.read(address + 1); long two = EEPROM.read(address + 2); long one = EEPROM.read(address + 3); //4 byte long változóvá alakítása return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF); } void char_konv(int szam) { String konv_string=String(szam); hossz=konv_string.length(); for (byte j=0;j<4;j++) {szamjegy_db[j]='0';} for (byte i=0;i<hossz;i++) {szamjegy_db[4-hossz+i]=konv_string.charAt(i);} } void motor_lekerdezes() { if (!digitalRead(2) || analogRead(A2)>aram_kuszob) {motor_megy=HIGH;} else {motor_megy=LOW;} if (analogRead(A2)>analogRead(A1)) {motor_tularam=HIGH;} }
Fontos lehet még, hogyan is figyeltem a szivattyú működését. A szivattyúnak egy beépített vízszint kapcsolója van. Ha magas a vízszint, akkor bekapcsol, ha lecsökkent ürítéskor a vízszint, akkor meg kikapcsol. Az egész egy levegővel töltött műanyag buborék, ami úszik a vízen (szaron), és ki be kapcsolgatja a szivattyút! Valamilyen módon meg kellett állapítani, hogy a szivattyú éppen energiát vesz fel a rendszerből Fontos szempont még az érintésvédelem, hiszen egy 230V-os szivattyút nem szerencsés semmilyen módon összekötni az Arduino-val. Akkor, amikor készítettem ezt a kütyüt, még nem tudtam, hogy kapható ez:
Forrás: https://www.aliexpress.com/item/32950949653.html?spm=a2g0s.9042311.0.0.27424c4d9KXUGZ
Ez egy olyan szerkezet, aminek a fekete színű tekercsének a belső nyílásán (nem látszik a képen), át kell vezetni a szivattyú vagy más villamos gép egyik vezetékét. Csak az egyiket, és nem a védőföldet. Az a kis fekete tekercs transzformátorként működik, kicsi feszültség indukálódik benne, amikor a szivattyú működik, amit az elektronika felerősít, és ha egy beállított értéknél nagyobb a feszültség meghúz a relé. Ezt ugyan túláram jelzésre találták ki, de ha elegendően feltekerjük a potméterrel az érzékenységet, akkor folyamatosan meghúzva tartja a relét a szivattyú működés közben. Már csak a relét kell bekötni az ATmega megfelelő bemenetére mintha egy nyomógomb lenne, és megtörtént a leválasztásos működés jelzés.
Én azonban akkor még nem tudtam, hogy ez készen kapható, és a Hobbielektronika weboldal fórumán valakitől megkaptam ezt a kapcsolást:
Ez lényegében ugyanaz, mint a kész áramkör. A tekercsben keletkező feszültséget egyenirányítani kell, és az Arduino analóg bemenetén már lehet is mérni a feszültséget. A D1 diódára azért van szükség, mert 0,7V-al megemeli a tekercsben indukálódott áramból R1 ellenálláson keletkező feszültséget, pont annyival amekkora a D2 nyitófeszültsége. Így az egyenirányító már 0V-tól kezdve “egyenirányít”. Hogy biztosan ne legyen 5V-nál magasabb a feszültség a tekercs után, én még betettem egy 4,7V-os zener diódát védelemnek, ez nincs a rajzon. Az egész áramkör a vezérlővel együtt így néz ki:
A tekercs áramérzékelő néven bármelyik trafikban kapható (trafik alatt elektronikai boltot értek pl. Lomex). Kb 1000 menetes kell legyen a tekercs, ekkor ha átvezetjük a szivattyú egyik vezetékét a lukon, a szivattyú 5A-es árama néhány volt feszültséget fog előállítani a R1 100 ohm-os terhelő ellenálláson. Egyszerű kiszámolni. A tekercsben (mert ez egy áramváltó valójában) 5A/1000=5mA áram fog folyni. Ez 100 ohm ellenálláson 0,5V feszültséget csinál. Már ez is bőven elég, de ha mégis kevés lenne (mondjuk nem szivattyú és kisebb az áramfelvétele) akkor fűzzük át a lyukon a vezetéket kétszer, vagy háromszor is. A feszültség 2-3-szor nagyobb lesz!
Az áramkörre beépítettem a teszteléshez nyomógombokat. Ezek simán párhuzamosan kapcsolódtak azokkal a nyomógombokkal, amiket a készülék dobozára szereltem. A nyomógombok vezetékeit csatlakozókkal dugtam a panelre, hogy az egész szétszedhető legyen. Csináltam RESET gombot is, ezzel lehet törölni az eeprom-ban tárolt adatokat, ha bekapcsoláskor nyomva tartom. A kijelzőt beforrasztottam, ahhoz nem volt csatlakozóm. A potméterrel a túláram küszöböt lehet beállítani. Ha kiugróan magas áramot vesz fel a motor, akkor kigyullad a kijelzőn a tizedespont. A tápegység 5V feszültséget állít elő egy 7805 táp IC-vel. A kimenetére egy led-et is beforrasztottam, lássam ha áram alatt van a szerkezet. A bal oldalon alul látható piros-fekete vezeték az áramérzékelő vezetéke. A bekötésnél látható a két dióda és a szükséges kondik ellenállások. Az ATmega328 chip közelében van a 4,7V-os zener dióda, ami az esetleges túl nagy jelfeszültségektől védi a chip-et!