duminică, 22 aprilie 2012

Panou Termic Solar DIY - Partea III (Software)

Comanda pompei - partea software

În acest articol voi prezenta în detaliu algoritmul din spatele circuitului de comandă şi realizarea programului software.
O să încep prin a enumera cerinţele iniţiale:
  • Să măsoare şi să afişeze temperaturile din panou şi din bazin.
  • Să ofere posibilitatea reglării temperaturii de prag pentru panou şi a diferenţei de temperatură dintre panou şi bazin.
  • Să comande releul ce alimentează pompa atunci când temperatura din panou e mai mare decât temperatura de prag şi mai mare decât temperatura din bazin.
  • Să permită controlul atât automat cât şi manual al pompei.
Pe lângă aceste cerinţe iniţiale s-au mai adăugat:
  • Afişarea orei în format [oră : minute].
  • Afişarea datei în format [zi / lună / an].
  • Reglarea orei şi a datei.
  • Salvarea temperaturii minime şi maxime din panou, alături de oră şi dată.
  • Salvarea datelor şi a setărilor în cazul penelor de curent.
  • Indicator  luminos pentru avarie şi afişarea unui mesaj de eroare.
  • Controlul pompei cu histereză.
În ochii unui programator cerinţele astea se transformă în următoarele funcţionalităţi:
  1. Controlul ecranului cu actualizarea ciclică a datelor afişate.
  2. Maşină de stări internă pentru meniul afişat. 
  3. Scanarea ciclică a tastaturii.
  4. Monitorizarea temperaturii şi comunicarea prin OWP cu senzorii. 
  5. Actualizarea ore şi a datei.
  6. Monitorizarea tensiunii de 12V şi detectarea unei căderi de tensiune
  7. Scrierea şi citirea datelor în şi din EEPROM, cu validare prin CRC.
  8. Detectarea şi administrarea erorilor.
  9. Controlul releului pentru pompă.
Cu alte cuvinte programul trebuie să permită citirea şi procesarea informaţiilor de la senzori în timp ce ceasul merge şi utilizatorul manipulează tastatura, respectiv manipulează datele afişate pe ecran. Ar trebui ca microcontroller-ul să facă aparent mai multe lucruri în paralel. Microprocesorul folosit de mine poate executa instrucţiuni doar secvenţial. Asta înseamnă că a trebuit să găsesc o metodă de a împărţi şi de a amesteca operaţiile pe care trebuie să le execute controller-ul astfel încât să dea impresia că face mai multe lucruri în paralel.
Ce înseamnă execuţia de operaţii în paralel?
O să încep cu un exemplu. Să zicem că avem un senzor de temperatură DS18S20 şi vrem să afişăm temperatura pe un LCD, dar vrem ca temperatura afişată să pâlpâie de 2 ori pe secundă. Pentru a putea face asta trebuie să reactualizăm textul afişat pe ecran tot la 250 ms. Mai exact, va trebui făcută secvenţa următoare:
  1. Afişez textul (ce conţine temperatura)
  2. Aştept 250 ms
  3. Şterg textul (afişez " " pe tot ecranul)
  4. Aştept 250 ms
  5. Afişez din nou textul
  6. Aştept 250 ms
  7. Şterg din nou textul
  8. Aştept 250 ms
  9. Sar înapoi la pasul 1
