Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2024:sseverin:doru_vlad.gheorghiu [2024/04/29 20:50]
doru_vlad.gheorghiu
pm:prj2024:sseverin:doru_vlad.gheorghiu [2024/05/27 10:26] (current)
doru_vlad.gheorghiu
Line 5: Line 5:
 ---- ----
  
-Proiectul constă în realizarea unui sistem care să monitorizeze **umiditatea solului** uneia sau mai multor plante, iar când solul se usucă sub un anumit prag, sistemul o să **ude automat** pământul. În paralel, sistemul va măsura **temperatura ​și altitudinea** locului în care este plasat, informațiile fiind **afișate pe un ecran LCD**.+Proiectul constă în realizarea unui sistem care să monitorizeze **umiditatea solului** uneia sau mai multor plante, iar când solul se usucă sub un anumit prag, sistemul o să **ude automat** pământul. În paralel, sistemul va măsura **temperatura** locului în care este plasat, informațiile fiind **afișate pe un ecran LCD**.
  
 <note tip> <note tip>
-Sistemul folosește un **senzor de umiditate a solului** care este înfipt în pământ, măsurătorile fiind trimise analogic către un **microcontroler**. Pentru a uda pământul am folosit o **pompă de apă**, alimentată separat prin o **baterie de 9V**, care este așezată într-un **compartiment umplut cu suficientă apă**. Pe **ecranul LCD** sunt afișate temperatura, altitudinea ​și umiditatea solului (în procente).+Sistemul folosește un **senzor de umiditate a solului** care este înfipt în pământ, măsurătorile fiind trimise analogic către un **microcontroler**. Pentru a uda pământul am folosit o **pompă de apă**, alimentată separat prin o **baterie de 9V**, care este așezată într-un **compartiment umplut cu suficientă apă**. Pe **ecranul LCD** sunt afișate temperatura și umiditatea solului (în procente).
 </​note>​ </​note>​
  
Line 24: Line 24:
   - Microcontrolerul citește datele senzorului de umiditate a solului și a senzorului de temperatură și umiditate.   - Microcontrolerul citește datele senzorului de umiditate a solului și a senzorului de temperatură și umiditate.
   - Dacă citirea analogică a senzorului de umiditate depășește un threshold setat, se încearcă pornirea pompei de apă.   - Dacă citirea analogică a senzorului de umiditate depășește un threshold setat, se încearcă pornirea pompei de apă.
-  - Dacă, de asemenea, butonul pentru pornirea pompei de apă este setat pe ON, se pornește pompa de apă până când umiditatea ​scade sub threshold.+  - Dacă, de asemenea, butonul pentru pornirea pompei de apă este setat pe ON, se pornește pompa de apă până când măsuratoarea analogică ​scade sub threshold.
   - Datele sunt afișate pe ecranul LCD   - Datele sunt afișate pe ecranul LCD
   - Se repetă procesul în loop până când microcontrolerul este deconectat de la sursa de curent.   - Se repetă procesul în loop până când microcontrolerul este deconectat de la sursa de curent.
  
-{{:​pm:​prj2024:​sseverin:​diagrama.png?​700x400|General Diagram}}+{{:​pm:​prj2024:​sseverin:​diagrama_gheorghiu_vlad.png?​700x400|General Diagram}}
  
 === Hardware Design === === Hardware Design ===
Line 37: Line 37:
   * **Arduino Uno** (Microcontrolerul sistemului. Nu este neapărat cel mai bun microcontroler pentru genul de proiect cu multe module, într-un use case real aș fi folosit un ESP, dar am reușit un workaround pentru a evita dificultăți în care se blochează un modul)   * **Arduino Uno** (Microcontrolerul sistemului. Nu este neapărat cel mai bun microcontroler pentru genul de proiect cu multe module, într-un use case real aș fi folosit un ESP, dar am reușit un workaround pentru a evita dificultăți în care se blochează un modul)
 {{:​pm:​prj2024:​sseverin:​arduino-uno.jpg?​150x150|Arduino Uno}} {{:​pm:​prj2024:​sseverin:​arduino-uno.jpg?​150x150|Arduino Uno}}
