MONITORIZAREA ȘI CONTROLUL MEDIULUI DINTR-O SERĂ Georgiana – Lucreția Stoian COORDONATOR ȘTIINȚIFIC Ș.L. Dr. Ing. Eugen Dumitrașcu IULIE 2016 CRAIOVA… [301917]

[anonimizat]

Ș.L. Dr. Ing. Eugen Dumitrașcu

IULIE 2016

CRAIOVA

MONITORIZAREA ȘI CONTROLUL MEDIULUI DINTR-O [anonimizat]

Ș.L. Dr. Ing. Eugen Dumitrașcu

IULIE 2016

CRAIOVA

„Învățătura este o comoară care își urmează stăpânul pretutindeni.”

[anonimizat], student: [anonimizat], Calculatoare și Electronică a [anonimizat], [anonimizat]:

cu titlul MONITORIZAREA ȘI CONTROLUL MEDIULUI DINTR-O SERĂ,

coordonată de Ș.L. Dr. Ing. [anonimizat] 2016.

[anonimizat]:

reproducerea exactă a [anonimizat]-o [anonimizat]-o [anonimizat],

[anonimizat], [anonimizat] a unor aplicații realizate de alți autori fără menționarea corectă a [anonimizat] a [anonimizat].

Pentru evitarea acestor situații neplăcute se recomandă:

plasarea între ghilimele a citatelor directe și indicarea referinței într-o [anonimizat] a [anonimizat] a sursei originale de la care s-a [anonimizat] s-[anonimizat], figuri, imagini, statistici, [anonimizat], a căror paternitate este unanim cunoscută și acceptată.

Data, Semnătura candidat: [anonimizat],

PROIECTUL DE DIPLOMĂ

REFERATUL CONDUCĂTORULUI ȘTIINȚIFIC

În urma analizei lucrării candidat: [anonimizat]:

[anonimizat]:

Data, [anonimizat]

O seră este o [anonimizat], având un rol deosebit de important în agricultură.

Obiectivul acestui proiect este de a monitoriza și controla mediul dintr-o seră. [anonimizat], sau se poate controla nivelul fotoradiațiilor pentru a facilita fotosinteza.

În dezvoltarea acestui proiect se vor implementa algoritmi pentru:

gestionarea temperaturii;

gestionarea umiditații;

gestionarea luminii;

Sistemul ce va fi capabil să facă toate aceste lucruri va fi controlat cu ajutorul unui microcontroler ATMega2560.

Se vor folosi:

[anonimizat] a monitoriza în permanență nivelul de apă din sol. Pe baza valorilor primite de la acești senzori se va hotărî dacă se va porni sau nu o pompă de apă.

senzori de temperatură – pentru a menține constantă temperatura. Pe baza valorilor recepționate de la acești senzori se va porni sau nu o sursă de caldură.

senzori de lumină – pentru a gestiona cantitatea de lumină necesară plantelor. În cazul în care nu este suficientă lumina solară, se vor porni Led-uri.

Se va dezvolta o aplicație desktop, în Java. Senzorii vor trimite în timp real către aplicația Java valorile acestora.

Aplicația Java constituie Panoul de control pentru User. Aici, un user poate să observe în permanență parametrii mediului din seră, și să poată acționa manual anumite comenzi. Aplicația Java va conține o interfață prietenoasă cu utilizatorul, astfel încât să fie ușor de folosit. Această aplicație poate să conțină și o bază de date unde se stochează datele pe o perioadă de timp și pe baza cărora se pot genera anumite statistici.

Arhitectura proiectului este urmatoarea:

Termenii cheie: seră, senzor, lumină, umiditate, temperatură, serial, Arduino, pompă apă, LED, ventilator.

MULȚUMIRI

În această secțiune, pot mulțumi întregii mele familii pentru susținere și în special soțului meu pentru ajutorul acordat în finalizarea acestui proiect, ce reprezintă încheierea cu succes a unui nou capitol din viața mea.

De asemenea, un ajutor foarte important a fost domnul profesor coordonator, care a avut încredere în mine și în acest proiect, care m-a sfătuit și susținut.

Și bineînteles vreau să le mulțumesc prietenilor mei foarte apropiați, care nu m-au lăsat la greu și m-au ascultat atunci când am avut nevoie.

Vă mulțumesc tuturor încă odată, pentru întreg sprijinul acordat și pentru răbdarea de care ați dat dovadă atunci când am fost poate prea stresantă sau stresată.

CUPRINSUL

1 Introducere 1

1.1 Scopul 1

1.2 Motivația 1

2 Componente hardware utilizate 3

2.1 Microcontroler. Definiție. Structură 3

2.2 Microcontroler-ul ATmega2560 6

2.3 Microcontrolere Arduino 8

2.4 Senzori 9

2.4.1 Senzori de temperatură 10

2.4.2 Senzori de umiditate 11

2.4.3 Senzori de lumină 11

2.5 LED-uri 12

2.6 Relee 13

2.7 Pompe hidraulice 14

2.8 Ventilatoare 15

3 Componente software utilizate 16

3.1 Arduino IDE 16

3.2 NetBeans IDE 17

3.3 Oracle Database 18

3.4 Visual Studio 18

3.5 Fritzing IDE 19

4 Arhitectura hardware 20

4.1 Arhitectura hardware generală a serei 20

4.2 Conectarea senzorilor 22

4.3 Conectarea pompelor de apă 23

4.4 Conectarea ventilatoarelor 24

4.5 Conectarea LED-urilor 25

4.6 Arduino Mega2560 26

4.7 Surse de alimentare 27

5 Arhitectura software 28

5.1 Librării utilizate 28

5.1.1 Librăria JFreeChart 28

5.1.2 Librăria JDBC 29

5.1.3 Librăria PanamaHitek_Arduino 30

5.2 Structura bazei de date 31

5.3 Aplicația Arduino 32

5.3.1 Funcția setup 32

5.3.2 Funcția loop 33

5.4 Aplicația JAVA 34

5.4.1 Pachetul Model 34

5.4.1.1 Clasa History 34

5.4.1.2 Clasa SensorValues 35

5.4.1.3 Clasa Users 36

5.4.2 Pachetul View 36

5.4.2.1 Clasa Application 37

5.4.2.2 Clasa Change_password 40

5.4.2.3 Clasa Chart 41

5.4.2.4 Clasa Login 45

5.4.2.5 Clasa MyPainter 46

5.4.2.6 Clasa Register 47

5.4.3 Pachetul Control 48

5.4.3.1 Application_listener 48

5.4.3.2 Change_password_listener 51

5.4.3.3 Chart_listener 52

5.4.3.4 Login_listener 52

5.4.3.5 Register_listener 53

5.4.3.6 SerialPort_listener 54

5.4.4 Pachetul SQL 55

5.4.4.1 MYSQLCMD 55

5.4.4.2 MyConnection 55

6 Concluzii 56

7 Bibliografie 57

8 Referințe web 58

A. Livrările proiectului 60

B. Arhitectura generală a serei 61

C. Schema electronică a serei 62

C. Codul Sursă 63

D. CD / DVD 79

Index 80

LISTA FIGURILOR

Figura 1. Structura unui microcontroler 3

Figura 2. Convertor Analogic – Digital / Convertor Numeric – Analogic 5

Figura 3. Microcontroler-ul Atmega2560 6

Figura 4. ATmega 2450-Configurația pinilor 7

Figura 5. Logo-ul oficial ARDUINO 8

Figura 6. Schema bloc a unui senzor 9

Figura 7. Termistor NTC 10

Figura 8. Senzor de umiditate a solului 11

Figura 9. Fotorezistor 11

Figura 10. Simbolurile fotorezistorului 12

Figura 11. Stuctura unui LED 12

Figura 12. Schema unui releu 13

Figura 13. Mașină cu roți dințate 14

Figura 14. Ventilator axial 15

Figura 15. Arduino 1.6.8 17

Figura 16. NetBeans IDE 8.1 17

Figura 17. Oracle Database 11g 18

Figura 18. Microsoft Visual Studio 2012 19

Figura 19. Logo-ul Fritzing 19

Figura 20. Modul de interconectare a componentelor 21

Figura 21. Schema electronică a proiectului 21

Figura 22. Conectarea senzorilor 22

Figura 23. Conectarea pompelor de apă prin intermediul releelor 23

Figura 24. Relee srd-05vdc-sl-c 24

Figura 25. Conectarea ventilatoarelor 25

Figura 26. Conectarea LED-urilor 26

Figura 27. Shield Arduino Mega 26

Figura 28. Exemplu de grafic de tip bară 28

Figura 29. Logo Panama Hitek 30

Figura 30. Diagrama bazei de date 31

Figura 31. Modelul MVC 34

Figura 32. Clasa History 35

Figura 33. Clasa SensorValue 35

Figura 34. Clasa Users 36

Figura 35. Interfața principală a aplicației 37

Figura 37. Accesarea meniului Cont 39

Figura 36. Accesarea meniului 39

Figura 38. Fereastra de schimbare a parolei 40

Figura 39. Grafic tip bară 3D 42

Figura 40. Grafic tip bară 42

Figura 41. Grafic tip linie 43

Figura 42. Grafic tip linie 3D 44

Figura 43. Grafic tip zonă 44

Figura 44. Fereastra de Logare 46

Figura 45. Fereastra de înregistrare cont 47

Figura 46. Ștergere cont 51

Figura 47. Cont șters 51

Figura 48. Parolă salvată 51

Figura 49. Parole diferite 52

Figura 50. Cont creat 53

Figura 51. Plantă ofilită 54

Figura 52. Plantă uscată 54

Figura 53. Plantă normală 54

LISTA TABELELOR

Tabelul 1. Bara de butoane a tool-ului Arduino IDE 16

Tabelul 2. Conectarea senzorilor la plăcuță 22

Tabelul 3. Conectarea ventilatoarelor la plăcuță 24

Tabelul 4. Specificații Arduino Mega 27

Tabelul 5. Configurația pinilor 33

Introducere

Scopul

Proiectul de licență a fost ales pentru a facilita întreținerea unei sere, astfel prin acest sistem care se va ocupa de controlarea parametrilor, se va evita prezența umană.

Proiectul se bazează pe implementarea unui sistem capabil să monitorizeze și să controleze mediul dintr-o seră. Acest sistem va comunica cu o interfață Java, ce va constitui panoul de control al utilizatorului. User-ul va putea decide ce mod de funcționare dorește: manual sau automat. În modul automat sistemul va controla (pe baza informațiilor primite de la senzori) toate dispozitivele menite să țină sera în parametrii normali, iar în modul manual user-ul va fi cel ce va acționa aceste dispozitive, fie pe baza presupunerilor lui, fie pe baza informațiilor recepționate de la senzori (informații ce sunt vizibile în timp real în aplicația Java).

Motivația

O seră este o construcție specială amenajată pentru adăpostirea și cultivarea plantelor, având un rol deosebit de important în agricultură. Deobicei are acoperiș (și cu pereți) din sticlă sau din material plastic. Ea se construiește cu scopul de a crea un microclimat optim și artificial, creșterii și dezvoltării plantelor pe tot parcursul anului.

Lumina într-o seră este folosită în principal pentru procesul de fotosinteză, în care plantele absorb și acumulează pînă la 10% din energia radiației solare incidente. În același timp, din dioxidul de carbon și apă, sub acțiunea luminii solare se formează carbohidrații și oxigenul molecular. Din moleculele carbohidraților se dezvoltă substanțele organice necesare pentru viața și creșterea plantelor. De asemenea și temperatura este un factor important în viața unei plante. Serele pot fi încălzite cu apă fierbinte, aburi, aer cald, radiație infraroșie sau produsele de ardere ale combustiei.

Luând în considerare toți acești factori, ar fi de folos un sistem automat ce se ocupă cu controlarea acestor parametrii, fără a mai fi nevoie permanent de prezența umană.

De ce am ales un proiect ce presupune lucrul cu o seră este foarte simplu. Având în vedere că trăim într-un secol în care oamenii preferă să lase natura deoparte, în favoarea confortului, ar fi foarte interesant să pun accentul pe un lucru indispensabil nouă și anume natura ce este o sursă de oxigen.

Acum explicația pentru care am ales să monitorizez și să controlez o seră, este faptul că, datorită acestui secol al vitezei în care nu mai avem timp să ne ocupăm de mai multe lucruri deodată, ar fi utilă o aplicație care să facă asta în locul nostru.

Dar cum funcționalitațile acestui proiect au fost deja dezvoltate de firma WADSWORTH Control Systems, eu am hotarât să încerc să îmi demonstrez mie că pot realiza la scară mai mică acest proiect, cu toate resursele și cunoștințele ce sunt disponibile unui student aflat la început de drum. Aceasta este adevarata mea motivație pentru care am ales să duc la bun sfarșit ceea ce mi-am ales să fac.

Componente hardware utilizate

Microcontroler. Definiție. Structură