Dacă adunăm timpul de aşteptare vom obţine exact o secundă (250 ms + 250 ms + 250 ms + 250 ms = 1 sec), iar în acea secundă textul a fost afişat de două ori, exact cum am vrut.
Comunicarea cu senzorul DS18S20 se face prin protocolul 1Wire, şi presupune transmiterea, respectiv recepţia unui număr de biţi, iar timpul de conversie pentru senzorul DS18S20 e de aproximativ 700 ms. Astfel vom avea temperatura actualizată tot la 700 ms şi ceva. Problem care trebuie rezolvată în acest moment e cum putem face transmiterea comenzilor pentru ecran, în aceelaşi timp cu transmiterea comenzilor pentru senzor şi respectiv recepţia datelor de la senzor? Una din soluţii e aceea de a folosi o maşină de stări.
Ce este o maşină de stări?
Eu aş zice că e un mecanism care controlează ordinea în care se execută o colecţie de stări. Folosirea într-o funcţie a unei maşini de stări presupune structurarea funcţiei respective în stări. Fiecare stare trebuie să reprezinte o anumită secvenţă de cod din acea funcţie. La fiecare apel al funcţiei, se va executa secvenţa de cod coresunzătoare stării active. Astfel, pentru a finaliza execuţia întregii funcţii, e nevoie de apelarea repetată a acelei funcţii.  După ce maşina de stări a terminat de executat toate stările, orice alt apel către funcţia respectivă va fi ignorat, până la resetarea maşinii de stări. Resetarea maşinii de stări presupune înlocuirea stării curente cu starea iniţială. Ideal ar fi ca fiecare secvenţă de cod ataşată unei stări să fie scurtă şi utilă.
Ei, dacă funcţia care desenează întreg ecranul ar conţine o astfel de maşină de stări, atunci funcţia ar putea afişa câte un caracter pe ecran la fiecare apel. Pentru a desena întreg ecranul LCD 2x16, va fi nevoie de 32 de apeluri.
În mod similar putem avea o maşină de stări pentru controlul senzorului. Astfel la fiecare apel al acelei funcţiei se transmite sau se recepţionează câte un bit pe protocolul 1Wire.
Dacă vom apela cele două funcţii odată la o milisecundă, atunci, după aproximativ 32 ms vom avea întreg ecranul scris, iar pe protocolul 1Wire vor fi 4 bytes transmişi sau recepţionaţi (32 biţi / 8 = 4 bytes).
În cazul citirii senzorului putem verifica la fiecare apel al funcţiei dacă s-au recepţionat toate datele, caz în care putem introduce noua temperatură obţinută în textul ce urmează să fie afişat. Tot atunci putem reseta maşina de stări astfel ca să se înceapă o nouă conversie.
În continuare, putem ca tot la 250 ms să actualizam textul ce urmează să fie afişat pe ecran. Fie folosim textul curent, fie folosim caracterul " " pentru a şterge întreg ercanul. Tot atunci putem reseta maşina de stări a funcţiei ce scrie ecranul. Obţinem astfel actualizarea ecranului tot la 250 ms (pâlpâitul) şi citirea temperaturii.
TEOS
Pentru a realiza toate astea cât mai simpu, şi pentru a şi învăţa câte ceva, mi-am propus să fac un pseudo sistem de operare. Nu e un sistem de operare în adevăratul sens al cuvântului, ci e mai degrabă un planificator de operaţii. Oricum, eu l-am numit TEOS, adică Triggered Event Operating System. În traducere asta înseamnă Sistem de operare bazat pe evenimente declanşate.
Ce înseamnă un event (eveniment)?
Termenul l-am preluat din programarea orientată pe obiecte, unde un eveniment reprezintă, printre altele şi o schimbare a stării sistemului. De exemplu, mişcarea mouse-ului, apăsarea unei taste, selectarea unei ferestre, etc.
În cazul de faţă, sistemul de operare TEOS va oferi posibilitatea creării unui set de evenimente cu diferite moduri de declanşare (triggers). Ca să dau câteva exemple:
Evenimentul 1 va avea ca şi declanşator expirarea timer-ului de 10 ms. Asta înseamnă că la fiecare 10 ms acest eveniment va deveni activ.
Evenimentul 2 va deveni activ când se va apăsa o tastă.
Evenimentul 3 va deveni activ dacă timp de 1 minut nici o tastă nu s-a apăsat.
Şi aşa mai departe...
Ce înseamnă că un eveniment e activ?
Pe lângă posibilitatea de a executa o operaţie (sau funcţie) printr-un apel către ea, acest sistem de operare oferă posibilitatea de a ataşa funcţiei dorite un eveniment, legând astfel execuţia funcţiei respective de activarea evenimentului ales. Mergând pe aceeaşi idee, putem avea mai multe funcţii care să fie legate de aceelaşi eveniment. Astfel, de fiecare dată când acel eveniment se va activa, se vor executa toate funcţile care sunt ataşate evenimentului respectiv.
Ce evenimente am ales să folosesc?
Deocamdată le voi enumera doar, urmând ca în continuare să vin cu explicaţii mai amănunţite legate de alegerea acestor evenimente.
Pentru programul care face controlul pompei şi monitorizarea temperaturilor am folosit 6 evenimente:
  1. Event1ms - eveniment care devine activ o dată o milisecundă
  2. Event10ms - eveniment care devine activ o dată la 10 milisecunde
  3. Event200ms - eveniment care devine activ o dată la 200 milisecunde
  4. Event1min - eveniment care devine activ o dată la un minut
  5. EventKeyPressed - eveniment care devine activ când s-a apăsat orice tastă
  6. EventKeyTimeout - eveniment care devine activ dacă timp aproximativ de 1 minut nu s-a apăsat nici o tastă
