Table of Contents

Mist Wise

  • Nume: Bădîrcea Alexandru-Mădălin
  • Grupa: 331CB

Introducere

Mist Wise este definiția confortului îmbinat cu tehnologia. Proiectul constă într-un umidificator automat care transformă atmosfera casei tale într-o oază de prospețime și relaxare, un dispozitiv inteligent care îți monitorizează și reglează automat nivelul de umiditate din cameră, creând un mediu optim pentru sănătate și bunăstare.

Ideea a luat naștere de la observația că nivelul de umiditate din aer poate avea un impact semnificativ asupra concentrării. Am câștigat recent la un concurs un umidifcator și l-am folosit în camera de cămin. După câteva zile, mi-am dat seama de beneficiile importante ale acestuia. Oricine și-ar dori un mediu cat mai confortabil pentru lucru și tot odata mai sanătos.

Descriere generală

Schema bloc

Placuța de dezvoltare va fi alimentată de la o sursă de alimentare de 24V, astfel că va fi necesar un modul de coborâre a tensiunii pentru a furniza 5V către componentele sensibile. Modulul de coborâre a tensiunii (LM2596) va transforma tensiunea de 24V în 5V, asigurând o alimentare stabilă și protejată pentru Arduino UNO și alte componente electronice.

Sistemul va colecta date de la doi senzori principali: un senzor de umiditate DHT22 și un potențiometru. Senzorul de umiditate va monitoriza constant nivelul de umiditate din cameră și va trimite aceste date către Arduino. Potențiometrul va permite utilizatorului să seteze manual nivelul de umiditate dorit. Arduino va interpreta valoarea ajustată de potențiometru și o va compara cu datele de la senzorul DHT22.

Valorile de umiditate măsurate vor fi stocate pe un card microSD, permițând astfel păstrarea unui istoric al nivelurilor de umiditate. Modulul microSD comunică cu Arduino prin protocolul SPI, asigurând transferul eficient și fiabil al datelor.

Când nivelul de umiditate din cameră scade sub pragul setat de utilizator, Arduino va activa atomizatorul ultrasonic prin intermediul unui MOSFET. Atomizatorul ultrasonic va transforma apa în vapori, umidificând aerul din cameră. Pentru a asigura o distribuție uniformă a vaporilor, un ventilator de 12V va fi activat simultan, controlat de Arduino prin semnale PWM.

Starea sistemului va fi semnalizată vizual prin intermediul a trei LED-uri:

Pe ecranul LCD conectat la Arduino vor fi afișate diferite mesaje în funcție de starea sistemului. În timpul funcționării normale, ecranul va afișa nivelul curent de umiditate și un mesaj care indică îmbunătățirea umidității în cameră. Dacă sistemul nu este activ, ecranul va afișa istoricul nivelurilor de umiditate stocate pe cardul microSD, oferind utilizatorului o imagine de ansamblu asupra fluctuațiilor de umiditate din timp.

Hardware Design

Pini Conectati
Alte conexiuni

Software Design

Pentru dezvoltarea proiectului am ales folosirea mediului de dezvoltare Arduino IDE.

Biblioteci folosite:

  • DHT: Biblioteca DHT este folosită pentru citirea datelor de la senzorul de umiditate și temperatură DHT22.
  • Wire: Biblioteca Wire este utilizată pentru comunicarea I2C, necesară pentru afișajul LCD.
  • SPI și SD: Aceste biblioteci sunt esențiale pentru comunicarea cu cardul SD, permițând stocarea datelor de la senzor pentru analiza ulterioară.
  • LiquidCrystal_I2C: Biblioteca LiquidCrystal_I2C simplifică interacțiunea cu afișajele LCD bazate pe I2C

Elementul de noutate al proiectului Mist Wise constă în integrarea armonioasă a mai multor funcționalități, precum monitorizarea și controlul automat al umidității, stocarea datelor istorice pe un card SD și afișarea informațiilor pe un LCD. Utilizând un senzor DHT22, un potențiometru și un atomizator ultrasonic controlat prin MOSFET, sistemul ajustează automat nivelul de umiditate pentru a menține un mediu optim. LED-urile de stare și interfața user-friendly oferă feedback vizual și acces facil la datele de umiditate. Acest proiect inovativ aduce un confort sporit și un mediu sănătos în orice cameră.

Implementare software:

#define DHTPIN 7      // Pinul la care este conectat senzorul
#define DHTTYPE DHT22 // AM2302 este echivalent cu DHT22
DHT dht(DHTPIN, DHTTYPE); // Inițializarea senzorului DHT
 