Dealungul timpului prin procesul de miniaturizare a controlerelor destinate unei interacțiuni caracteristice cu mediul exterior fără a mai fi nevoie de intervenția unui operator uman, a fost posibil ca majoritatea componentelor constituente ale acestora să fie înglobate într-un singur circuit, ce poartă numele de microcircuit sau microcontroler. [LAU12]

Figura 1. Structura unui microcontroler

Microcontrolerul este cel ce integrează pe lângă microprocesor și alte dispozitive, toate pe același chip. Cu alte cuvinte diferența dintre un microcontroler (µC) și un microprocesor (µP) este că microcontroler-ul este cel ce are în componența sa un microprocesor. [CIO03]

Un microcontroler este compus cel puțin din urmatoarele componenete:

Unitate centrală (CPU);

O memorie locală tip ROM/PROM/EPROM/FLASH;

O memorie RAM;

Un sistem de întreruperi;

I/O – intrari/ieșiri;

Un sistem de timere;

Un sistem de conversie analog numerică;

Un sistem de conversie numeric analogic;

Un comparator analogic;

Memoria FLASH

Memoria de program sau FLASH este memoria în care se stochează programul ce se dorește a fi executat, astfel microcontrelerul nu face altceva decât să urmarească instrucțiunile fară să le modifice în vreun fel. Scrierea acestei memorii este deobicei limitată.

Memoria RAM

Este o memorie volatilă (Random Access Memory), ceea ce presupune că datele sunt stocate doar temporar. Mai precis în cazul unui reset sau atunci când microcontroler-ul nu mai este alimentat, datele aflate în această memorie vor fi pierdute.

I/O

Intrările microcontroler-ului sunt de mai multe tipuri:

Digitale: se pot primi numai date digitale și anume 0 sau 1;

Analogice: tensiunea aplicată pe acestă intrare va fi convertită de un convertor A/D și ulterior va putea fi folosită de microcontroler ce va putea percepe mai multe valori, nu numai 1 și 0;

Ieșirile microcontroler-ului pot fi numai digitale.

Convertor Analogic – Digital

Acest convertor este folosit pentru a transforma un semnal analogic într-unul digital. Rezoluția disponibilă este de 8, 10, 12 biți.

Convertor Numeric – Analogic

Acest convertor este folosit pentru a transforma un semnal digital într-unul analogic. Cea mai răspândită tehnică este cea bazată pe modulația în factor de umplere ( PWM – Pulse Width Modulation). [LAU12]

Figura 2. Convertor Analogic – Digital / Convertor Numeric – Analogic

Cele mai cunoscute familii de microcontrolere sunt:

PIC

AVR

COP4 și COP8;

Z8;

Renesas;

Microcontroler-ul ATmega2560

Nucleul AVR combină un set de instrucțiuni cu 32 de regiștrii. Toți cei 32 de regiștrii sunt conectați direct la Unitatea Logică Aritmetică (ALU – Arithmetic Logic Unit), permițând ca două registre independente să fie accesate într-o singură instrucțiune executată într-un singur ciclu de ceas. Arhitectura rezultată este mult mai eficientă fiind de aproximativ zece ori mai rapidă decât microcontrolere convenționale CISC. [ATM14]

Principala funcție a nucleului este să asigure corecta funcționare a programelor. CPU-ul trebuie să fie capabil să acceseze memoria, să facă calcule, să controleze perifericele și să gestioneze întreruperile. AVR-ul utilizează o arhitectură Harvard cu memorii și magistrale separate pentru program și date. Cât timp o instrucțiune este executată, o alta deja se citește din memoria de program. [ATM14]

Configurația microcontroler-ului Atmega2560 este:

256 KB memorie Flash;

4 KB memorie EEPROM;

8 KB memorie RAM;

86 pini de I/O;

12 canale PWM;

16 canale ADC;

Microcontreler-ul Atmega2560 suportă o suită întreagă de programe și tool-uri de dezvoltare incluzând: compilatoare C, asambloare macro, programe de debug/ simulare, kituri de evaluare.

Atmega2560 este un microcontroller puternic ce furnizează soluții foarte flexibile și ieftine pentru multe aplicații embedded.

Microcontrolere Arduino

Arduino este o companie open-source care le oferă studenților nenumărate avantaje deoarece produce pe lângă placuțe de dezvoltare, software ce este de mare ajutor programării acestor placuțe. Pe lângă acest avantaj vizibil, există și o mare comunitate care dezvoltă diferite proiecte utilizând partea hardware cât și software furnizată de această companie.

Aceste plăci pun la dispoziția utilizatorilor pini de intrare/ieșire (I/O pins) digitali și analogici. Acestea dispun și de interfețe de comunicații seriale, pot dispune chiar de USB cu ajutorul căruia se pot descărca programe din calculatoarele dezvoltatorilor.

Primul Arduino a fost lansat în 2005, fiind o soluție simplă și ieftină pentru toate tipurile de utilizatori. O placuță a fost inițial compusă dintr-un microcontroler Atmel AVR, iar ulterior s-au adăugat chipuri de la alți producatori. Aceasta mai conține pe lângă microprocesor: un oscilator și un regulator liniar de 5 V. [ARD16]

Arduino este foarte simplu de utilizat astfel prin intermediul software-ului ARDUINO IDE se poate scrie programul dorit după care acesta se poate descărca pe placuța de dezvoltare. Acest tool permite scrierea programelor în limbajul C/C++.

Arduino este astfel un mic calculator, deoarce se pot controla intrarile și ieșirile de la chip, prin intermediul lui.

Există mai multe tipuri de placuțe Arduino:

Arduino UNO (Atmega328);

Arduino Mega (Arduino Mega2560):

Arduino Leonardo (Atmega32u4);

Arduino Diecimila (Atmega168);

Arduino Nano (Atmega328);

Arduino Duemilavove (Atmega168);

Senzori

Ce este un senzor? Senzorul poate fi numit și traductor. Mai precis senzorul preia informații din mediu și le furnizează mai departe microcontroler-elor. În acest mod semnalele neelectrice sunt convertite în semnale electrice ce pot fi interpretate.

Atunci când se dorește alegerea unui senzor trebuiesc urmariți o serie de parametri, ca spre exemplu: costul, greutatea, consumul de energie, dimensiunile, precizia, sensibilitatea, domeniul de măsurare, viteza de răspuns, stabilitate. Există în schimb o mare varietate de senzori, care au caracteristici specifice grupei din care fac parte.[DUM06]

Putem privi un sensor ca pe o „cutie neagră”, deoarece aplicăm niște intrări ce urmează a fi măsurate și la ieșire ne așteptăm la rezultate.

Clasificari

Există mai multe tipuri de senzori (circa 2000 tipuri distincte). Una dintre cele mai importante clasificari ale senzorilor este în funcție de tipul mărimii de ieșire:

Analogici – semnalul de ieșire este proporțtonal cu cel de intrare;

Digitali – semnalul de ieșire are un numar limitat de valori care permit cuantificarea semnalului de intrare;

Tipuri de senzori

Există nenumărate tipuri de senzori, printre cei mai cunoscuți și utilizați sunt:

Senzori de turație;

Senzori de umiditate;

Senzori de presiune;

Senzori de lumină;

Senzori de temperatură;

Senzori de distanță;

Senzori de mișcare;

Senzori tactili;

Deoarece în acest proiect am folosit senzori de umiditate, temperatură și lumină, mai departe voi vorbi despre aceștia.

Senzori de temperatură

Senzorii de temperatură mai pot fi numiți si termometre. Aceștia pot fi de două tipuri și anume: pot avea contact direct cu obiectul asupra căruia se dorește să se execute măsurătoarea sau fară contact.

Termometrele au constanta de timp variabilă, datorită inerției termice ce depinde de rezistența termică dintre senzor și obiectul asupra căruia se dorește să se execute măsurătoarea, tipul senzorului, locul de montare al senzorului. Termometrele cu termistoare și termorezistoare au aceste constante de timp de aproape o secundă.

Senzorii de temperatură se clasifică în funcție de tipul ieșirii și de modul de comandă în:

Analogici;

Cu intrari și ieșiri digitale;

Cu ieșiri digitale;

Pentru proiectul meu am ales să folosesc termistori (vezi Figura 8). Un termistor este un rezistor dependent de temperatură, realizat din materiale semiconductoare. Există două tipuri de termistoare și anume:

NTC – au un coeficient negativ la variația rezistenței cu temperatura;

PTC – au un coeficient pozitiv la variația rezistenței cu temperatura;

La termistoarele NTC, se realizează o scădere a rezistenței atunci când temperatura crește, iar la cele PTC este exact invers. [VOR09]

Eu am ales să folosesc un termistor ca cel din figură (vezi Figura 7). Acesta este un termistor NTC care dă o anumită tensiune de ieșire, în funcție de modificarea temperaturii.

Senzori de umiditate

Senzorii de umiditate sunt acei senzori care pot măsura nivelul de umiditate. Există senzori care pot măsura fie umiditatea aerului ambiental și gaze, fie pe cea a solului.

Umiditatea aerului este măsurată prin acei senzori ce pot stabili câți vapori de apă există în aer. Această măsurare este mult mai dificilă decât măsurarea cu exactitate temperaturii și vitezei vântului, pentru că acești senzori sunt mai puțin sensibili. Instrumentele prin care se măsoară umiditatea aerului sunt: psihometru, higrometrul cu punct de rouă, higrometru volumic, hrigrometru cu fir de păr, higrometru electrolitic, higrometru cu interferență, higrometru cu infraroșu, etc.[STE04]

Măsurarea umidității solului este foarte importantă în special în agricultură, unde este nevoie să se cunoască umiditatea solului și pe baza acestei informații să se ia decizii de pornire a sistemelor de irigații.

Pentru acest proiect am ales să folosesc senzori de umiditate a solului ca cei din Figura 8.

Senzori de lumină

Senzorii de lumină sunt acei senzori ce pot detecta o mărime de ieșire de natură optică: difuzia, intensitatea luminoasă, absorbanța.

În cadrul acestui proiect am folosit ca senzor de lumină fotorezistorul, așa că aș dori să vorbesc mai multe despre el.

Fotorezistorul este un dispozitiv, a cărui rezistență se modifică sub acțiunea luminii, care cade pe suprafața acestuia. Acest dispozitiv electronic este format dintr-o peliculă de material semiconductor care este depusă pe un grătar metalic, fixat pe o placă izolatoare. [RUS15]

Rezistența fotorezistorului scade odată cu creșterea intensității luminii ce este aplicată pe suprafața acestuia.

Dacă acest fotorezistor este conectat într-un circuit electric, el modifică intensitatea curentului. Astfel intensitatea curentului crește odată cu scăderea rezistenței electrice a acestuia. [RUS15]

LED-uri

Dioda luminiscentă (Light Emitting Diode) este dioda care poate produce lumină, atunci când este polarizată direct.

Această diodă este compusă dintr-o structură semiconductoare pn care are proprietatea de a emite lumină ( vezi Figura 11 a).

Această structură este pusă într-o cupă reflectoare ( vezi Figura 11 b) care este conectată la terminale. Aceste terminale se numesc ANOD ( +) și CATOD (-).

Culoarea luminii produse depinde de aliajul din care este făcută structura semiconductoare și anume:

Roșu (Aluminiu – Galiu – Arsen);

Verde (Aluminiu – Galiu – Fosfor);

Albastru (Zinc –Seleniu);

Ultraviolet (Carbon), etc.;

Relee

Releul este un aparat cu acțiune automată, care la o anumită valoare a intrăsrii, produce o modificare a ieșirii, fiind cel puțin una dintre acestea două de natură electrică. Dacă ieșirea este electrică, atunci înseamnă că avem de a face cu un releu indirect.

Atunci când este sesizată o modificare a intrării, releu compară intrarea cu valoarea stabilită prin reglaj și transmite mai departe informația elementului de execuție. Acesta execută lucrul mecanic specific tipului de releu. [REL11]

Clasificare

O clasificare importantă a releelor este în funcție de natura mărimii de intrare:

Relee de curent;

Relee de tensiune;

Relee de putere;

Relee de frecvență;

Relee de timp;

Pompe hidraulice

Mașinile hidraulice sunt sisteme capabile să transforme energia mecanică în energie hidraulică și bineînteles și invers. În cazul în care această energie hidraulică este transformată în energie mecanică, mașina poartă numele de motor hidraulic, iar în cazul în care această transformare este inversă, mașina se va numi pompă. [DIN08]

Mașinile hidraulice pot fi de doua tipuri:

Rotative;

Liniare:

Mașinile rotative produc o mișcare de rotație a unui arbore, iar cele liniare sunt formate dintr-un cilindru cu piston.

În acest proiect am folosit o pompă de apă cu roți dințate și aș dori să vorbesc puțin despre aceast tip de pompe.

Mașina cu roți dințate este o mașină hidraulică rotativă. Această mașină prezintă două camere separate și anume: camera de joasă presiune și camera de înaltă presiune. Pentru o pompă de apă lichidul circulă din camera de joasă presiune spre cea de înaltă presiune.