Fiecare din evenimentele de mai sus va avea una sau mai multe funcţii ataşate. Fiecare funcţie face parte din câte un modul cu un rol anume în funcţionarea programului.

O parte din evenimentele alese sunt ciclice pentru că se activează cu regularitate tot la 1 ms, sau 10 ms, etc. Activarea unui eveniment se face de către declanşatorul ataşat evenimentului (Trigger). De exemplu, pentru evenimentul de 200 ms, trigger-ul este un timer ce expiră tot la 200ms. Tot atunci timer-ul reporneşte, realizând astfel repetarea activării evenimentului după încă 200 ms. În mod similar se activează celelalte evenimente ciclice. În imaginea de mai jos se poate observa felul în care evenimentele ciclice (1 ms, 10 ms, 200 ms şi 1 min) se activează:

Evenimentul "Any key" este aciclic, deoarece trigger-ul lui depinde de momentul în care o tastă a fost apăsată.
Evenimentul "Key timeout" este ciclic, dar nu se activează întotdeauna cu regularitate. În mod normal evenimentul devine activ dacă timp de aproximativ 1 minut nu s-a apăsat nici o tastă. Astfel, în cazul în care nici o tastă nu este apăsată, evenimentul va fi activat tot la 1 minut, deci trigger-ul lui este un timer ce expiră la 1 minut. În schimb de fiecare dată când o tastă a fost apăsată, timerul va fi repornit, întârziind astfel expirarea lui, şi deci activarea evenimentului. Cu alte cuvinte, dacă tot la 59 de secunde apăsăm o tastă, evenimentul nu se va activa niciodată.
Modulele folosite
Următoarele module au fost necesare pentru realizarea acestui program:
  • CRC - Calculează un CRC pe 8 biţi bazat pe "SAU Exclusiv"
  • DELAY - Permite crearea de pauze şi permite întârzieri scurte în execuţia unei funcţii
  • DISPLAY - Permite manipularea datelor ce urmează să fie afişate pe ecran
  • ERROR - Gestionează erorile care pot apărea
  • HMDY - controleaza ora şi data
  • IEP - Permite accesul EEPROM-ului intern
  • KEYB - Scanează tastatura şi reţine starea fiecărei taste
  • LCD - Permite controlul ecranului
  • MAIN - modulul central, unde vine făcut primul apel de funcţie
  • OWP - Permite transmisia şi recepţia datelor prin protocolul 1-Wire
  • PUMP - Controlează şi reţine starea releului
  • SSM - Gestionează maşina de stări sistemului
  • STRING - Manipulează şiruri de caractere
  • TEOS - Controlează activarea evenimentelor
  • TEXT - Conţine o parte din textele afişate pe ecran
  • TIM - Manipulează timerele software
  • TMON - Monitorizează temperaturile şi decide pornirea sau oprirea pompei
  • TSENS - Controlează senzorul de temperatură
  • VMON - Monitorizează tensiunea de 12V
Toate aceste module au fost concepute şi scrise de mine de la zero pentru a mă asigura că vor fi compatibile cu pseudo-sistemul de operare TEOS.
O parte din modulele enumerate mai sus sunt scrise intenţionat înclinat, pentru a marca modulele care au implementate maşini de stări. Cu ajutorul acestor module am realizat toate funcţionalităţile cerute.
Dar să începem cu prima funcţionalitate.
1. Controlul ecranului cu actualizarea ciclică a datelor afişate
Ecranul folosit e un LCD (Liquid Crystal Display = Ecran cu cristale lichide) RC1602D, cu 2 linii şi 16 coloane. Poate fi controlat prin 4 linii de comandă şi 8 sau 4 linii de date. Cele 4 linii de comandă sunt:
  • Vo - Reglajul contrastului (semnal analogic)
  • RS - linia Register select (semnal digital)
  • R/W - linia de Read/Write (semnal digital)
  • E - linia de Enable (semnal digital)