-  * **Accelerometru și giroscop MPU6050** (Folosit pentru măsurarea temperaturii ​și altitudinii. Deși nu îi folosesc capacitățile de accelerometru și giroscop, este capabil de cerințele actuale și poate fi ușor înlocuit cu un modul BME datorită comunicării I2C)+  * **Accelerometru și giroscop MPU6050** (Folosit pentru măsurarea temperaturii. Deși nu îi folosesc capacitățile de accelerometru și giroscop, este capabil de cerințele actuale și poate fi ușor înlocuit cu un modul BME datorită comunicării I2C)
 {{:​pm:​prj2024:​sseverin:​mpu6050.jpeg?​150x150|MPU6050}} {{:​pm:​prj2024:​sseverin:​mpu6050.jpeg?​150x150|MPU6050}}
   * **Probă sol FC-28** (Proba este înfiptă în solul de lângă plantă, la o adâncime suficientă cât să acopere toți senzorii (găurile de pe limbi) pentru o măsurătoare precisă. Dacă această adâncime nu este atinsă, poate fi introdus și la un unghi. Proba este conectată la modulul LM393)   * **Probă sol FC-28** (Proba este înfiptă în solul de lângă plantă, la o adâncime suficientă cât să acopere toți senzorii (găurile de pe limbi) pentru o măsurătoare precisă. Dacă această adâncime nu este atinsă, poate fi introdus și la un unghi. Proba este conectată la modulul LM393)
Line 43: Line 43:
   * **Senzor umiditate sol LM393** (Acest modul recepționează semnalul de la probă, este interpretat,​ apoi măsurătoarea este trimisă printr-un semnal analogic la microcontroler într-o valoare între 0 și 1023)   * **Senzor umiditate sol LM393** (Acest modul recepționează semnalul de la probă, este interpretat,​ apoi măsurătoarea este trimisă printr-un semnal analogic la microcontroler într-o valoare între 0 și 1023)
 {{:​pm:​prj2024:​sseverin:​lm393_soil_moisture_sensor.png?​150x200|LM393 Soil Humidity Sensor}} {{:​pm:​prj2024:​sseverin:​lm393_soil_moisture_sensor.png?​150x200|LM393 Soil Humidity Sensor}}
-  * **Ecran LCD 1602** (Pe acest ecran vor fi afișate informațiile senzorilor. În colțul stânga-sus,​ va fi temperatura în grade Celsius, dreapta-sus altitudinea în metri, iar stânga-jos umiditatea în procente)+  * **Ecran LCD 1602** (Pe acest ecran vor fi afișate informațiile senzorilor. În colțul stânga-sus,​ va fi temperatura în grade Celsius, iar stânga-jos umiditatea în procente)
 {{:​pm:​prj2024:​sseverin:​lcd-screen-1602.jpg?​150x150|1602 LCD Screen}} {{:​pm:​prj2024:​sseverin:​lcd-screen-1602.jpg?​150x150|1602 LCD Screen}}
   * **Interfață I2C LCM1602** (Modulul este lipit de ecranul LCD și are rolul de a simplifica comunicarea cu acesta. Deoarece ecranul are 16 pini, legarea tuturor constituie lipirea multor fire și complicarea diagramei electrice. Prin adăugarea modulului, reducem numărul de pini la 4 și simplificăm semnificativ diagrama prin comunicarea cu I2C)   * **Interfață I2C LCM1602** (Modulul este lipit de ecranul LCD și are rolul de a simplifica comunicarea cu acesta. Deoarece ecranul are 16 pini, legarea tuturor constituie lipirea multor fire și complicarea diagramei electrice. Prin adăugarea modulului, reducem numărul de pini la 4 și simplificăm semnificativ diagrama prin comunicarea cu I2C)
Line 61: Line 61:
   * **1x Rezistor 220 Ohm** (Rezistența LED-ului ce previne arderea lui)   * **1x Rezistor 220 Ohm** (Rezistența LED-ului ce previne arderea lui)
 {{:​pm:​prj2024:​sseverin:​220-ohm-resistor.jpg?​200x150|220 Ohm Resistor}} {{:​pm:​prj2024:​sseverin:​220-ohm-resistor.jpg?​200x150|220 Ohm Resistor}}