În timpul funcționării ca pompă, lichidul este aspirat în spațiul dintre doi dinți și este transportat în camera de înaltă presiune. Deoarece lichidul nu este eliminat lin, ci este prins între doi dinți, apar curgeri de mare viteză și șocuri în angrenaj. Datorită acestui fapt pompa va produce mult zgomot, iar curgerile vor provoca uzura prematură a componentelor pompei. [DIN08]

Ventilatoare

Ventilatoarele sunt generatoare ce funcționează în medii gazoase și produc energie pneumatică ce este transformată din energie mecanică (preluată de la motorul de antrenare).

Cea mai importantă clasificare a ventilatoarelor este în funcție de direcția de mișcare a gazului. Astfel există două tipuri de ventilatoare: radiale și axiale.

În continuare voi vorbi despre ventilatoarele axiale, deoarece pe acestea le-am folosit în acest proiect.

Ventilatoarele axiale sunt cele în care particulele de gaz sunt transportate pe “traiectorii paralele cu axul mașinii”, spre deosebire de cele radiale în care particulele de gaz ”sunt transportate pe traiectorii ce se îndepartează de axul mașinii”. [NAG05]

Acest tip de ventilator este compus dintr-un stator, rotor si o carcasă. Statorul ajută la conducerea favorabilă a curentului și poate lipsii, iar rotorul este constituit dintr-un butuc și palete.

Componente software utilizate

Arduino IDE

Programele Arduino pot fi scrise în oricare limbaj de progrmare, sigura condiție ar fi că este necesar un compilator care să transforme acel cod scris într-un cod mașină pe care plăcuța să îl poată interpreta.

Arduino IDE este o aplicație “cross-platform” ceea ce înseamnă că acest program este produs în mai multe variante, fiecare specifică pentru un anumit sistem de operare, astfel există acest software pentru Windows, Mac OS și Linux. Acest program este scris în Java și este proiectat astfel încât să fie ușor de folosit și de cei ce nu sunt familiarizați cu programarea.

Arduino IDE are un editor de cod ce este foarte util deoarece evidențiază termenii cheie și ține cont de potrivirea parantezelor. Un program scris în acest tool se numește “sketch”. [ARD16]

În tabelul de mai jos sunt descrise butoanele ce sunt disponibile în Arduino IDE.

Tabelul 1. Bara de butoane a tool-ului Arduino IDE

În Serial Monitor se pot vedea mesajele transmise serial de la placuța Arduino. Pentru a putea trimite date serial placuței trebuie avut grijă să fie aceeași configurație în această fereastră și în funcția setup. Odată ce configurația este aceeași mai rămâne doar să scriem mesajul și să apăsăm butonul de Send.

Pentru a scrie codul C și pentru a îl pune pe microcontroller am folosit Arduino IDE versiunea 1.6.8, pentru Windows pe 64-biți.

NetBeans IDE

NetBeans este o platformă de dezvoltare ce este scrisă în Java. Această tool este cross- platform și are versiuni disponibile pentru Windows, Linux, Mac OS.

Acest program este deobicei utilizat pentru a scris cod JAVA, dar nu numai. Astfel se pot scrie programe în PHP, C/C++, HTML5,C#. [NET16]

Acest program are în componența sa mai multe module ca spre exemplu:

NetBeans Profiler – instrument ce ajută dezvoltatorii să găsească scurgeri de memorie și să optimizeze viteza.;

Instrument de proiectare GUI ce facilitează creeare interfețelor;

Editor NetBeans JavaScript ce oferă suport pentru JavaScript, Ajax, CSS;

Pentru realizarea aplicației desktop a proiectului s-a utilizat NetBeans IDE versiunea 8.1 pentru Windows pe 64-biți, iar codul a fost scris în JAVA.

Oracle Database

Oracle Database este un program ce permite gestionarea bazelor de date relaționare. Oracle stochează datele în mod logic, adică sub formă de tabele.

Acest software este disponibil în mai multe versiuni și pe mai multe sisteme de operare, ca spre exemplu:Windows, Linux. Acesta este simplu de utilizat și distribuit. [ORA14]

Oracle este foarte util pentru:

Dezvoltatori care lucrează cu Python, Java, PHP, XML;

Cei care au nevoie de o bază de date gratuită pentru a învăța si a implementa;

Instituțiile de învățământ și studenți;

Acest tool a fost utilizat pentru a creea o bază de date pentru acest proiect. Această bază de date conține utilizatori precum și informații salvate de la senzori, informații pe baza cărora se pot face grafice.

Visual Studio

Visual Studio este un tool ce include un set de instrumente de dezvoltare pentru generarea de aplicații desktop, mobile, aplicații ASP.NET. Acest IDE este scris în C++ și C#.

Acest tool este disponibil numai pe Windows și suportă următoarele limbaje de programare: C++, VB.NET, C#, F#. [VIS16]

Am ales pentru acest proiect să folosesc Visual Studio 2012, pentru a face debug pe codul ce va fi scris pe microcontroler. Acest lucru a fost posibil numai după instalarea unui plugin. Acest plugin se numește Visual Micro și are versiunea 1606.7.10.

Fritzing IDE

Fritzing IDE este un tool gratuit ce a fost dezvoltat de Universitatea de Științe Aplicate din Potsdam. Acest tool ajută dezvoltatorii oferindu-le oportunitatea de a realiza un prototip al circuitului înainte de a-l realiza fizic. [FRI16]

Codul sursă a acestui program este scris în C++ și poate fi descărcat și editat prin intermediul git-hub. Acest program este disponibil pe mai multe platforme și anume: Windows, Mac OS, Linux.

Am utilizat acest tool pentru a realiza schema hardware a aplicației practice din acest proiect și pentru asta am instalat ultima versiune a acestui tool (0.9.3b).

Arhitectura hardware

Arhitectura hardware generală a serei

În acest capitol voi prezenta arhitectura serei și componentele folosite.

Componentele cele mai importante pe care le-am folosit sunt:

Ghivece flori

Microcontroler ATMega2560

Senzori de temperatură

Senzori de umiditate

Senzori de lumină

Pompe de apă

Ventilatoare

LED-uri

Fire

Sursă de tensiune

Relee

Laptop

În schema de mai jos se poate observa modul de interconectare a tuturor componentelor utilizate. Deși în schemă nu sunt figurate sursele de alimentare (datorită faptului că schema s-ar fi încărcat prea mult), ele există și sunt una de 5V și respectiv alta de 12V.

Am ales să utilizez pentru acest proiect numai două plante, ceea ce înseamnă că vor fi folosiți câte doi senzori din fiecare tip și bineînțeles câte două componente de control din fiecare tip.

Pe lângă schema din figura 20 am mai realizat o schemă electronică (vezi Figura 21) ce a fost și ea luată în calcul atunci când am realizat asamblarea proiectului. Odată realizată schema electronică, nu a mai rămas decât aranjarea într-un mod cât mai estetic a acestor componente ce au fost dispuse pe o machetă creată pentru fiecare plantă în parte.

Figura 20. Modul de interconectare a componentelor

Figura 21. Schema electronică a proiectului

Conectarea senzorilor

Dupa cum se poate vedea în figura 22 de sus în jos primii doi senzori sunt cei de temperatură, următorii doi sunt cei de umiditate, iar ultimii sunt senzorii de lumină. Aceștia sunt conectați la placuță ca în tabelul 2

Tabelul 2. Conectarea senzorilor la plăcuță

Toți cei șase senzori au 2 intrari și 2 ieșiri după cum urmează;

VCC prin intermediul căreia se vor lega la plus;

GND prin intermediul căreia se vor lega la minus;

A0 prin intermediul căreia vor furniza date analogice;

D0 prin intermediul căreia vor furniza date digitale.

Am ales să folosesc ieșirea analogică pentru a realiza în cod interpretarea datelor recepționate. Calibrarea senzorilor s-a efectuat manual, prin teste repetate aplicate sistemului.

Toți cei șase senzori prezintă un potențiometru ce este util numai pentru ieșirea digitală și un comparator LM393. Așa cum am precizat într-un capitol anterior, senzorul de temperatură este defapt un termistor NTC, iar cel de lumină un fotorezistor.

Acești senzori sunt foarte importanți în proiect, deoarece pe baza informațiilor primite de la aceștia, se poate decide ce anume ar trebui făcut mai departe pentru a menține sera în parametrii normali.

Conectarea pompelor de apă

Am ales să utilizez o bandă de 8 relee de tipul celor din figura 24 (vor fi folosite numai 6 relee din cele 8) atât pentru conectarea pompelor cât și a ventilatoarelor, deoarece acestea au nevoie de o tensiune de alimentare mai mare de 5 V.

Așa cum am mai precizat pompele de apă sunt pompe cu roți dințate, ce vor fi alimentate la 12 V prin intermediul releelor. Releele ce vor fi folosite pentru ele se vor lega la pinul 23 respectiv pinul 25, ca în figura 23.

Releele au trei intrări respectiv și două ieșiri. Intrările sunt GND, VCC și comandă, iar cele două ieșiri vor fi active când una când cealălaltă.

Am ales să folosesc ieșirea ce este activă atunci când pinul de comandă este zero, iar cealălaltă ieșire este deconectată. Asta înseamnă că programul va trimite 1 logic atunci când nu se dorește activarea ieșirii și 0 în rest.

Conectarea ventilatoarelor

Ventilatoarele ca și pompele de apă au nevoie de curent mai mare și de aceea au fost conectate în ansamblu prin intermediul releelor. Aceste relee sunt folosite la fel cum am precizat în capitolul anterior.

După cum se poate vedea în figura 25 am utilizat două ventilatoare la care am legat două LED-uri albastre, respectiv două roșii.

Atunci când ventilatorul va fi pornit și LED-ul albastru aprins, va însemna că a fost pornită o aerotermă ce produce rece,iar atunci când LED-ul roșu va fi aprins și ventilatorul pornit va însemna că va fi pornită o aerotermă ce produce căldură. În continuare aș prefera să continui cu termenul de aeroterme. Releele ce vor porni ventilatoarele sunt conectate la Arduino la fel ca în tabelul 3.

Conectarea LED-urilor

Am folosit două LED-uri UV pentru acest proiect, deoarece ajută plantele să crească mai repede. Ele sunt folosite în acest proiect pentru a suplinii cantitatea de lumină naturală, bineînteles numai atunci când este nevoie.

Aceste LED-uri se vor lega cu anodul la pinii 22 respectiv 24, iar catodul va fi legat printr-o rezistență de 150Ω la ground (vezi figura 26). Aceste LED-uri se vor aprinde atunci când cantitatea de lumină este insuficientă.

Figura 26. Conectarea LED-urilor

Arduino Mega2560

Arduino Mega2560 este o placuță de dezvoltare ce conține un microcontroller Atmega2560. Această plăcuță dispune de 54 pini digitali de intrare/ieșire (doar 14 dintre aceștia pot fi folosiți ca PWM), 16 intrări analogice, 4 porturi seriale hardware, un oscilator cu cristal de 16 MHz, o conexiune USB, un jack de putere și un buton de resetare. [MEG14]

Specificații:

Tabelul 4. Specificații Arduino Mega

Surse de alimentare

În acest proiect sunt utilizate ca surse de alimentare urmatoarele:

Conexiunea plăcuței cu laptopul prin intermediul căreia se iau 5V;

O sursă de tensiune externă de 5V;

O sursă de tensiune externă de 12V;

De la această sursă de 5V se vor conecta defapt toți senzorii, de la cea de 12 V se vor conecta pompele de apă și ventilatoarele, iar restul componentelor inclusiv plăcuța se vor alimenta prin intermediul laptopului.

Arhitectura software

Librării utilizate

Librăria JFreeChart

Această librarie este o librarie gratuită scrisă în JAVA ce poate fi utilizată pentru a genera chart-uri, de aceea am utilizat-o în acest proiect. Scopul a fost generarea unor statistici pe baza informațiilor primite de la senzori.

Librăria JFreeChart este făcută pentru a fi utilizată spre exemplu în aplicații, servlet-uri și este distribuită cu tot codul sursă.

Tipurile de chart-uri oferite de această librarie sunt:

Grafice pie;

Grafice tip bară;

Grafice tip linie;

Grafice Gantt;

Grafice scatter, etc.

Această librărie a fost descărcată de pe următorul site ce a fost specificat în referințele web.[***01]

Dintre toate funcționalitătile pe care le are această librarie am ales să le folosesc doar pe următoarele:

Datele sunt accesibile din orice parte a implementării;

Zoom pe grafic;

Disponibilitatea pentru aplicații JAVA;

Mai multe tipuri de grafice. [GIL14]

Librăria JDBC

Această librărie este făcută pentru a permite unei aplicații JAVA să interacționeze cu o bază de date. În acest proiect am utilizat Oracle 11g împreună cu OJDBC7 ce poate fi descărcată de pe site-ul specificat în referințe.[***02]

Această librărie ne permite să:

Deschidem o conexiune;

Creeăm un obiect statement;

Rulăm o interogare;