#define LED_RED 8 // Pinul la care este conectat LED-ul roșu
#define LED_BLUE 9 // Pinul la care este conectat LED-ul albastru
#define LED_YELLOW 10 // Pinul la care este conectat LED-ul galben
 
#define MOSFET_PIN 2 // Pinul la care este conectat MOSFET-ul
 
LiquidCrystal_I2C lcd(0x27, 16, 2); // Inițializarea LCD-ului
 
const int chipSelect = 4; // Pinul la care este conectat cardul SD
int pot; // Valoarea citită de la potențiometru
File dataFile; // Fișierul pentru scrierea datelor
void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(MOSFET_PIN, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_YELLOW, OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  digitalWrite(MOSFET_PIN, 0);
 
  // Initializarea cardului SD
  if(!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("Card initialized.");
 
  // Deschiderea fișierului pentru scriere
  dataFile = SD.open("datalog.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.println("Potentiometer, Temperature, Humidity");
    dataFile.close();
  } else {
    Serial.println("Error opening datalog.csv");
  }
 
  // Inițializarea comunicării I2C
  Wire.begin();
 
  // Inițializarea LCD-ului
  lcd.init();
  lcd.begin(16, 2);
  lcd.backlight();
 
  // Curățarea conținutului fișierului
  clearFileContent("datalog.csv");
}
void loop() {
  // Citirea umidității și a temperaturii
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // Verificarea dacă citirile sunt valide
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
 
  // Afișarea rezultatelor
  Serial.print("Umiditate: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" *C");
 
  pot = analogRead(A0);
  pot = round(pot / 200.0) * 200;
  int partNumber = pot / 200;
  Serial.print("Potentiometer: ");
  Serial.println(pot);
  Serial.println(partNumber);
 
  writeDataToFile("datalog.csv", partNumber, t, h);
 
 
  int humidityThreshold = 0;
  switch (partNumber) {
    case 1: humidityThreshold = 30; break;
    case 2: humidityThreshold = 40; break;
    case 3: humidityThreshold = 50; break;
    case 4: humidityThreshold = 60; break;
    case 5: humidityThreshold = 70; break;
    default: humidityThreshold = 0; break;
  }
 
   // Controlul MOSFET-ului și LED-urilor
  if (h < humidityThreshold) {
    digitalWrite(MOSFET_PIN, HIGH);  // Pornește MOSFET-ul
    digitalWrite(LED_RED, HIGH);     // Aprinde LED-ul roșu
    digitalWrite(LED_BLUE, LOW);     // Stinge LED-ul albastru
    digitalWrite(LED_YELLOW, LOW);   // Stinge LED-ul galben
  } else {
    digitalWrite(MOSFET_PIN, LOW);   // Oprește MOSFET-ul
    digitalWrite(LED_RED, LOW);      // Stinge LED-ul roșu
    digitalWrite(LED_BLUE, HIGH);    // Aprinde LED-ul albastru
    digitalWrite(LED_YELLOW, HIGH);  // Aprinde LED-ul galben
  }
 
  if (digitalRead(LED_YELLOW) == HIGH) {
    lcd.clear();
    float avgTemp = 0.0;
    float avgHum = 0.0;
    int numEntries = 0;
 
    calculateAverageFromFile("datalog.csv", avgTemp, avgHum, numEntries);
 
    lcd.setBacklight(HIGH);
    lcd.setCursor(0, 0);
    lcd.print("Humidity & Temp");
    lcd.setCursor(0, 1);
    lcd.print("HISTORY");
    delay(3000);
    lcd.setCursor(0, 0);
    lcd.print("Avg Temp:");
    lcd.print(avgTemp);
    lcd.print("*C");
    lcd.setCursor(0, 1);
    lcd.print("Avg Hum:");
    lcd.print(avgHum);
    lcd.print("%");
    delay(5000);  // Afișează media timp de 5 secunde
  } else {
    lcd.setBacklight(LOW);
    lcd.clear();
  }
}

Functii auxiliare:

void clearFileContent(const char *fileName) {
  // Sterge fișierul dacă există
  if (SD.exists(fileName)) {
    SD.remove(fileName);
    Serial.print("File removed: ");
    Serial.println(fileName);
  } else {
    Serial.print("File does not exist: ");
    Serial.println(fileName);
  }
 
  // Creează un fișier nou
  File file = SD.open(fileName, FILE_WRITE);
  if (file) {
    file.println("Potentiometer, Temperature, Humidity"); // Adaugă antetul
    Serial.print("New file created: ");
    Serial.println(fileName);
    file.close();
  } else {
    Serial.print("Error creating file: ");
    Serial.println(fileName);
  }
}
void writeDataToFile(const char *fileName, int pot, float temp, float hum) {
  // Deschide fișierul pentru scriere
  File file = SD.open(fileName, FILE_WRITE);
  if (file) {
    // Scrie datele în fișier
    file.print(pot);
    file.print(", ");
    file.print(temp);
    file.print(", ");
    file.println(hum);
    file.close();
  } else {
    Serial.print("Error opening file: ");
    Serial.println(fileName);
  }
}
void calculateAverageFromFile(const char *fileName, float &avgTemp, float &avgHum, int &numEntries) {
  File file = SD.open(fileName, FILE_READ);
  if (file) {
    float tempSum = 0.0; // Suma temperaturilor
    float humSum = 0.0; // Suma umidităților
    int count = 0; // Numărul de înregistrări
    bool isHeader = true;
 
    while (file.available()) {
      String line = file.readStringUntil('\n');
      if (isHeader) {
        isHeader = false; // Ignoră antetul
        continue;
      }
 
      int firstComma = line.indexOf(','); // Găsește prima virgulă
      int secondComma = line.indexOf(',', firstComma + 1);
      int thirdComma = line.indexOf(',', secondComma + 1);
 
      if (firstComma > 0 && secondComma > 0) { // Verifică dacă sunt date valide
        float temp = line.substring(firstComma + 2, secondComma).toFloat();
        float hum = line.substring(secondComma + 2, line.length()).toFloat();
 
        tempSum += temp;
        humSum += hum;
        count++;
      }
    }
 
    file.close();
 
    if (count > 0) {
      avgTemp = tempSum / count;
      avgHum = humSum / count;
      numEntries = count;
    } else {
      avgTemp = 0.0;
      avgHum = 0.0;
      numEntries = 0;
    }
  } else {
    Serial.print("Error opening file for reading: ");
    Serial.println(fileName);
  }
}

Proiectul Mist Wise integrează trei noțiuni esențiale învățate în laboratoare: ADC, SPI și I2C. Citirea valorii de la potențiometru se realizează prin funcția analogRead(A0) utilizând ADC, care convertește semnalul analogic într-o valoare digitală pentru setarea pragurilor de umiditate. Protocolul SPI este folosit pentru comunicarea cu cardul SD, permițând stocarea și citirea datelor de umiditate și temperatură prin funcții precum SD.begin(chipSelect) și SD.open(), asigurând un istoric al valorilor măsurate. I2C este utilizat pentru comunicarea cu afișajul LCD, iar funcțiile Wire.begin(), lcd.init() și lcd.print() permit afișarea în timp real a stării sistemului și a valorilor de umiditate și temperatură. Aceste noțiuni fundamentale demonstrează aplicarea practică a cunoștințelor dobândite în laboratoare.

Rezultate Obţinute

Concluzii

În final, proiectul a atins un stadiu care poate fi îmbunătățit cu mai multe funcționalități, însă aspectul general a fost realizat. Sunt foarte mulțumit de proiect, punctul forte al acestuia fiind independența față de laptop și faptul că îl voi putea folosi și pe parcursul verii ce urmează. Am întâmpinat câteva probleme la lucrul cu 24V, reușind să ard o placuță, modulul de coborâre nefiind setat corespunzător. O altă problema ar fi, integritatea circuitului ar trebui îmbunătățită, jumperele nefiind suficient de sigure, fiind necesară o atenție sporită la transport. Ca și îmbunătățiri imediate ce pot fi aduse proiectului, ar fi un ventilator de 24V, pentru un randament mult mai bun al aparatului.

Lăsând la o parte micile probleme și provocări, experiența de lucru la proiectul Mist Wise a fost extrem de plăcută și unică. După ce am depășit dificultățile inițiale și am înțeles cum funcționează toate componentele, am abordat fiecare etapă cu entuziasm. Satisfacția de a vedea proiectul final funcționând și de a ști că am creat ceva util pentru viața de zi cu zi este îmbucurătoare. Acest proiect nu doar că mi-a îmbunătățit considerabil abilitățile tehnice, dar mi-a oferit și o profundă satisfacție personală și o experiență valoroasă de învățare.

Download

mist_wise.zip

Jurnal

02.05.2024 - Comandare piese
05.05.2024 - Creare pagină și adăugare introducere, descriere generală, componente folosite
08.05.2024 - Verificarea funcționalității pieselor
17.05.2024 - Completarea milestone-ului HARDWARE
19.05.2024 - Realizarea codului
24.05.2024 - Completarea milestone-ului SOFTWARE

Bibliografie/Resurse