Controlând aceste 4 linii putem comunica cu microcontroler-ul intern al LCD-ului şi putem afişa textul dorit pe ecran. Modulul LCD se ocupă cu iniţializarea şi afişarea datelor pe ecran. Tot ceea ce face acest modul e să ia datele ce trebuie afişate de la o anumită adresă din memorie şi să le afişeze pe ecran. Maşina de stări a modulului LCD e legată de evnimentul de 1 ms, putând astfel afişa pe ecran câte un nou caracter aproximativ o data la fiecare o milisecundă. După aproximativ 32 de milisecunde, modulul a rescris întreg ecranul şi poate intra în stare de aşteptare. Din această stare de aşteptare va ieşi în cazul în care un alt modul va cere rescrierea ecranului.
Modulul TEOS va cere o dată la 200 ms reactualizarea (refresh-ul) ecranului. Astfel, ecranul va fi redesenat de aproximativ 5 ori pe secundă. Motivul pentru care am ales frecvenţa asta de rescriere a ecranului e pentru a putea realiza pâlpâitul textului afişat, în cazul în care o anumită valoare trebuie modificată de către utilizator.
2. Maşină de stări internă pentru meniul afişat
Conţinutul ecranului este compus dintr-o parte statică (ce nu se schimbă) şi o parte dinamică (care se poate schimba). Partea statică depinde de starea în care se află modului SSM, iar partea dinamică este controlată de modulul DISPLAY.
Starea modului SSM se poate schimba la apăsarea unei taste, lucru care poate determina schimbarea conţinutului ecranului, adică schimbarea adresei de la care modulul LCD preia datele ce vor fi trimise la ecran.
Pe de altă parte, conţinutul dinamic al ecranului e controlat de funcţia care face reactualizarea ecranului o dată la 200ms. Această funcţie va apela modulul DISPLAY pentru a modifica anumite porţiuni ale ecranului. De exemplu, în cazul afişării temperaturilor sau a orei, aceste valori vor trebui reactualizate pentru că se pot modifica oricând.
 În imaginea de mai sus se pot vedea o parte din stările modului SSM alături de conţinutul ecranului asociat fiecărei stări. Toate locurile ocupate de caracterul "-" reprezintă conţinutul dinamic al ecranului, care va fi modificat la apelul funcţiei de refresh cu ajutorul modului DISPLAY.
3. Scanarea ciclică a tastaturii.
Tastatura este citită de către KEYB. Acest modul scanează tot la 10 ms fiecare tastă şi reţine starea ei. Astfel o tastă poate trece prin următoarele stări:
Trecerea de la o stare la alta în funcţie de următoarele tranziţii:
T1 - la prima citire pinul este "0" logic
T2 - la a doua citire pinul este "1" logic (eroare de citire)
T3 - la a doua citire pinul este "0" logic (butonul a fost apăsat)
T4 - pinul este citit ca "1" logic
T5 - repetând citirea, pinul este "0" logic (eroare de citire)
T6 - repetând citirea, pinul este "1" logic (btonul a fost lăsat)
T7 - funcţia butonului a fost procesată, stare se resetează
Cele două stări "aparent lăsată" şi "aparent apăsată" au fost introduse pentru a filtra eventualele semnale parazite ce pot apărea. Trecerea de la starea "lăsată" la starea "neapăsată" se face doar după procesarea tastei, respectiv activarea evenimentului care depinde de apăsarea unei taste.
De fiecare dată când o tastă trece în starea "Lăsată", evenimentul AnyKey devine activ. De activarea acestui eveniment este legată maşina de stări a modului SSM, respectiv conţinutul textului afişat.
În cazul în care SSM se află în starea S0, el poate trece în starea S1 dacă tasta "Enter" a fost apăsată. Din S1 poate trece în S2 dacă fie tasta "+" sau "-" a fost apăsată. Apăsând tasta "Escape" se revine în starea S0.
Din starea S1 se poate trece în următoarele stări apăsând tasta "Enter":
Pentru starea S11, următoarele tranziţii sunt posible:
Din starea S12 se poate ajunge în următoarele stări:
S2 poate trece în una din următoarele stări:
Din starea S21 se poate ajnge următoarele stări:

În reprezentările de mai sus am omis să menţionez o serie de stări folosite pentru modificarea unor parametri interni ai sistemului, cum ar fi:
S1111 - stare folosită pentru modificarea Temperaturii de prag a panoului (Tp)
S1121 - modificarea Diferenţei de temperatură dintre Tp şi Tb (DeltaT)
S1131 - modificarea numărului de conversii înainte de comanda pompei
S1211 - modificarea orei
S1212 - modificarea minutului
S1221 - modificarea zilei
S1222 - modificarea lunii
S1223 - modificarea anului
S131 - controlul pompei
La aceste stări se ajunge cu ajutorul tastei "Enter", iar folosindu-se tastele "+" şi "-" se pot modifica valorile pe care le reprezintă.
 4. Monitorizarea temperaturii şi comunicarea prin OWP cu senzorii. 
Partea de citire şi monitorizare a temperaturilor este realizată de mai multe module structurate pe nivele.
4.1 OWP şi DELAY
Nivelul cel mai de jos e reprezentat de modulul OWP, care transmite şi recepţionează date date prin protocolul 1-Wire. Dat fiind că protocolul 1-Wire are o serie de cerinţe stricte legate de durata impulsurilor, momentul când portul de comunicare devine intrare sau ieşire, etc, m-am folosit şi de modulul DELAY. Acest modul permite crearea de pauze de lungime precisă de ordinul microsecundelor. Mai mult, acest modul permite şi întârzierea execuţiei unei funcţii cu un anumit număr de microsecunde. Asta este realizat prin salvarea pointer-ului către funcţia ce trebuie executată şi chemarea acelei funcţii în interiorul intreruperii generate la expirarea perioadei de pauză. Astfel funcţia ce trebuie întârziată se va executa cu întârzierea dorită, iar în timpul acelei întârzieri, microcontroller-ul poate executa altceva.
O funcţionalitate importantă a modului OWP este aceea că permite calcularea unui CRC pe toate datele primite, conform cu polinomul: CRC = X^8 + X^5 + X^4 + 1.
Dat fiind că partea de iniţializare a comunicării presupune recepţionarea unui impuls de prezenţă de la senzor, modulul OWP poate determina cu aproximaţie o serie de probleme care pot să apară:
  • dacă linia de comunicare rămâne în "1" logic, fără să apară impulsul de prezenţă, atunci fie cablul este rupt, fie senzorul lipseşte, fie avem un scurt la plus.
  • dacă linia de comunicare rămâne pe "0" logic, după iniţializare, atunci avem un scurt la masă.
4.2 TSENS
Nivelul de deasupra modului OWP este TSENS. Acest modul ştie să comunice cu senzorul. Cu alte cuvinte poate să trimită aproape toate comenzile recunoscute de către senzorul DS18B20 şi ştie să citească întreaga memorie a senzorului (cei 9 bytes din Scratchpad). Modulul verifică starea modului OWP, decide ce trebuie făcut şi pasează eventuala eroare nivelului superior. Asta înseamnă că, în cazul unei erori, el va încerca să restabilească comunicarea cu acel senzor de fiecare dată când acel senzor va fi accesat. În plus modulul TSENS verifică dacă datele primite sunt corecte cu ajutorul CRC-ului oferit de OWP şi alertează modulul superior dacă o nouă temperatură este disponiblă.
4.3 TMON şi ERROR
Nivelul cel mai de sus este TMON. Acest modul are un rol foarte important pentru că el decide pornirea sau oprirea pompei, în funcţie de datele primite. Modul în care funcţionează este următorul:
  • citeşte alternativ temperaturile celor doi senzori (Tpanou şi Tbazin).
  • în momentul în care s-a făcut numărul de conversii dorit, realizează o medie a temperaturilor pentru Tpanou şi Tbazin.
  • valorile medii ale temperaturilor sunt comparate cu valorile setate de către utilizator, iar în cazul în care se respectă condiţia de pornire a pompei, pompa este pornită, altfel pompa este oprită.
  • în cazul în care unul din senzori (sau ambii) e marcat de către TSENS ca fiind în starea de eroare, acel senzor va fi ignorat până ce starea lui nu se schimbă.
În cazul apariţei oricărei erori, modulul ERROR va fi chemat. Acest modul ţine evidenţa tuturor erorilor ce au apărut în sistem. Dacă numărul erorilor e mai mare de 0 atunci LED-ul de avarie va fi aprins.
Dacă unul din senzori e în starea de eroare atunci numărul de conversii nu va ajunge niciodată la valoarea dorită, deci pompa nu va fi comandată.
Modulul OWP este legat de evenimentul de 1 ms, asta înseamnă că un bit va fi transmis, sau recepţionat la fiecare o milisecundă.
Modulul TSENS e legat de evenimentul de 10 ms, adică tot la 10 milisecunde va trimite o nouă comandă (un byte), sau va recepţiona un nou byte de date.
Modulul TMON e legat de evenimentul de 200 ms, adică tot la 200 ms verifică dacă există o nouă valoare disponibilă a temperaturii pe oricare din canalele folosite (Tpanou sau Tbazin), iar dacă există o procesează.
 5. Actualizarea ore şi a datei.