Procesăm o interogare;

Să facem modificări în baza de date;

Să salvăm modificările;

Să închidem o conexiune. [JDBC14]

Librăria PanamaHitek_Arduino

Această librărie a fost creeată de Antony García González student al secției de inginerie electromecanică de la Universitatea Tehnologică din Panamá în scopul de a putea distribui în spaniolă cunoștiințele sale despre cele mai noi tehnologii și aplicațiile sale în inginerie. [GON14]

Librăria PanamHitek_Arduino se ocupă de realizarea comunicației și a conexiunilor cu Arduino. Conexiunea este realizată între o aplicație Java și un cod C++ ce va fi descărcat pe plăcuța Arduino. Comunicația dintre acestea se realizează serial. [GON14]

Am utilizat în acest proiect versiunea 2.7.0 a acestei librării și dintre toate funcțiile disponibile le-am folosit decât pe următoarele:

PanamaHitek_Arduino() ce este funcția constructor;

arduinoRXTX(String PORT_NAME, int DATA_RATE, SerialPortEventListener events) – utilizată pentru a deschide o conexiune atât pentru recepționarea de date cât și pentru transmiterea de date; Această funcție primește ca parametrii numele portului prin intermediul căruia Arduino este conectat la calculator, rata de transmisie, și un eveniment serial cu ajutorul căruia aplicația Java va ști că a primit un mesaj;

sendData(String data) – utilizată pentru a trimite date de la aplicația JAVA către Arduino; Această funcție primește ca parametru mesajul ce se dorește a fi trimis;

MessageAvailable() – o funcție utilizată pentru a detecta atunci când există un mesaj; Această funcție are ca tip de return boolean, ceea ce înseamnă că dacă există un mesaj return-ul va fi TRUE, iar dacă nu FALSE;

getSerialPorts() – această funcție va returna o listă de porturi disponibile;

killArduinoConnection() – va închide conexiunea cu Arduino;

printMessage() – va returna mesajul recepționat;

Această librărie a fost descărcată de pe un site specificat în anexe.[***03]

Structura bazei de date

Am ales ca proiectul meu să aibă o listă cu utilizatori, să pot salva istoricul comenzilor efectuate și să pot salva informațiile de la senzori. Și ce e mai bun pentru asta decât o bază de date.

Figura 30. Diagrama bazei de date

După cum se poate vedea în figura 30 am ales să am trei tabele. Primul tabel este cel al utilizatorilor în care se va stoca un id de utilizator, un username și o parolă și va avea ca și cheie primară username-ul ce va trebui să fie unic. Al doilea tabel este cel în care se va memora istoricul comenzilor astfel acesta va cuprinde un id, un username, o comandă executată precum și o data la care s-a executat comanda. Acest tabel are ca și cheie primară id-ul, iar cheia externă va fi username-ul.

Ultimul tabel este cel în care se vor stoca informațiile de la senzori. Acest tabel conține un id, un nume de senzor, o valoare a unui senzor precum și data salvării.

Aplicația Arduino

Aplicația Arduino este acea aplicație ce va fi descărcată pe plăcuța Arduino. Această aplicație se ocupă de configurarea pinilor precum și de scrierea/citirea pinilor.

Aplicația Arduino va primi date de la senzori și le va trimite serial către aplicația Java, dar tot odată va putea primi comenzi serial din aplicația Java. Această aplicație utilizează două funcții și anume:

Funcția setup;

Funcția loop;

În subcapitolele următoare voi explica mai în detaliu aceste funcții.

Funcția setup

Această funcție se ocupă de configurarea pinilor de intrare/ ieșire și a stabilirii valorilor default a pinilor de ieșire și se execută o singură dată, atunci când sistemul este pornit.

Lista pinilor configurați poate fi observată în tabelul 5.

Tabelul 5. Configurația pinilor

Cum am mai zis aici sunt configurate valorile default, așa că am ales ca valorile default pentru pinii ce controlează cele doua Led-uri (pinul 22 și pinul 23) sa fie LOW, iar pentru restul pinilor ce controlează componente prin intermediul releelor am ales valoarea HIGH (atunci când comanda este HIGH releul nu este cuplat).

Tot aici am configurat și seriala pe care am setat-o la un baudrate de 9600 bps.

Funcția loop

Această funcție este aceea care se execută ciclic adică pe fiecare clock al procesorului. În interiorul acesteia se realizează următoarele:

Se citesc toți pinii de intrare;

Se trimit serial valorile analogice ale acestora către aplicația Java;

Se citește seriala;

În cazul în care s-a recepționat ceva serial, se interpretează codul primit și în funcție de acest cod se iau următoarele decizii (aprinderea/stingerea Led-urilor, pornirea/oprirea pompelor de apă, pornirea/oprirea ventilatorului sau setarea modului automat/manual);

Aplicația JAVA

Aplicația Java este defapt aplicația cu care interacționează în mod direct utilizatorul. Am ales să folosesc pentru această aplicație modelul Model – View – Controller care este cel mai indicat pentru implementarea interfeței cu utilizatorul.

Figura 31. Modelul MVC

Mai departe voi descrie fiecare pachet și clasele din el.

Pachetul Model

Pachetul acesta se ocupă de gestiunea datelor și conține următoarele clase ce vor fi detaliate în subcapitolele următoare:

History

SensorValues

Users

Clasa History

Clasa History conține ca și membrii de tip public un id, un utilizator de tipul clasei Users, o comandă și o dată de timp. Prin intermediul acestei clase se va salva un istoric al aplicației, având ca și corespondent un tabel din baza de date.

Figura 32. Clasa History

Clasa SensorValues

Clasa SensorValues conține ca și membrii de tip public un id, un nume de senzor, o valuare a unui senzor și o dată de timp. Cu ajutorul acestei clase se vor putea salva valorile senzorilor.

Figura 33. Clasa SensorValue

Clasa Users

Clasa Users conține ca si membrii un id, un nume de utilizator și o parolă. Cu ajutorul acestei clase se va putea ține o evidență a utilizatorilor.

Figura 34. Clasa Users

Pachetul View

Pachetul View conține mai exacte ce poate vedea efectiv utilizatorul și conține următoarele clase:

Application

Change_password

Chart

Login

MyPainter

Register

Aceste clase vor fi detaliate în subcapitolele următoare.

Clasa Application

Această clasă se ocupă de dispunerea pe ecran a interfeței principale, din care se poate controla sera. Are ca membrii o clasă de tip SerialPort, una de timp PanamaHiteck_Arduino (această clasă face parte din librăria pe care am menționat-o), alta de tip Login și una de tip Application_listener, restul de membrii sunt panel-uri, label-uri, butoane, zone de text etc.

Această clasă are ca funcții un constructor ce se ocupă de inițializări și configurări, o funcție initComponents() ce se ocupă de setarea pozițiilor pentru toate componetele de interfață utilizate și o funcție app_start(Login login) ce face vizibilă fereastra creată de această clasă și primește ca parametru o clasă Login prin intermediul căreia se pot duce mai departe setările inițiale.

Această clasă este apelată prin intermediul clasei Login_listener ce se ocupă de interpretarea evenimentelor din clasa Login.

Figura 35. Interfața principală a aplicației

După cum se poate observa în figura 35 se află fereastra creată de această clasă. Pentru a creea tot ce se vede în imagine am folosit:

JMenuBar – pentru a creea meniul din colțul stânga sus;

JMenuItem – pentru a creea submeniurile ca în figura 36 și figura 37;

JLabel – pentru titlul aplicației, pentru a spune ce fac diverse obiecte ca spre exemplu Senzor de lumină 1, LED 2, etc. Acest JLabel a fost utilizat și pentru a afișa imaginile cu starea plantelor la un moment dat. Acest lucru a fost posibil numai prin utilizarea unei proprietăți, astfel am putut pune un icon căruia i-am atribuit calea de pe disk a pozei;

JPanel – pentru a putea împărți întreaga fereastră în mai multe subpărți ca spre exemplu partea numită Valori parametrii, partea Facilități de control etc. Pentru a putea da nume acestor părți am utilizat o proprietate a JPanel-ului și anume bordura, astfel am ales o bordură ce conține titlu;

JProgressBar – folosite pentru a afișa în procente valorile senzorilor de lumină și umiditate pentru cele două plante;

JTextField – pentru a afișa temperatura mediului pentru cele două plante;

JRadioButton – pentru a seta sistemul fie în starea automat fie în starea manual;

JButton – pentru a porni sau opri diverse componente hardware destinate reglării parametrilor serei. Aceste butoane pot fi apăsate numai atunci când sistemul se află în starea manual;

În figura 36 se poate vedea ce anume poate fi accesibil din meniul Cont, astfel dacă este apăsat submeniul:

Ieșire cont – se va închide această fereastră și se va deschide fereastra de logare;

Schimbă parola – se va deschide o fereastră în care se va putea schimba parola;

Șterge cont – se va deschide un JOptionDialog prin care se va întreba utilizatorul dacă este sigur de alegerea făcută;

Figura 37. Accesarea meniului Cont

În figura 37 se pot observa submeniurile disponibile din Meniu. Astfel dacă vom apăsa pe submeniul:

Istoric – se va deschide o fereastră în care se va putea vedea istoricul;

Statistică pentru planta 1 – se va deschide o fereastră în care se va putea observa un grafic pentru prima plantă, generat pe baza informațiiilor salvate de la senzori;

Statistică pentru planta 2 – se va deschide o fereastră în care se va putea observa un grafic pentru a doua plantă, generat pe baza informațiilor salvate de la senzori;

Ieșire – se va închide aplicația la fel ca și prin apăsarea butonului

Clasa Change_password

Clasa Change_password se ocupă de afișarea unei interfețe prin care utilizatorul își poate schimba parola. Această clasă are ca membrii o clasă de tip Application prin intemediul căreia poate accesa parola utilizatorului logat, o altă clasa de tip Change_password_listener cu ajutorul căreia se vor putea trata evenimentele apărute în fereastra generată de această clasă. Restul de membrii ai acestei clase sunt butoane, zone de text și label-uri.

Clasa aceasta are ca funcții un constructor ce se ocupă de inițializări și configurări și o funcție initComponents() ce se ocupă de setarea pozițiilor pentru toate componentele ce fac parte din această fereastră.

Această clasă este apelată prin intermediul clasei Application_listener ce se ocupă de interpretarea evenimentelor din clasa Application. Astfel fereastra generată de această clasă va fi vizibilă atunci când se va apăsa submeniul “Schimbă parola” sau prin apăsarea combinației de taste “Shift + P” din fereastra principală a aplicației.

În figura 38 se află fereastra generată de această clasă. Pentru creearea acesteia am folosit următoarele:

JLabel – pentru numele ferestrei, precum și pentru numele căsuțelor de text;

JPasswordField – pentru parole. A fost folosită această componentă, pentru a nu se vedea parola;

JButton – pentru a creea butonul “Salvează”, prin apăsarea căruia va apărea un eveniment ce va fi tratat de clasa Change_password_listener;

Clasa Chart

Clasa Chart se ocupă de afișarea unei interfețe prin care se vor putea vedea grafice. Această clasă are ca membrii o clasă de tip MYSQLCMD ce se ocupă cu executarea interogărilor către baza de date, o alta de tipul ChartPanel cu ajutorul căreia se realizează graficul, alta de tipul CategoryDataset care va reține toate datele graficului și nu în ultimul rând una de tipul Chart_listener ce se ocupă de tratarea evenimentelor acestei clase.

Clasa aceasta are ca funcții:

un constructor;

o funcție createTrace() cu ajutorul căreia se va crea un JComboBox ce va permite să fie activată/dezactivată urmărirea. Prin acest lucru se va afișa sau nu un set de axe din dreptul săgeții de la mouse;

o funcție createGraphic() cu ajutorul căreia se va crea un JComboBox ce va permite schimbarea tipului de grafic. În acest proiect sunt disponibile cinci tipuri de grafice: grafic tip bară 3D, grafic tip linie 3D, grafic tip bară, grafic tip linie, grafic tip zonă;

o funcție createZoom() cu ajutorul căreia se va crea un buton prin apăsarea căruia graficul se va autoscala pentru a fi vizibil integral;

funcție createChart() ce are ca tip de return ChartPanel. Cu ajutorul acestei funcții se va crea efectiv graficul;

o funcție createDataset() cu tipul de return CategoryDataset. În această funcție se va realiza interogarea bazei de date și preluarea datelor salvate de acolo;

o funcție rulează() cu ajutorul căreia se va afișa fereastra.

o funcție setPlant(String plant) prin apelare căreia se va ști pentru care plantă va trebui creat graficul;

Această clasă este apelată prin intermediul clasei Application_listener ce se ocupă de interpretarea evenimentelor din clasa Application. Astfel fereastra generată de această clasă va fi vizibilă atunci când se va apăsa submeniul “Statistică pentru planta 1” sau submeniul “Statistică pentru planta 2”. În funcție de butonul apăsat se va ști pentru ce plantă se va genera graficul.