-  ​* **1x Rezistor 1K Ohm** (Rezistență de pull-down pentru butonul tactil) +  * **1x Buton tactil** (Butonul este folosit pentru a opri sau porni pompa de apă. L-am adăugat pentru cazul în care se dorește scoaterea probei de sol și mutarea ei la altă plantă. Astfel, previne pornirea pompei atunci când proba este scoasă din pământ, sau mai exact, când umiditatea scade brusc. Butonul leagă un pin al plăcuței Arduino pus la pull-up de GND și pinul detectează schimbările semnalului)
-{{:​pm:​prj2024:​sseverin:​1k-ohm-resistor.jpg?​200x150|1k Ohm Resistor}} +
-  ​* **1x Buton tactil** (Butonul este folosit pentru a opri sau porni pompa de apă. L-am adăugat pentru cazul în care se dorește scoaterea probei de sol și mutarea ei la altă plantă. Astfel, previne pornirea pompei atunci când proba este scoasă din pământ, sau mai exact, când umiditatea scade brusc. Butonul leagă un pin al plăcuței Arduino pus la pull-up de GND)+
 {{:​pm:​prj2024:​sseverin:​tactile-push-button.jpg?​150x150|Tactile Push Button}} {{:​pm:​prj2024:​sseverin:​tactile-push-button.jpg?​150x150|Tactile Push Button}}
  
 == Electric Design == == Electric Design ==