Modulul HMDY (Hour Minute Day Year = oră minut zi an) realizează gestionarea timpului. Acest modul e chemat o dată la un minut, datorită evenimentului 1min. De fiecare dată când acest modul se execută el va face următoarele operaţii:
Astfel la fiecare apel al modulului HMDY se va incrementa valoarea minutelor. În funcţie de această valoare se verifică dacă valoarea orei curente nu trebuie incrementată. La rândul ei ora curentă poate determina incrementarea zilei, ziua poate determina valoarea lunii şi tot aşa până la an. Determinarea anilor bisecţi (când luna Februarie are 29 zile) se face prin verificarea dacă anul curent este multiplu de 4 sau nu. Nu e o metodă foarte exactă, dar acoperă aproape toate situaţiile în care avem ani bisecţi.
 6. Monitorizarea tensiunii de 12V şi detectarea unei căderi de tensiune.
Detectarea unei căderea de tensiune poartă numele de BOD (Brown Out Detection). Atmega8 are posibilitatea de a fixa nivelul de detectie la 4V sau 2.7V. În cazul programului meu, nivelul de detecţie e setat la 2.7V. Asta înseamnă că în momentul în care tensiunea de alimentare a ajuns la valoarea de 2.7V, microcontroler-ul se va reseta.
Pe lângă această măsură de precauţie, am folosit intrările comparatorului analogic AIN0 şi AIN1 , prin intermediu modului VMON, pentru a determina din timp dacă apare o pană de curent. Astfel, tensiunea de 12V de la 7812, trece printr-un divizor de tensiune şi intră în AIN1 (intrarea inversoare a comparatorului) sub forma unei tensiuni de 5.3V. Tensiunea de 5V de la 7805 intră direct în AIN0 (intrarea neinversoare a comparatorului). De fiecare dată când nivelul tensiunii de pe pinul AIN1 devine mai mic decât nivelul tensiunii de pe pinul AIN0, ieşirea comparatorului va trece din "0" în "1" şi va genera o întrerupere. În această întrerupere se salvează toate configuraţiile făcute şi istoricul de temperaturi, împreună cu un CRC care va fi folosit pentru validarea datelor citite din EEPROM. Prin natura circuitului electronic de alimentare, este posibilă întârzierea căderii de tensiune sub pragul de 2.7V, astfel încât să putem salva toate datele.
 7. Scrierea şi citirea datelor în şi din EEPROM, cu validare prin CRC.
Datele sistemului se salvează în memoria EEPROM internă doar când este detectată o cădere de tensiune. Împreună cu datele salvate, se salvează şi CRC-ul calculat pentru datele scrise.
La pornirea sistemului, se vor citi toate datele din EEPROM cu ajutorul modulului IEP şi se va verifica dacă CRC-ul calculat la citire coincide cu CRC-ul scris în EEPROM. În cazul în care cele două valori ale CRC-ului sunt identice, datele din EEPROM sunt valide şi se pot folosi pentru iniţializarea variabilelor globale ale sistemului. În cazul în care CRC-ul este diferit, datele din EEPROM nu sunt valide, aşa că se vor folosi nişte date împlicite (salvate în memoria Flash) pentru iniţializarea vaiabilelor globale.
 8. Detectarea şi administrarea erorilor.
Modulul care se ocupă cu administrarea erorilor este modulul ERROR. Modulul este chemat de către fiecare alt modul capabil să detecteze o eroare: OWP, VMON şi PUMP.
Următoarele erori sunt detectable:
  1. cablu rupt pentru senzorul din panou
  2. scurt la masă pe cablul pentru senzorul din panou
  3. cablu rupt pentru senzorul din bazin
  4. scurt la masă pe cablul pentru senzorul din bazin
  5. tensiunea de 12V lipseşte
  6. cablu rupt pentru releul care comandă pompa