Figura 42. Grafic tip linie 3D

În figura 39, 40, 41, 42, 43 se poate observa fereastra generată de această clasă. Pentru creearea acesteia am folosit următoarele:

JButton – pentru crearea butonului de autoscalare;

JComboBox – pentru crearea unei liste de acțiuni dintre care se poate alege. Acestă componentă a fost folosită pentru alegerea tipului de grafic și pentru activarea/dezactivarea urmăririi;

JPanel – pentru a pune separat butoanele de grafic;

ChartPanel – componentă a librăriei JFreeChart cu ajutorul căreia se creează graficul;

Tot în figurile menționate mai sus se observă că se poate schimba tipul graficului generat, păstrându-se aceleași date ce au fost preluate din baza de date. În figura 39 se află un grafic de tip bară 3D, în figura 40 unul de tip bară, în figura 41 unul de tip linie, în figura 42 unul tip linie 3D, iar în figura 43 un grafic tip zonă.

Clasa Login

Clasa Login se ocupă de afișarea unei interfețe prin care utilizatorul se poate loga și va putea avea acces la funcționalitățile aplicației. Această clasă are ca membrii o clasă de tipul PanamHitek_Arduino disponibilă din librăria pe care am menționat-o într-un capitol anterior, o alta de tipul Application prin intermediul căreia se va putea avea acces la funcționalitățile aplicației și o alta Login_listener ce se va ocupa de tratarea evenimentelor apărute în această clasă. Restul membrilor clasei Login sunt butoane, zone de text și label-uri.

Clasa aceasta are ca funcții un constructor ce se ocupă de inițializări și configurări, o funcție initComponents() ce se ocupă de setarea pozițiilor pentru toate componentele ce fac parte din această fereastră și o funcție main, deci aceasta este clasa din care se va porni întreaga aplicație.

Când se va rula aplicația, se va apela funcția main care va face vizibilă această fereastră.

În figura 44 se află fereastra generată de această clasă. Pentru creearea acesteia am folosit următoarele:

JLabel – pentru numele ferestrei, precum și pentru numele căsuțelor de text;

JPasswordField – pentru parola introdusă de utilizator. A fost folosită această componentă, pentru a nu se vedea parola;

JButton – pentru a creea butonul “Logare” și butonul “Înregistrare”, prin apăsarea cărora va apărea un eveniment ce va fi tratat de clasa Login_listener;

JComboBox – pentru a putea selecta portul prin care este conectată plăcuța la calculator;

Prin intermediul constructorului se mai realizează și găsirea automată a portului serial disponibil, astfel se evită apariția erorilor de conectare datorită selectării greșite a portului COM. Acest lucru se realizează cu ajutorul următoarei linii de cod:

List_of_ports.setModel(new DefaultComboBoxModel(arduino.getSerialPorts().toArray())).

Clasa MyPainter

Clasa MyPainter se ocupă de culori și este folosită pentru schimbarea culorii de la componentele de tipul progress bar. Această clasă are ca membrii o clasă de tipul Color ce reprezintă culoarea și extinde clasa AbstractRegionPainter.

Clasa aceasta are ca funcții un constructor ce se ocupă de inițializări și configurări, o funcție doPaint() ce este suprascrisă.

Clasa Register

Clasa Register se ocupă de afișarea unei interfețe prin care utilizatorul se poate înregistra în baza de date și ulterior va putea avea acces la aplicație prin intermediul noului cont creat. Această clasă are ca membrii o clasă de tipul Login ce va putea prelua din această clasă datele utilizatorului și o alta Register_listener ce se va ocupa de tratarea evenimentelor apărute în această clasă. Restul membrilor clasei Register sunt butoane, zone de text și label-uri.

Clasa aceasta are ca funcții un constructor ce se ocupă de inițializări și configurări, o funcție initComponents() ce se ocupă de setarea pozițiilor pentru toate componentele ce fac parte din această fereastră și o funcție register_start cu ajutorul căreia fereastra generată de această clasa va fi făcută vizibilă.

În figura 45 se află fereastra generată de această clasă. Pentru creearea acesteia am folosit următoarele:

JLabel – pentru numele ferestrei, precum și pentru numele căsuțelor de text;

JPasswordField – pentru parola introdusă de utilizator. A fost folosită această componentă, pentru a nu se vedea parola;

JButton – pentru a creea butonul “Înregistrare”, prin apăsarea căruia va apărea un eveniment ce va fi tratat de clasa Register_listener;

Pachetul Control

Pachetul Control conține mai exacte acele clase care se ocupă de tratarea de evenimente și conține următoarele clase:

Application_listener

Change_password_listener

Chart_listener

Login_listener

Register_listener

SerialPort_listener

Aceste clase vor fi detaliate în subcapitolele următoare.

Application_listener

Clasa Application_listener este clasa ce se ocupă de tratarea evenimentelor din clasa Application. Această clasa conține ca și membrii o clasă Application și o alta MYSQLCMD.

Clasa Application_listener implementeaza clasa MouseListener și clasa ActionListener, ceea ce înseamnă că poate trata și evenimentele primite de la mouse.

Am suprascris următoarele funcții:

mouseClicked(MouseEvent evt);

actionPerformed(ActionEvent e);

Funcția mouseClicked

Funcția mouseClicked tratează mai multe evenimente și anume:

Butonul pentru modul automat. Atunci când acest buton este apăsat se dezactivează toate butoanele din panel-ul “Facilități de control” pentru a nu mai putea fi apăsate și se trimite serial către Arduino codul pentru modul automat;

Butonul pentru modul manual. Atunci când acest buton este apăsat se vor activa toate butoanele din panel-ul “Facilități de control” și se va trimite serial către Arduino codul pentru modul manual;

Butonul de pornit pentru led-ul 1. Prin apăsarea acestuia se va schimba culoarea butonului și se va trimite un cod serial către Arduino, urmând ca led-ul pentru prima plantă să se aprindă în urma interpretării mesajului primit;

Butonul de pornit pentru led-ul 2;

Butonul de oprit pentru led-ul 1. Prin apăsarea acestuia se va schimba culoarea butonului și se va trimite serial un cod către Arduino, care va ști că led-ul va trebui stins;

Butonul de oprit pentru led-ul 2;

Butonul de pornit pentru pompa 1. Prin apăsarea acestuia se va schimba culoarea butonului și se va trimite un cod serial către Arduino care va cupla releul corespunzător aprinderii pompei de apă;

Butonul de pornit pentru pompa 2;

Butonul de oprit pentru pompa 1. După ce acest buton este apăsat se va schimba culoarea acestuia și se va decupla releul corespunzător prin trimiterea unui cod serial;

Butonul de oprit pentru pompa 2;

Butonul de pornit pentru aeroterma rece 1. În urma apăsării acestui buton se va trimite o comandă de cuplare a releului ce va permite aprinderea unui led albastru și a ventilatorului corespunzător;

Butonul de pornit pentru aeroterma rece 2;

Butonul de oprit pentru aeroterma rece 1. După apăsarea butonului se trimite codul de decuplare a releului și astfel ventilatorul și led-ul albastru corespunzător vor fi oprite;

Butonul de oprit pentru aeroterma rece 2;

Butonul de pornit pentru aeroterma caldă 1. În urma apăsării butonului se va trimite codul de cuplare a releului corespunzător și astfel se va aprinde un led roșu și ventilatorul corespunzător;

Butonul de pornit pentru aeroterma caldă 2;

Butonul de oprit pentru aeroterma rece 1. După apăsarea butonului, aplicația va trimite un cod serial ce va decupla releul corespunzator și astfel led-ul și ventilatorul vor fi oprite;

Butonul de oprit pentru aeroterma rece 2;

Funcția actionPerformed

Această funcție se ocupă de tratarea evenimentelor primite de la următoarele componente:

Butonul de “Ieșire” aflat în Meniu. Prin apăsarea acestuia, aplicația Java va executa o instrucțiune de închidere;

Butonul “Statistică pentru planta 1” aflat în Meniu. Prin apăsarea acestuia se va deschide o fereastră ce conține un grafic generat pe baza valorilor salvate de la senzorii corespunzători primei plante;

Butonul “Statistică pentru planta 2” aflat în Meniu;

Butonul “Istoric” aflat tot în Meniu. După apăsarea acestuia se va deschide o fereastră în care se va regăsii istoricul aplicației;

Butonul “Ieșire cont” din meniul Cont. În urma apăsării se va executa un cod de inactivare a ferestrei principale și de activare a ferestrei de logare;

Butonul “Schimbă parola”. După apăsare se va deschide o fereastră în care se va putea schimba parola;

Butonul “Șterge cont”. Prin apăsarea acestui buton se va executa un cod ce va deschide mai întâi o ferestră prin care utilizatorul se va putea răzgândi (vezi figura 46), în caz contrar se va șterge din baza de date contul (vezi figura 47) și se va activa fereastra de logare;

Change_password_listener

Clasa Change_password_listener este clasa ce se ocupă de tratarea evenimentelor din clasa Change_password. Această clasă conține ca și membrii o clasă Change_password și o alta MYSQLCMD.

Clasa Change_password_listener implementează clasa MouseListener ceea ce înseamnă că se vor trata evenimentele primite de la mouse.

Am suprascris numai funcția mouseClicked(MouseEvent evt). Acestă clasă poate trata numai evenimentul primit de la butonul de “Salvează”. Atunci când acest buton este apăsat se va executa o interogare ce va salva noua parolă în baza de date și se va dezactiva fereastra de schimbare a parolei. Dacă parola a fost salvată cu succes va apărea un mesaj ca în figura 48.

Chart_listener

Clasa Chart_listener este clasa care se ocupă de tratarea evenimentelor primite de la clasa Chart. Această clasă implementează o altă clasă numită ActionListener. De aceea am suprascris funcția actionPerformed(ActionEvent e).

Această clasă se ocupă de tratarea evenimentelor primite de la următoarele componente:

ComboBox-ul ce conține activarea/dezactivarea urmăririi;

ComboBox-ul ce selectează tipul de chart. Aici se realizează schimbarea tipului de chart în funcție de ce este selectat în ComboBox;

Butonul de autoscalare. Atunci când acest buton este apăsat se va executa o funcție de autoscalare disponibilă în librăria JFreeChart;

Login_listener

Clasa Login_listener este clasa ce se ocupă de tratarea evenimentelor din clasa Login. Această clasă conține ca și membrii o clasă Login și o alta MYSQLCMD.

Clasa Login_listener implementează clasa MouseListener ceea ce înseamnă că se vor trata evenimentele primite de la mouse.

Am suprascris numai funcția mouseClicked(MouseEvent evt). Acestă clasă poate trata numai evenimentul primit de la butonul de “Logare” precum și de la butonul “Înregistrare”. Atunci când butonul de logare este apăsat se va verifica corectitudina datelor introduse, iar în cazul în care ceva nu este bine va apărea un mesaj corespunzător (vezi figura 49) și se va deschide fereastra principală a aplicației. În schimb dacă se va apăsa butonul de înregistrare se va deschide fereastra de înregistrare cont.

Register_listener

Clasa Register_listener este clasa ce se ocupă de tratarea evenimentelor din clasa Register. Această clasă conține ca și membrii o clasă Register și o alta MYSQLCMD.

Clasa Register_listener implementează clasa MouseListener și se vor trata evenimentele primite de la mouse.

Am suprascris numai funcția mouseClicked(MouseEvent evt). Acestă clasă poate trata numai evenimentul primit de la butonul de “Înregistrare”. Atunci când butonul de înregistrare este apăsat se va verifica corectitudinea datelor introduse (dacă parolele coincid), iar în cazul în care ceva nu a decurs așa cum ar trebui va apărea un mesaj corespunzător (vezi figura 49). În cazul în care totul a decurs bine și datele au fost corecte va apărea un mesaj de informare conform căruia contul a fost creat, la fel ca în figura 50.

SerialPort_listener

Clasa SerialPort_listener implementează o clasă numită SerialPortEventListener și se ocupă cu tratarea evenimentelor apărute pe port, adică cu ce s-a primit serial. Această clasă conține un membru de tipul clasei Application.

Dacă s-a primit ceva pe serială atunci această clasă se va ocupa de mesajul recepționat. Plăcuța Arduino trimite serial pe o singură linie toate informațiile recepționate de la senzori. Aici se va interpreta acest mesaj luând valoarea corespunzătoare primei codări găsite. Pentru a lua întreaga valoare ce se află între două codări de senzori se vor folosi două obiecte: unul de tipul clasei Pattern și un altul de tipul clasei Matcher. Un mesaj primit serial arată astfel: L1453L2459H11023H21023T122.52T222.63

Codările utilizate sunt următoarele:

L1 – corespunzător primului senzor de lumină;

L2 – pentru cel de al doilea senzor de lumină;

H1 – corespunzător primului senzor de umiditate;

H2 – pentru informația primită de la cel de al doilea senzor de umiditate;

T1 – pentru primul senzor de temperatură;

T2 – corespunzător celui de al doilea senzor de temperatură;