-{{:​pm:​prj2024:​sseverin:​gheorghiu_vlad_electric_design.png?​600x600|Electrical ​Design}} +{{:​pm:​prj2024:​sseverin:​electric_design_gheorghiu_vlad.png?​600x600|Electric ​Design}}
-<note tip> +
-Componentele sistemului sunt lipite pe o plăcuță de proiectare (sau cel puțin componentele care pot fi lipite). De asemenea, am încercat să modularizez cât mai mult partea hardware, mai exact prin posibilitatea deconectării cu ușurință a componentelor pentru înlocuirea lor) +
-</​note>​+
 === Software Design === === Software Design ===
 ---- ----
 +
 +Bibliotecile folosite sunt:
 +   * **Arduino.h** (Biblioteca standard pentru Arduino)
 +   * **Adafruit_Sensor.h** (Biblioteca pentru a folosi senzori Adafruit)
 +   * **Adafruit_MPU6050.h** (Biblioteca pentru a folosi senzorul MPU6050)
 +   * **LiquidCrystal_I2C.h** (Biblioteca pentru a folosi ecranul LCD 1602 folosind interfața I2C)
 +
 +Prezentarea codului:
 +<​code>​
 +void setup() {
 +  Serial.begin(9600);​
 +
 +  pinMode(buttonPin,​ INPUT_PULLUP);​
 +  attachInterrupt(digitalPinToInterrupt(buttonPin),​ turnPumpOnOff,​ CHANGE);
 +  pinMode(rainPin,​ INPUT); ​
 +  pinMode(relayPin,​ OUTPUT);
 +
 +  bool status;
 +  status = mpu.begin();  ​
 +  if (!status) {
 +    Serial.println("​Could not find a valid MPU6050 sensor, check wiring!"​);​
 +    while (1);
 +  }
 +
 +  lcd.init();
 +  lcd.backlight();​
 +}
 +</​code>​
 +   * În **setup()**,​ setăm pinii în felul următor:
 +     * **buttonPin** (pinul butonului de pe care citim schimbările) la **INPUT_PULLUP** (adică valoarea pinului rămâne VCC și vom citi de pe el). De asemenea, vom folosi pinul pentru a genera întreruperi,​ astfel că la fiecare schimbare (**CHANGE**) a semnalului, se va apela funcția **turnPumpOnOff()**. Astfel, când apăsăm butonul, semnalul de pe pin este tras de la VCC la GND și microcontrolerul va genera o întrerupere. <​code>​
 +void turnPumpOnOff() {
 +  buttonFlag = 1;
 +}
 +</​code>​
 +     * **rainPin** (pinul analogic al senzorului de umiditate a solului) la **INPUT** (vom citi semnalele analogice ale senzorului).
 +     * **relayPin** (pinul releului) la **OUTPUT** (vom porni și opri releul care acționează la rândul lui pompa).
 +<note tip>
 +În **turnPumpOnOff()** doar vom seta flag-ul că s-a apăsat butonul.
 +</​note>​
 +   * Pe urmă, pornim senzorul de temperatură și ecranul LCD.
 +   * În funcția **loop()**:
 +     * Vom citi măsurătorile făcute de MPU6050 (vom folosi doar măsurătorile temperaturii) <​code>​
 +  sensors_event_t a, g, temp;
 +  mpu.getEvent(&​a,​ &g, &temp);
 +</​code>​
 +     * Vom verifica dacă butonul a fost apăsat, iar dacă **buttonFlag == 1**, vom face debouncing pe buton și vom inversa flagul de pornire a pompei (**pumpToggle**) <​code>​
 +  if((millis() - previousPress) > buttonDebounce && buttonFlag)
 +  {
 +    previousPress = millis();
 +    if(digitalRead(buttonPin) == LOW && previousState == HIGH)
 +    {
 +      pumpToggle =! pumpToggle;
 +      Serial.println("​pressed button"​);​
 +      previousState = LOW;
 +    }
 +    ​
 +    else if(digitalRead(buttonPin) == HIGH && previousState == LOW)
 +    {
 +      previousState = HIGH;
 +    }
 +    buttonFlag = 0;
 +  }
 +</​code>​
 +     * Citim valoarea analogică a senzorului de umiditate a solului și o convertim în procente. Dacă valoarea este mai mare de un threshold stabilit (**thresholdValue = 40** în acest caz), planta nu trebuie udată și setez pinul releului pe **LOW**. Dacă valoarea este mai mare decât threshold-ul,​ vom verifica dacă flag-ul pompei (**pumpToggle**) este pornit, iar dacă este, setăm pinul releului pe **HIGH** și pompa se va porni, alimentându-se de la baterie. <​code>​ double sensorValue = (1023 - analogRead(rainPin)) * (100.0 / 1023);
 +  if (sensorValue > thresholdValue) {
 +    Serial.print(sensorValue);​
 +    Serial.println("​ - Doesn'​t need watering"​);​
 +    digitalWrite(relayPin,​ LOW);
 +  }
 +  else if (pumpToggle) {
 +    Serial.print(sensorValue);​
 +    Serial.println("​ - Time to water your plant"​);​
 +    digitalWrite(relayPin,​ HIGH);
 +  } else if (!pumpToggle) {
 +    digitalWrite(relayPin,​ LOW);
 +  }
 +</​code>​
 +     * De asemenea, vom scrie pe pin-ul de PWM al LED-ului valoarea senzorului de umiditate, scalată astfel încât să fie vizibilă schimbarea. Dacă pământul este umed, LED-ul va lumina mai puțin. <​code>​ analogWrite(pwmPin,​ 255 - sensorValue * 3.7); </​code>​
 +     * În final, scriem pe ecranul LCD valorile obținute. <​code>​ lcd.setCursor(0,​ 0);
 +  lcd.print("​Temp:​ ");
 +  lcd.print(temp.temperature);​
 +  lcd.print("​ C");
 +  lcd.setCursor(0,​ 1);
 +  lcd.print("​Humidity:​ ");
 +  lcd.print(sensorValue);​
 +  lcd.print("​%"​);​
 +
 +  delay(100);
 +  lcd.clear();​
 + </​code>​
  
 === Rezultate Obținute === === Rezultate Obținute ===
 ---- ----
 +[[https://​www.youtube.com/​shorts/​szFKygTQOv0|Rezultate Obţinute]]
  
 === Concluzii === === Concluzii ===
 ---- ----
 +
 +A fost un proiect din care am învățat destul de multe și mi-am solidificat cunoștințe de hardware. Am avut câteva probleme care m-au făcut să caut mai amănunțit informații despre cum funcționează unele componente și consider că a fost un milestone pentru mine să realizez sistemul acesta.
  
 === Download === === Download ===
 ---- ----
  
-=== Jurnal === +{{:​pm:​prj2024:​sseverin:​proiect_pm.zip|}}
-----+
  
 === Bibliografie/​Resurse === === Bibliografie/​Resurse ===
pm/prj2024/sseverin/doru_vlad.gheorghiu.1714413007.txt.gz · Last modified: 2024/04/29 20:50 by doru_vlad.gheorghiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0