Modulul ERROR setează bitul corespunzător erorii apărute. În cazul apariţiei oricărei erori, led-ul de avarie se va aprinde. Acest led va rămâne aprins până când problema care a cauzat eroarea nu a fost remediată. pentru a vedea ce eroare a apărut, trebuie să navigăm prin meniu până în starea S23. Aici controller-ul va afişa toate erorile care au fost detectate în momentul respectiv:
De exemplu, în cazul în care avem 4 erori: cablu rupt pentru senzorul din panou, scurt la masă pe cablul de la senzorul din bazin, releul lipseşte şi tensiunea de alimentare este sub 12V, atunci vom vedea următoarele mesaje de eroare:
Trecerea de la un mesaj de eroare la altul se face apăsând tasta "Enter", în momentul în care suntem în starea S23.
 9. Controlul releului pentru pompă.
Controlul releului care alimentează pompa se face din starea 1.3 (Control Pompă). Din acest meniu putem pune pompa în trei stări diferite:
  • Off - Comanda maunală de oprire a pompei
  • On - Comandă manuală de pornire a pompei
  • Auto - Mod automat
Dacă primele două setări sunt clare, Modul Auto e puţin mai complicat. În acest mod, controlul pompei este preluat de către microcontroller. Acesta va decide când trebuie să pornească pompa şi când să se oprească, pe baza temperaturii măsurate de către cei doi senzori, după cum urmează:
Pentru ca pompa să poată porni trebuie îndeplinite trei condiţii:
  • Temperatura din panou este mai mare decât temperatura setată (Tp)
  • Diferenţa de temperatură dintre temperatura din panou şi cea din bazinul de stocare este mai mare decât cea setată (Delta.T)
  • S-au făcut un număr de măsurători egal cu cel setat (Nr.Conv.)
Pornirea pompei e restricţionată pentru a nu permite răcirea bazinului de stocare, în cazul în care temperatura din bazin e mai mare decât temperatura din panou şi decât temperatura setată (Tp). Valoarea Delta.T reprezintă acea diferenţă de temperatură care permite un transfer util de căldură. Agentul termic ce vine de la panou trebuie să aibă o temperatură cu câteva grade mai mare decât cel din bazin pentru a permite transferul termic.
Pentru a nu avea situaţia în care releul cuplează şi apoi decuplează succesiv, la interval foarte scurt, s-a introdus trimiterea comenzii pentru pompă doar după un număr configurabil de măsurători. Dacă Nr.Conv e setat la valoarea 1 atunci, cum fiecare măsurătoare a temperaturii durează aproximativ o secundă, iar cum avem doi senzori, timpul cel mai scurt de transmiterea al unei comenzi va fi de aprox. 2 secumde. Pentru Nr.Conv egal cu 30, transmiterea comenzii se va face tot la un minut.
Cam în asta constă partea de logică a controllerului...
10. Surse
Codul se poate copia de aici...
Fişierul hex cu programul pentru ATmega8 se poate copia de aici...
Datele pentru EEPROM se pot copia de aici...

11. Fuse bits Atmega8 [update 02.01.2018]

9 comentarii:

  1. Foarte fain documentat, explicat si cu multe lucruri de invatat!

    RăspundețiȘtergere
  2. Schema ieste buna dar unde pot gasi sofware la schema respectiva ?!!?

    RăspundețiȘtergere
    Răspunsuri
    1. Salut Francisc,
      Pentru a realiza scheme electronice şi pentru a proiecta cablaje, poţi folosi o multitudine de programele, disponibile pe net. Eagle e unul din ele, de exemplu.
      Numai bine!

      Ștergere
    2. eagle (optiune1) sau Fritzing(2)

      Ștergere
  3. Salut Misha,exista si o schema pentru acest controller? Multumesc..

    RăspundețiȘtergere
    Răspunsuri
    1. Salut,
      Există! :-)

      http://cumsefaceunaalta.blogspot.ro/2012_02_01_archive.html

      Numai bine!

      Ștergere
  4. Va salut! Am urmat sfaturile autorului in ceea ce privește fuse bits pentru uC, numai că nu m-am descurcat. Dintre dvs. care ați realizat acest proiect puteți posta acești parametrii? Va mulțumesc anticipat.

    RăspundețiȘtergere
    Răspunsuri
    1. Salut Valentin,
      Îmi cer scuze pentru răspunsul târziu.
      Am adaugat la articol o poză cu configuraţia fuse-biţilor.
      Sper să ajute!

      Ștergere