Pe lângă primirea de informații această clasă se ocupă și de updatarea valorilor primite în interfața principală, de aceea este nevoie de un membru de tipul clasei Application. Elementele de tip progress bar vor avea și culori diferite în funcție de aceste valori.

Această clasă se mai ocupă de asemenea de updatarea imaginilor plantelor din interfața principală tot pe baza acestor informațiilor primite serial. Pentru asta am folosit trei poze diferite care pot fi observate în figurile 51, 52, 53 . Cele trei imagini se vor schimba în timp real.

Pachetul SQL

Pachetul SQL conține mai exacte acele clase care se ocupă de crearea conexiunii cu baza de date, executarea interogărilo. Există două clase în acest pachet și anume:

MYSQLCMD

MyConnection

Aceste clase vor fi detaliate în subcapitolele următoare.

MYSQLCMD

Clasa MYSQLCMD este clasa ce se ocupă de executarea interogărilor către baza de date și are un membru de tipul clasei Connection și un altul de tipul clasei Statement. Ca funcții această clasă are:

Funcția openconnection() – ce deschide o conexiune;

Funcția closeconnection() – ce închide o conexiune;

Funcția ArrayList<Users> get_users() – ce returnează o listă cu toți utilizatorii din baza de date;

Funcția String register(String username, String password) – ce inserează un nou utilizator în baza de date;

Funcția String update_password(String username, String password) – ce updatează parola utilizatorului logat;

Funcția String delete_account(String username) – ce șterge contul utilizatorului logat;

Funcția ArrayList<History> get_history(String username) – ce returnează istoricul aplicației;

Funcția ArrayList<SensorValues> get_SensorValues() – ce returnează valorile senzorilor deja salvate în baza de date;

Funcția String insert_history(String username, String command) – ce inserează în tabelul History o nouă înregistrare;

Funcția String insert_sensorValues(ArrayList<SensorValues> sensorValues) – ce inserează în tabelul SensorValues o nouă înregistrare;

MyConnection

Clasa MyConnection este clasa care conține datele de conectare către Oracle și clasa care returnează o conexiune pe baza acestor date. Funcția care realizează acest lucru se numește Connection getConnection().

Concluzii

Proiectul de licență a fost ales pentru a facilita întreținerea unei sere, astfel prin acest sistem care se ocupă de controlarea parametrilor, se va evita prezența umană.

Pornind de la obiectivele proiectului, am început dezvoltarea unei platforme capabile să îndeplinească toate aceste cerințe. În plus scopul proiectului este de a arăta că pentru un astfel de proiect se pot utiliza cunoștințe din mai multe domenii (ca de exemplu: bazele electrotehnicii, programarea microcontroller-elor, programarea orientată pe obiect, inginerie software, medii de programare vizuală, electronică, etc.) precum și alte tehnologii.

Prima etapă în dezvoltarea proiectului a fost selectarea componentelor și realizarea unei machete provizorii ce am utilizat-o pentru testarea funcționalitaților. Astfel în acest pas am conectat microcontroller-ul cu senzorii, cu LED-urile precum și cu pompele de apă, urmând ulterior să atașez la această machetă și senzorii de temperatură, precum și ventilatoarele.

Următoarea etapă a constat în scrierea unui cod capabil să recepționeze informațiile primite de la senzori și să le scrie pe serială, de unde vor putea fi folosite mai departe de aplicația Java. Tot aici a trebuit să se calibreze valorile senzorilor, deoarece senzorii au fost conectați la porturi analogice. În funcție de valorile pe care le-au dat senzorii în diferite circumstanțe a fost posibilă calibrarea lor. Acestă parte a fost realizată în aplicația Arduino.

Ulterior am reușit integrarea senzorilor de temperatură și a ventilatoarelor atât în aplicația Arduino cât și în aplicația JAVA. A urmat după asta o etapă de găsire a eventuale probleme și rezolvarea acestora. Iar în final nu a mai rămas decât de făcut macheta finală a proiectului, documentația și prezentarea finală.

În acest proiect am investit mult suflet și am vrut să iasă ceva cât mai bun de pe urma tuturor cunoștințelor dobândite în urma facultății. De asemenea am vrut să combin în acest proiect tot ce imi place mie mai mult. Astfel am revenit la o veche pasiune de a mea, desenatul realizând imaginile cu cele trei plante. Și de ce nu aș putea să zic că și tema proiectului este o veche pasiune de a mea adică grădinăritul și cum majoritatea nu avem timp pentru asemenea lucruri, dar totuși am vrea o gradină cât mai frumoasă sau am vrea să mâncăm cât mai sănătos, acest proiect s-a potrivit ca o mănușe.

Aș vrea să continui acest proiect prin extinderea lui pe mai multe plante, eventual să pot controla parametrii serei în funcție de tipurile de plante și de ce nu, să le și pot supraveghea online pe bază unor camere de filmat. Aș putea extinde aplicația astfel încât să nu mai fie decât desktop, eventual o aplicație web sau o aplicație pe mobil.

Bibliografie

[DUM06] – Bazele sistemelor mecatronice Curs, Adrian Dumitriu, Brașov, 2006

[DIN08] – Echipamente și sisteme hidropneumatice de bord, Liviu Dincă, Editura Universitaria, Craiova, 2008

[STE04] – Fizica Atmosferei, vremea si clima, Sabina Stefan, Editura Universității din București, 2004

[MAR10] – Ghid practic de programare în C, MARIAN Gheorghe, MARIAN Marius – Adrian, ENESCU Nicolae, DUMITRAȘCU Eugen, Editura UNIVERSITARIA, Craiova, 2010

[JDBC14] – Oracle Database JDBC Developer’s Guide 12c Release 1 (12.1), 2014

[GIL14] – The JFreeChart Class Library Version 1.0.19 Installation Guide, David Gilbert, 2014

Referințe web

[LAU12] – Laurean Bogdan, Microcontrolere Introducere, disponibil via web la adresa

http://web.ulbsibiu.ro/laurean.bogdan/html/Microcontrolere%20introducere.pdf

[CIO03] – Andrei Ciorba, Introducere în microcontrollere, disponibil via web la adresa

http://andrei.clubcisco.ro/cursuri/3pm/lab1.pdf

[ATM14] – Atmel Atmega640/V-1280/V-1281/V-2560/V-2561/V, disponibil via web la adresa

http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

[ARD16] – Arduino, disponibil via web la adresa

https://ro.wikipedia.org/wiki/Arduino

[VOR09]- Liliana Vornicu, Senzori și traductoare, disponibil via web la adresa

http://ep.etc.tuiasi.ro/index_sen.html

[REL11] – Relee și declanșatoare, disponibil via web la adresa

http://elth.ucv.ro/student1/Cursuri/Echipamente%20electrice%20I/Laborator/Studiul%20releelor%20si%20declansatoarelor.pdf

[NAG05] – Ștefan Nagy, Ventilatoare și instalații de ventilare, disponibil via web la adresa

http://test.mrxl.ro/joomla/images/Cursuri/uem/Cap5.pdf

[NET16] – NetBeans, disponibil via web la adresa

https://en.wikipedia.org/wiki/NetBeans

[ORA14] – Oracle Database 11g Express Edition, disponibil via web la adresa

http://www.oracle.com/technetwork/database/database-technologies/express-edition/overview/index.html

[VIS16] – Microsoft Visual Studio, disponibil via web la adresa

https://en.wikipedia.org/wiki/Microsoft_Visual_Studio

[FRI16] – Fritzing, disponibil via web la adresa

https://en.wikipedia.org/wiki/Fritzing

[MEG14] – Arduino Mega 2560, disponibil via web la adresa

http://www.geeetech.com/wiki/index.php/Arduino_Mega_2560

[GON14] – Panama Hiteck, disponibil via web la adresa

Inicio

[REG16] – Regular expressions, disponibil via web la adresa

http://www.tutorialspoint.com/java/java_regular_expressions.htm

[***01] disponibil via web la adresa

http://jaist.dl.sourceforge.net/project/jfreechart/1.%20JFreeChart/1.0.19/

[***02] disponibil via web la adresa

http://www.oracle.com/technetwork/database/features/jdbc/jdbc-drivers-12c-download-1958347.html

[***03] disponibil via web la adresa

https://sourceforge.net/projects/arduinoyjava/files/v2.7.0/

[***04] disponibil via web la adresa

https://docs.oracle.com/javase/tutorial/jdbc/basics/

[***05] disponibil via web la adresa

http://playground.arduino.cc/ComponentLib/Thermistor2

Livrările proiectului

Arhitectura generală a serei

Schema electronică a serei

Codul Sursă

În această anexă voi selecta doar anumite pasaje din cod, restul se va găsi pe CD-ul/DVD-ul atașat acestei lucrări.

Aplicația Arduino

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

int input = 'A';

int old_input;

int state = 1; // Automatic_state = 1; Manual_state == 0;

int light_sensorValue1 = 0;

int light_sensorValue2 = 0;

int humidity_sensorValue1 = 0;

int humidity_sensorValue2 = 0;

float temperature_sensorValue1 = 0;

float temperature_sensorValue2 = 0;

float old_temperature_sensorValue1 = 0;

float old_temperature_sensorValue2 = 0;

long previous_time = 0;

unsigned long current_time = 0;

long interval = 1000;

void setup ()

{

pinMode(22,OUTPUT); /* The Led for the plant 1*/

pinMode(24,OUTPUT); /* The Led for the plant 2*/

pinMode(23,OUTPUT); /* The pump for plant 1*/

pinMode(25,OUTPUT); /* The pump for plant 2*/

pinMode(26,OUTPUT); /* The heating fan for plant 1*/

pinMode(27,OUTPUT); /* The cooling fan for plant 1*/

pinMode(28,OUTPUT); /* The heating fan for plant 2*/

pinMode(29,OUTPUT); /* The cooling fan for plant 2*/

pinMode(0,INPUT); /*Light sensor for plant 1*/

pinMode(1,INPUT); /*Light sensor for plant 2*/

pinMode(2,INPUT); /*Humidity sensor for plant 1*/

pinMode(3,INPUT); /*Humidity sensor for plant 2*/

pinMode(4,INPUT); /*Temperature sensor for plant 1*/

pinMode(5,INPUT); /*Temperature sensor for plant 2*/

digitalWrite(22,LOW);

digitalWrite(24,LOW);

digitalWrite(23,HIGH);

digitalWrite(25,HIGH);

digitalWrite(26,HIGH);

digitalWrite(27,HIGH);

digitalWrite(28,HIGH);

digitalWrite(29,HIGH);

Serial.begin(9600);

}

void loop()

{

long previous_timer_L1 = 0;

long current_timer_L1 = 0;

long previous_timer_L2 = 0;

long current_timer_L2 = 0;

long interval_timer = 1;

float cal = 4.8;

light_sensorValue1 = analogRead(0);

light_sensorValue2 = analogRead(1);

humidity_sensorValue1 = analogRead(2);

humidity_sensorValue2 = analogRead(3);

temperature_sensorValue1 = analogRead(4);

temperature_sensorValue2 = analogRead(5);

for(int i=0;i<7;i++)

{

temperature_sensorValue1 += analogRead(4);

}

temperature_sensorValue1 = temperature_sensorValue1/8;

for(int i=0;i<7;i++)

{

temperature_sensorValue2 += analogRead(5);

}

temperature_sensorValue2 = temperature_sensorValue2/8;

temperature_sensorValue1 = map(temperature_sensorValue1, 0, 1023, 1023, 0);

temperature_sensorValue1 = log(((10240000 / temperature_sensorValue1) – 10000));

temperature_sensorValue1 = 1 / (0.001129148 + (0.000234125 * temperature_sensorValue1) + (0.0000000876741 * temperature_sensorValue1 * temperature_sensorValue1 * temperature_sensorValue1)); //Cube! [***05]

temperature_sensorValue1 = temperature_sensorValue1 – 273.15;

temperature_sensorValue1 = temperature_sensorValue1 -21;

temperature_sensorValue2 = map(temperature_sensorValue2, 0, 1023, 1023, 0);

temperature_sensorValue2 = log(((10240000 / temperature_sensorValue2) – 10000));

temperature_sensorValue2 = 1 / (0.001129148 + (0.000234125 * temperature_sensorValue2) + (0.0000000876741 * temperature_sensorValue2 * temperature_sensorValue2 * temperature_sensorValue2)); //Cube! [***05]

temperature_sensorValue2 = temperature_sensorValue2 – 273.15;

temperature_sensorValue2 = temperature_sensorValue2 -21;

if(abs(temperature_sensorValue1 – old_temperature_sensorValue1)>0.5)

{

old_temperature_sensorValue1 = temperature_sensorValue1;

}

if(abs(temperature_sensorValue2 – old_temperature_sensorValue2)>0.5)

{

old_temperature_sensorValue2 = temperature_sensorValue2;

}

current_time = millis();

if(current_time – previous_time >interval)

{

previous_time = current_time;

Serial.print("L1");

Serial.print(light_sensorValue1);

Serial.print("L2");

Serial.print(light_sensorValue2);

Serial.print("H1");

Serial.print(humidity_sensorValue1);

Serial.print("H2");

Serial.print(humidity_sensorValue2);

Serial.print("T1");

Serial.print(old_temperature_sensorValue1);

Serial.print("T2");

Serial.println(old_temperature_sensorValue2);

}

if(old_input!=10)

input=old_input;

switch(input)

{

case 'A':

state = 1;

if(light_sensorValue1<300)

{

digitalWrite(22,LOW);

}

else

if(light_sensorValue1>=300 && light_sensorValue1<=500)

{

current_timer_L1 = micros();

if(current_timer_L1 – previous_timer_L1 > interval_timer)

{

previous_timer_L1 = current_timer_L1;

int ledPin = digitalRead(22);

digitalWrite(22, !ledPin);

}

}

else

{

digitalWrite(22, HIGH);

}

if(light_sensorValue2<300)

{

digitalWrite(24,LOW);

}

else

if(light_sensorValue2>=300 && light_sensorValue2<=500)

{

current_timer_L2 = micros();

if(current_timer_L2 – previous_timer_L2 > interval_timer)

{

previous_timer_L2 = current_timer_L2;

int ledPin = digitalRead(24);

digitalWrite(24, !ledPin);

}

}

else

{

digitalWrite(24, HIGH);

}

if( humidity_sensorValue1<=440 )

{

digitalWrite(23,HIGH);

}

else

{

if( humidity_sensorValue1>=460 )

digitalWrite(23, LOW);

}

if( humidity_sensorValue2<=440 )

{

digitalWrite(25,HIGH);

}

else

{

if( humidity_sensorValue2>=460 )

digitalWrite(25,LOW);

}

if( temperature_sensorValue1>10 && temperature_sensorValue1<35)

{

digitalWrite(26,HIGH);

digitalWrite(27,HIGH);

}

else

{

if(temperature_sensorValue1<=10)

digitalWrite(26, LOW);

else

digitalWrite(27,LOW);

}

if( temperature_sensorValue2>10 && temperature_sensorValue2<35)

{

digitalWrite(28,HIGH);

digitalWrite(29,HIGH);

}

else

{

if( temperature_sensorValue2<=10)

digitalWrite(28,LOW);

else

digitalWrite(29,LOW);

}

break;

case 'M':

state =0;

digitalWrite(22,LOW);

digitalWrite(23,HIGH);

digitalWrite(24,LOW);

digitalWrite(25,HIGH);

digitalWrite(26,HIGH);

digitalWrite(27,HIGH);

digitalWrite(28,HIGH);

digitalWrite(29,HIGH);

break;

}

if(state == 0)

{

//LED1

if( input == '0')

digitalWrite(22,HIGH);

if( input == '1')

digitalWrite(22,LOW);

//LED2

if( input == '2')

digitalWrite(24,HIGH);

if( input == '3')

digitalWrite(24,LOW);

//Pump1

if( input == '4')

digitalWrite(23,LOW);

if( input == '5')

digitalWrite(23,HIGH);

//Pump2

if( input == '6')

digitalWrite(25,LOW);

if( input == '7')

digitalWrite(25,HIGH);

//Heatingfan1

if( input == '8')

digitalWrite(26,LOW);

if( input == '9')

digitalWrite(26,HIGH);

//Coolingfan1

if( input == 'q')

digitalWrite(27,LOW);

if( input == 'w')

digitalWrite(27,HIGH);

// Heatingfan2

if( input == 'e')

digitalWrite(28,LOW);

if( input == 'r')

digitalWrite(28,HIGH);

//Coolingfan2

if( input == 't')

digitalWrite(29,LOW);

if( input == 'y')

digitalWrite(29,HIGH);

}

if ( Serial.available()>0 )

{

old_input = Serial.read();

}

}

Aplicația Java

Chart_listener.java

package Control;

import View.Chart;

import static View.Chart.plant;

import java.awt.Color;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import org.jfree.chart.ChartFactory;

import org.jfree.chart.JFreeChart;

import org.jfree.chart.plot.CategoryPlot;

import org.jfree.chart.plot.PlotOrientation;

public class Chart_listener implements ActionListener {

Chart chart;

public Chart_listener(Chart chart) {

this.chart = chart;

}

@Override

public void actionPerformed(ActionEvent e) {

if (e.getSource() == chart.trace) {

if (chart.traceCmds[0].equals(chart.trace.getSelectedItem())) {

chart.chartPanel.setHorizontalAxisTrace(true);

chart.chartPanel.setVerticalAxisTrace(true);

chart.chartPanel.repaint();

} else {

chart.chartPanel.setHorizontalAxisTrace(false);

chart.chartPanel.setVerticalAxisTrace(false);

chart.chartPanel.repaint();

}

}

if (e.getSource() == chart.type) {

JFreeChart ch = null;

if (chart.chartType[0].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createBarChart3D("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else

if (chart.chartType[1].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createLineChart3D("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else

if (chart.chartType[2].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createBarChart("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else

if (chart.chartType[3].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createLineChart("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else

if (chart.chartType[4].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createAreaChart("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

}

CategoryPlot plot = ch.getCategoryPlot();

plot.setBackgroundPaint(Color.white);

plot.getRenderer().setSeriesPaint(0, Color.RED);

plot.getRenderer().setSeriesPaint(1, Color.GREEN);

plot.getRenderer().setSeriesPaint(2, Color.BLUE);

chart.chartPanel.setChart(ch);

}

if (e.getSource() == chart.auto) {

chart.chartPanel.restoreAutoBounds();

}

}

}

SerialPort_listener.java

package Control;

import View.Application;

import View.MyPainter;

import gnu.io.SerialPortEvent;

import gnu.io.SerialPortEventListener;

import java.awt.Color;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import javax.swing.ImageIcon;

import javax.swing.UIDefaults;

public class SerialPort_listener implements SerialPortEventListener {

Application app;

SerialPort_listener(Application app) {

this.app = app;

}

@Override

public void serialEvent(SerialPortEvent spe) {

if (app.arduino.MessageAvailable() == true) {

String msg = app.arduino.printMessage();

if (msg.contains("L1")) {

String msg1 = msg;

Pattern pattern = Pattern.compile("L1(.*?)L2");

Matcher matcher = pattern.matcher(msg1);

while (matcher.find()) {

msg1 = matcher.group(1);

}

app.light_sensor1_status.setValue((1000 – Integer.parseInt(msg1)) / 10);

app.light_sensor1_status.setString((1000 – Integer.parseInt(msg1)) / 10 + " %");

if (((1000 – Integer.parseInt(msg1)) / 10) <= 30) {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));

app.light_sensor1_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.light_sensor1_status.putClientProperty("Nimbus.Overrides", defaults);

} else {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));

app.light_sensor1_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.light_sensor1_status.putClientProperty("Nimbus.Overrides", defaults);

}

}

if (msg.contains("L2")) {

String msg1 = msg;

Pattern pattern = Pattern.compile("L2(.*?)H1");

Matcher matcher = pattern.matcher(msg1);

while (matcher.find()) {

msg1 = matcher.group(1);

}

app.light_sensor2_status.setValue((1000 – Integer.parseInt(msg1)) / 10);

app.light_sensor2_status.setString((1000 – Integer.parseInt(msg1)) / 10 + " %");

if (((1000 – Integer.parseInt(msg1)) / 10) <= 50) {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));

app.light_sensor2_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.light_sensor2_status.putClientProperty("Nimbus.Overrides", defaults);

} else {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));

app.light_sensor2_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.light_sensor2_status.putClientProperty("Nimbus.Overrides", defaults);

}

}

if (msg.contains("H1")) {

String msg1 = msg;

Pattern pattern = Pattern.compile("H1(.*?)H2");

Matcher matcher = pattern.matcher(msg1);

while (matcher.find()) {

msg1 = matcher.group(1);

}

if ((1000 – Integer.parseInt(msg1)) / 10 >= 0 && (1000 – Integer.parseInt(msg1)) / 10 <= 100) {

app.humidity_sensor1_status.setValue((1000 – Integer.parseInt(msg1)) / 10);

app.humidity_sensor1_status.setString((1000 – Integer.parseInt(msg1)) / 10 + " %");

if ((((1000 – Integer.parseInt(msg1)) / 10) < 50) || (((1000 – Integer.parseInt(msg1)) / 10) > 70)) {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));

app.humidity_sensor1_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.humidity_sensor1_status.putClientProperty("Nimbus.Overrides", defaults);

} else {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));

app.humidity_sensor1_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.humidity_sensor1_status.putClientProperty("Nimbus.Overrides", defaults);

}

}

}

if (msg.contains("H2")) {

String msg1 = msg;

Pattern pattern = Pattern.compile("H2(.*?)T1");

Matcher matcher = pattern.matcher(msg1);

while (matcher.find()) {

msg1 = matcher.group(1);

}

if ((1000 – Integer.parseInt(msg1)) / 10 >= 0 && (1000 – Integer.parseInt(msg1)) / 10 <= 100) {

app.humidity_sensor2_status.setValue((1000 – Integer.parseInt(msg1)) / 10);

app.humidity_sensor2_status.setString((1000 – Integer.parseInt(msg1)) / 10 + " %");

if ((((1000 – Integer.parseInt(msg1)) / 10) < 50) || (((1000 – Integer.parseInt(msg1)) / 10) > 70)) {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));

app.humidity_sensor2_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.humidity_sensor2_status.putClientProperty("Nimbus.Overrides", defaults);

} else {

UIDefaults defaults = new UIDefaults();

defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.GREEN));

defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.GREEN));

app.humidity_sensor2_status.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);

app.humidity_sensor2_status.putClientProperty("Nimbus.Overrides", defaults);

}

}

}

if (msg.contains("T1")) {

String msg1 = msg;

Pattern pattern = Pattern.compile("T1(.*?)T2");

Matcher matcher = pattern.matcher(msg1);

while (matcher.find()) {

msg1 = matcher.group(1);

}

app.temperature_sensor1_status.setText("" + (float) Math.round(Float.valueOf(msg1) * 10) / 10);

}

if (msg.contains("T2")) {

String msg1 = msg;

Pattern pattern = Pattern.compile("T2(.*?)$");

Matcher matcher = pattern.matcher(msg1);

while (matcher.find()) {

msg1 = matcher.group(1);

}

app.temperature_sensor2_status.setText("" + (float) Math.round(Float.valueOf(msg1) * 10) / 10);

}

if (app.humidity_sensor1_status.getValue() < 50 || Float.valueOf(app.temperature_sensor1_status.getText()) > 35) {

ImageIcon icon = null;

icon = new ImageIcon(getClass().getClassLoader().getResource("Images/dryplant.jpg"));

app.image_label1.setIcon(icon);

} else if (app.humidity_sensor1_status.getValue() > 70 || Float.valueOf(app.temperature_sensor1_status.getText()) < 10 || app.light_sensor1_status.getValue() <= 30) {

ImageIcon icon = null;

icon = new ImageIcon(getClass().getClassLoader().getResource("Images/deficiency.jpg"));

app.image_label1.setIcon(icon);

} else {

ImageIcon icon = null;

icon = new ImageIcon(getClass().getClassLoader().getResource("Images/normalplant.jpg"));

app.image_label1.setIcon(icon);

}

if (app.humidity_sensor2_status.getValue() < 50 || Float.valueOf(app.temperature_sensor2_status.getText()) > 35) {

ImageIcon icon = null;

icon = new ImageIcon(getClass().getClassLoader().getResource("Images/dryplant.jpg"));

app.image_label2.setIcon(icon);

} else if (app.humidity_sensor2_status.getValue() > 70 || Float.valueOf(app.temperature_sensor2_status.getText()) < 10 || app.light_sensor2_status.getValue() <= 30) {

ImageIcon icon = null;

icon = new ImageIcon(getClass().getClassLoader().getResource("Images/deficiency.jpg"));

app.image_label2.setIcon(icon);

} else {

ImageIcon icon = null;

icon = new ImageIcon(getClass().getClassLoader().getResource("Images/normalplant.jpg"));

app.image_label2.setIcon(icon);

}

}

}

}

Chart_listener.java

package Control;

import View.Chart;

import static View.Chart.plant;

import java.awt.Color;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import org.jfree.chart.ChartFactory;

import org.jfree.chart.JFreeChart;

import org.jfree.chart.plot.CategoryPlot;

import org.jfree.chart.plot.PlotOrientation;

public class Chart_listener implements ActionListener {

Chart chart;

public Chart_listener(Chart chart) {

this.chart = chart;

}

@Override

public void actionPerformed(ActionEvent e) {

if (e.getSource() == chart.trace) {

if (chart.traceCmds[0].equals(chart.trace.getSelectedItem())) {

chart.chartPanel.setHorizontalAxisTrace(true);

chart.chartPanel.setVerticalAxisTrace(true);

chart.chartPanel.repaint();

} else {

chart.chartPanel.setHorizontalAxisTrace(false);

chart.chartPanel.setVerticalAxisTrace(false);

chart.chartPanel.repaint();

}

}

if (e.getSource() == chart.type) {

JFreeChart ch = null;

if (chart.chartType[0].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createBarChart3D("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else if (chart.chartType[1].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createLineChart3D("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else if (chart.chartType[2].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createBarChart("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else if (chart.chartType[3].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createLineChart("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

} else if (chart.chartType[4].equals(chart.type.getSelectedItem())) {

ch = ChartFactory.createAreaChart("Statistica pentru planta " + chart.plant, "Data", "Valoare", chart.roiData, PlotOrientation.VERTICAL, true, true, false);

}

CategoryPlot plot = ch.getCategoryPlot();

plot.setBackgroundPaint(Color.white);

plot.getRenderer().setSeriesPaint(0, Color.RED);

plot.getRenderer().setSeriesPaint(1, Color.GREEN);

plot.getRenderer().setSeriesPaint(2, Color.BLUE);

chart.chartPanel.setChart(ch);

}

if (e.getSource() == chart.auto) {

chart.chartPanel.restoreAutoBounds();

}

}

}

Change_password_listener.java

package Control;

import SQL.MYSQLCMD;

import View.Change_password;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.sql.SQLException;

import java.util.logging.Level;

import java.util.logging.Logger;

import javax.swing.JOptionPane;

public class Change_password_listener implements MouseListener {

MYSQLCMD sqlcmd;

Change_password change;

public Change_password_listener(Change_password change) {

this.change = change;

}

@Override

public void mouseClicked(MouseEvent e) {

if (e.getSource() == change.save_button) {

String response = "";

if (change.password.getText().equals(change.confirmPassword.getText())) {

try {

sqlcmd = new MYSQLCMD();

response = sqlcmd.update_password(change.app.username, change.password.getText());

} catch (SQLException ex) {

Logger.getLogger(Register_listener.class.getName()).log(Level.SEVERE, null, ex);

}

if (response.contains("done")) {

JOptionPane.showMessageDialog(change, "Modificarea a fost salvata!", "Succes", JOptionPane.INFORMATION_MESSAGE);

change.setVisible(false);

} else

JOptionPane.showMessageDialog(change, "A aparut o eroare. Mai incearca!", "Eroare", JOptionPane.ERROR_MESSAGE);

} else

JOptionPane.showMessageDialog(change, "Parolele sunt diferite!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

}

@Override

public void mousePressed(MouseEvent e) {

}

@Override

public void mouseReleased(MouseEvent e) {

}

@Override

public void mouseEntered(MouseEvent e) {

}

@Override

public void mouseExited(MouseEvent e) {

}

}

Login_listener.java

package Control;

import SQL.MYSQLCMD;

import Model.Users;

import View.Login;

import View.Register;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.util.ArrayList;

import java.util.logging.Level;

import java.util.logging.Logger;

import javax.swing.JOptionPane;

public class Login_listener implements MouseListener {

Login login;

SerialPort_listener evt;

MYSQLCMD sqlcmd;

public Login_listener(Login login) {

this.login = login;

}

@Override

public void mouseClicked(MouseEvent e) {

if (e.getSource() == login.Login_button) {

try {

sqlcmd = new MYSQLCMD();

boolean connect = false;

ArrayList<Users> users = sqlcmd.get_users();

int i;

for (i = 0; i < users.size(); i++) if (login.nickname.getText().equals(users.get(i).getUsername())) {

if (login.password.getText().equals(users.get(i).getPassword())) {

login.app.app_start(login);

login.app.username = login.nickname.getText();

login.app.password = login.password.getText();

login.app.account_menu.setText("Cont: " + login.nickname.getText());

login.setVisible(false);

evt = new SerialPort_listener(login.app);

login.arduino.arduinoRXTX((String) login.List_of_ports.getSelectedItem(), 9600, evt);

connect = true;

break;

}

}

if (connect != true && i >= users.size())

JOptionPane.showMessageDialog(login, "Numele de utilizator sau parola sunt incorecte!", "Eroare", JOptionPane.ERROR_MESSAGE);

} catch (Exception ex) {

Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);

}

}

if (e.getSource() == login.register_button) {

Register register = new Register(login);

login.setVisible(false);

register.register_start();

}

}

@Override

public void mousePressed(MouseEvent e) {

}

@Override

public void mouseReleased(MouseEvent e) {

}

@Override

public void mouseEntered(MouseEvent e) {

}

@Override

public void mouseExited(MouseEvent e) {

}

}

Register_listener.java

package Control;

import SQL.MYSQLCMD;

import View.Register;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.sql.SQLException;

import java.util.logging.Level;

import java.util.logging.Logger;

import javax.swing.JOptionPane;

public class Register_listener implements MouseListener {

Register register;

MYSQLCMD sqlcmd;

public Register_listener(Register register) {

this.register = register;

}

@Override

public void mouseClicked(MouseEvent e) {

if (e.getSource() == register.register_button) {

String response = "";

if (register.password.getText().equals(register.confirmPassword.getText())) {

try {

sqlcmd = new MYSQLCMD();

response = sqlcmd.register(register.nickname.getText(), register.password.getText());

} catch (SQLException ex) {

Logger.getLogger(Register_listener.class.getName()).log(Level.SEVERE, null, ex);

}

if (response.contains("Account")) {

JOptionPane.showMessageDialog(register, "Contul a fost creeat!", "Cont creat", JOptionPane.INFORMATION_MESSAGE);

register.setVisible(false);

register.login.setVisible(true);

register.login.nickname.setText(register.nickname.getText());

register.login.password.setText(register.password.getText());

} else

JOptionPane.showMessageDialog(register, "A aparut o eroare. Mai incearca!", "Eroare", JOptionPane.ERROR_MESSAGE);

} else

JOptionPane.showMessageDialog(register, "Parolele sunt diferite!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

}

@Override

public void mousePressed(MouseEvent e) {

}

@Override

public void mouseReleased(MouseEvent e) {

}

@Override

public void mouseEntered(MouseEvent e) {

}

@Override

public void mouseExited(MouseEvent e) {

}

}

MYSQLCMD.java

package SQL;

import Model.History;

import Model.SensorValues;

import Model.Users;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;

public class MYSQLCMD {

public Statement statement = null;

public Connection dbConnection = null;

public MYSQLCMD() {

}

public void openconnection() {

try {

MyConnection mc = new MyConnection();

dbConnection = mc.getConnection();

statement = dbConnection.createStatement();

} catch (SQLException e) {

}

}

public void closeconnection() {

try {

if (statement != null) {

statement.close();

}

if (dbConnection != null) {

dbConnection.close();

}

} catch (SQLException e) {

}

}

public ArrayList<Users> get_users() throws SQLException {

ArrayList<Users> users = new ArrayList();

try {

openconnection();

if (dbConnection != null) {

ResultSet rs = statement.executeQuery("select * from users");

while (rs.next()) {

Users user = new Users(rs.getInt("Id"), rs.getString("username"), rs.getString("password"));

users.add(user);

}

}

} catch (SQLException e) {

}

closeconnection();

return users;

}

public String register(String username, String password) throws SQLException {

String response = "";

try {

openconnection();

if (dbConnection != null) {

Boolean rs = statement.execute(" DECLARE\n" + "idmax NUMBER;\n" + " \n" + " BEGIN\n" + " SELECT max(id) INTO idmax FROM users;\n" + " if idmax IS NULL then\n" + " idmax := 1;\n" + " end if;\n" + " insert into users (id,username,password) values (idmax+1,'" + username + "','" + password + "');\n" + " END;");

if (rs == false) {

response = "Account created!";

} else {

response = "Try again!";

}

}

} catch (SQLException e) {

System.out.println("catch");

response = "Error in the database!";

}

closeconnection();

return response;

}

public String update_password(String username, String password) throws SQLException {

String response = "";

try {

openconnection();

if (dbConnection != null) {

Boolean rs = statement.execute("update users set password='" + password + "' where username='" + username + "'");

if (rs == false) {

response = "Update done!";

} else {

response = "Try again!";

}

}

} catch (SQLException e) {

response = "Error in the database!";

}

closeconnection();

return response;

}

public String delete_account(String username) throws SQLException {

String response = "";

try {

openconnection();

if (dbConnection != null) {

Boolean rs = statement.execute("delete from history where username='" + username + "'");

rs = statement.execute("delete from users where username='" + username + "'");

if (rs == false) {

response = "Account deleted!";

}

}

} catch (SQLException e) {

response = "Error in the database!";

}

closeconnection();

return response;

}

public ArrayList<History> get_history(String username) throws SQLException {

ArrayList<History> history = new ArrayList();

try {

openconnection();

if (dbConnection != null) {

ResultSet rs = statement.executeQuery("select * from history where username = '" + username + "' order by time desc");

while (rs.next()) {

History history_1 = new History(rs.getInt("Id"), rs.getString("username"), rs.getString("command"), rs.getString("time"));

history.add(history_1);

}

}

} catch (SQLException e) {

}

closeconnection();

return history;

}

public ArrayList<SensorValues> get_SensorValues() throws SQLException {

ArrayList<SensorValues> sensorvalues = new ArrayList();

try {

openconnection();

if (dbConnection != null) {

ResultSet rs = statement.executeQuery("select * from (select * from sensorvalues order by time desc) where rownum<=50");

while (rs.next()) {

SensorValues sensorvalue = new SensorValues(rs.getInt("Id"), rs.getString("sensorname"), rs.getInt("sensorvalue"), rs.getString("time"));

sensorvalue.time = sensorvalue.time.substring(0, 15);

sensorvalues.add(sensorvalue);

}

}

} catch (SQLException e) {

}

closeconnection();

return sensorvalues;

}

public String insert_history(String username, String command) throws SQLException {

String response = "";

try {

openconnection();

if (dbConnection != null) {

Boolean rs = statement.execute("DECLARE\n" + "id_max NUMBER;\n" + "BEGIN\n" + "SELECT max(id) INTO id_max FROM history;\n" + "if id_max IS NULL then\n" + "id_max := 1;\n" + "end if;\n" + "insert into history (id,username,time,command) values (id_max +1 ,'" + username + "',TO_CHAR(SYSTIMESTAMP),'" + command + "');\n" + "END;");

if (rs == false) {

response = "Istoric salvat!";

} else {

response = "Comanda nu a fost salvata in istoric!";

}

}

} catch (SQLException e) {

System.out.println("catch");

response = "Eroare in baza de date!";

}

closeconnection();

return response;

}

public String insert_sensorValues(ArrayList<SensorValues> sensorValues) throws SQLException {

String response = "";

try {

openconnection();

if (dbConnection != null) {

for (int i = 0; i < sensorValues.size(); i++) {

Boolean rs = statement.execute("DECLARE\n" + "id_max NUMBER;\n" + "BEGIN\n" + "SELECT max(id) INTO id_max FROM sensorvalues;\n" + "if id_max IS NULL then\n" + "id_max := 1;\n" + "end if;\n" + "insert into sensorvalues(id,sensorname,sensorvalue,time) values (id_max +1 ,'" + sensorValues.get(i).SensorName + "'," + sensorValues.get(i).SensorValue + ",TO_CHAR(SYSTIMESTAMP));\n" + "END;");

if (rs == false) {

response = "Valorile senzorilor au fost salvate!";

} else {

response = "Nu s-a realizat salvarea valorilor date de senzori.";

}

}

}

} catch (SQLException e) {

System.out.println("catch");

response = "Eroare in baza de date!";

}

closeconnection();

return response;

}

}

MyConnection.java

package SQL;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

public class MyConnection {

public Connection connection;

public int port = 1521;

public String SID = "XE";

public String sqlServer = "oracle.jdbc.driver.OracleDriver";

String localhost = "localhost";

String user = "STOIGE1";

String password = "BubuRoz_15";

public MyConnection() {

}

public Connection getConnection() {

try {

Class.forName(sqlServer);

} catch (ClassNotFoundException e) {

System.out.println("Driver-ul MySql nu a fost gasit");

}

connection = null;

try {

String select = "jdbc:oracle:thin:@" + localhost + ":" + port + ":" + SID;

connection = DriverManager.getConnection(select, user, password);

} catch (SQLException e) {

System.out.println("Nu exista baza de date sau localhost-ul");

}

return connection;

}

}

CD / DVD

În această anexă, este atașată versiunea electronică a aplicației, a acestei lucrări, precum și prezentarea finală a tezei.

Index

A

Arduino IDE 16

ATmega2560 6

B

Bibliografie 57

C

CUPRINSUL xi

F

Fritzing IDE 19

L

LED-uri 12

Librăria JDBC 29

Librăria JFreeChart 28

Librăria PanamaHitek 30

LISTA FIGURILOR xiii

LISTA TABELELOR xv

N

NetBeans IDE 17

O

Oracle Database 18

P

Pompe hidraulice 14

R

Referințe web 58

Relee 13

S

Senzori 9

V

Ventilatoare 15

Visual Studio 18

Similar Posts