This shows you the differences between two versions of the page.
pm:prj2025:avaduva:adina.zugravescu [2025/05/14 10:59] adina.zugravescu [Hardware Design] |
pm:prj2025:avaduva:adina.zugravescu [2025/05/29 18:03] (current) adina.zugravescu [Download] |
||
---|---|---|---|
Line 77: | Line 77: | ||
LiquidCrystal_I2C.h – pentru controlul afișajului LCD 1602 cu interfață I2C | LiquidCrystal_I2C.h – pentru controlul afișajului LCD 1602 cu interfață I2C | ||
- | **Structura logică și funcționarea sistemului** | + | **Descrierea codului aplicației:** |
- | * Sistemul este organizat pe bază de stări logice: standby → activare → finalizare → revenire. \\ | + | Codul monitorizează un senzor IR digital pentru a detecta prezența unei mâini. La detecție, se pornește un ventilator controlat prin PWM timp de 60 de secunde. Afișajul LCD conectat prin I2C arată un countdown, iar în ultimele 8 secunde viteza ventilatorului scade treptat (PWM: 150, 100, 50). După încheiere, ventilatorul se oprește și se afișează mesajul „Done!”, urmat de revenirea la starea „Ready”. |
- | * În starea de standby, se monitorizează constant ieșirea digitală a senzorului IR pentru a detecta prezența unei mâini (cu digitalRead). \\ | + | |
- | * La declanșare, se trece în starea de uscare: se pornește ventilatorul folosind un semnal PWM aplicat unui tranzistor MOSFET. \\ | + | |
- | * Este folosită o structură de temporizare software cu millis(), ce permite măsurarea duratei fără blocarea execuției. \\ | + | |
- | * Pe toată durata uscării, LCD-ul este actualizat continuu cu un countdown. \\ | + | |
- | * După expirarea celor 60 de secunde, sistemul oprește ventilatorul, afișează mesajul „Done!” și revine în starea inițială („Ready”). \\ | + | |
- | **Definiții, Variabile și Funcții:** | + | **Algoritmi și structuri implementate:** |
- | #define FAN_PIN 3 | + | * Sistem pe stări logice: standby → activare → rampă PWM → finalizare → standby \\ |
- | pinul D3 de pe Arduino este utilizat pentru controlul ventilatorului | + | * Temporizare non-blocantă cu millis() folosită pentru countdown și control treptat al ventilatorului \\ |
- | | + | * Control PWM gradual: analogWrite() cu valori 200 → 150 → 100 → 50 în ultimele 8 secunde \\ |
- | #define SENSOR_PIN 2 | + | * Afișare dinamică pe LCD: mesajele și countdown-ul sunt actualizate în timp real \\ |
- | pinul D2 de pe Arduino primește semnalul digital de la senzorul IR | + | * Optimizare a mesajelor transmise în Serial Monitor: evitarea afișărilor redundante \\ |
- | + | ||
- | LiquidCrystal_I2C lcd(0x27, 16, 2) | + | |
- | obiect care controlează un afișaj LCD 1602 conectat prin interfață I2C, cu adresa 0x27 | + | |
- | | + | |
- | bool drying | + | |
- | indică dacă sistemul se află în starea activă de uscare | + | |
- | unsigned long startTime | + | **Funcții implementate:** |
- | momentul în care a început uscarea | + | * setup(): configurarea pinilor, inițializarea LCD și Serial Monitor |
+ | <code> | ||
+ | pinMode(FAN_PIN, OUTPUT); // Set FAN_PIN as an output pin for controlling the fan | ||
+ | pinMode(SENSOR_PIN, INPUT); // Set SENSOR_PIN as an input for reading sensor data | ||
+ | analogWrite(FAN_PIN, 0); // (PWM 0%) | ||
+ | |||
+ | lcd.init(); | ||
+ | lcd.backlight(); | ||
+ | lcd.setCursor(5, 0); | ||
+ | lcd.print("Ready"); // Display "Ready" on the LCD initially | ||
+ | |||
+ | // Start serial monitor for debugging | ||
+ | Serial.begin(9600); | ||
+ | </code> | ||
+ | * loop(): verifică senzorul, declanșează ciclul de uscare și gestionează afișajul | ||
+ | <code> | ||
+ | // Update every 1 second to monitor the status | ||
+ | if (millis() - lastUpdateTime >= updateInterval) { | ||
+ | lastUpdateTime = millis(); | ||
- | const unsigned long dryingDuration | + | // If not currently drying and a hand is detected |
- | 60000 – durata uscării în milisecunde (60 secunde) | + | if (!drying && isHandDetected()) { |
- | + | drying = true; | |
- | setup() | + | startTime = millis(); |
- | configurare pini pentru ventilator și senzor, inițializare LCD | + | analogWrite(FAN_PIN, 200); // Start the fan immediately at 200 PWM |
+ | fanState = 1; // Update fan state to "on" | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(1, 0); | ||
+ | lcd.print("Drying started"); | ||
+ | Serial.println("Hand detected"); | ||
+ | } | ||
+ | |||
+ | if (drying) { | ||
+ | unsigned long elapsed = millis() - startTime; | ||
+ | unsigned long remaining = (dryingDuration - elapsed) / 1000; | ||
+ | |||
+ | lcd.setCursor(4, 1); | ||
+ | lcd.print("Time: "); | ||
+ | lcd.print(remaining); | ||
+ | lcd.print("s "); | ||
+ | |||
+ | // Handle gradual PWM ramp-down in the last 8 seconds | ||
+ | handlePWMSpeedControl(); | ||
+ | |||
+ | // Check if the drying duration has expired | ||
+ | if (elapsed >= dryingDuration) { | ||
+ | // Automatically reset drying process when the time expires | ||
+ | fanState = 0; | ||
+ | resetDryingProcess(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | * isHandDetected(): verifică dacă senzorul IR detectează o mână (semnal LOW) | ||
+ | <code> | ||
+ | int sensorValue = digitalRead(SENSOR_PIN); // Read the digital value from the sensor | ||
+ | if (sensorValue == LOW) { // If the sensor detects a hand | ||
+ | return true; | ||
+ | } | ||
+ | return false; | ||
+ | </code> | ||
+ | * handlePWMSpeedControl(): reduce progresiv viteza ventilatorului în ultimele 8 secunde | ||
+ | <code> | ||
+ | unsigned long elapsedTime = millis() - startTime; | ||
+ | |||
+ | if (elapsedTime >= 52000) { // After 52 seconds, start ramp-down | ||
+ | int pwmValue = 0; | ||
+ | |||
+ | // Ramp down the PWM speed to 150, 100, 50 over the last 8 seconds | ||
+ | if (elapsedTime <= dryingDuration - 7000) { | ||
+ | pwmValue = 150; | ||
+ | } else if (elapsedTime <= dryingDuration - 4000) { | ||
+ | pwmValue = 100; | ||
+ | } else if (elapsedTime <= dryingDuration - 1000) { | ||
+ | pwmValue = 50; | ||
+ | } | ||
+ | |||
+ | pwmValue = constrain(pwmValue, 0, 200); | ||
+ | |||
+ | // Only print PWM value if it's different from the previous one | ||
+ | static int lastPWMValue = -1; | ||
+ | if (pwmValue != lastPWMValue) { | ||
+ | analogWrite(FAN_PIN, pwmValue); | ||
+ | Serial.print("Fan PWM: "); | ||
+ | Serial.println(pwmValue); | ||
+ | lastPWMValue = pwmValue; // Update the last PWM value | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | * resetDryingProcess(): oprește ventilatorul, afișează „Done!” și revine la starea „Ready” | ||
+ | <code> | ||
+ | analogWrite(FAN_PIN, 0); // Stop the fan | ||
+ | Serial.print("Fan state: "); | ||
+ | Serial.println(fanState); | ||
+ | lcd.clear(); | ||
+ | lcd.setCursor(5, 0); | ||
+ | lcd.print("Done!"); | ||
+ | delay(2000); | ||
| | ||
- | loop() | + | lcd.clear(); |
- | logică principală de control și afișare | + | lcd.setCursor(5, 0); |
- | + | lcd.print("Ready"); | |
- | millis() | + | drying = false; |
- | temporizare non-blocantă pentru countdown | + | </code> |
- | + | ||
- | analogWrite(FAN_PIN, duty) | + | **Validare funcționalități:** |
- | control PWM pentru ventilator | + | |
- | + | Ventilatorul pornește automat la 200 PWM când senzorul detectează o mână. | |
- | lcd.*() | + | LCD-ul afișează countdown-ul de 60 de secunde în timp real. |
- | pentru inițializarea și manipularea afișajului | + | În ultimele 8 secunde, PWM-ul este redus gradual: 150 → 100 → 50. |
+ | După terminare, este afișat „Done!”, urmat de revenirea la „Ready”. | ||
+ | Pe Serial Monitor se afișează „Hand detected”, valorile PWM și „Fan state: 0” după finalizare. | ||
+ | |||
+ | **Elemente de noutate:** | ||
+ | * Rampă de coborâre a turației ventilatorului pe finalul ciclului | ||
+ | * Countdown afișat pe LCD fără blocare | ||
+ | * Diagnostic și urmărire prin mesaje în Serial Monitor | ||
+ | **Optimizări realizate:** | ||
+ | * Afișarea valorii PWM în Serial Monitor se face doar atunci când aceasta se modifică, evitând mesaje redundante | ||
+ | * Cod structurat în funcții dedicate cu responsabilitate unică | ||
+ | * Afișare eficientă pe LCD fără suprascrieri inutile | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
Line 133: | Line 224: | ||
Proiectul m-a ajutat să înțeleg mai bine integrarea componentelor hardware cu logica software într-un sistem automat. A fost o experiență practică utilă, care mi-a consolidat noțiunile studiate în cadrul laboratoarelor de PM. | Proiectul m-a ajutat să înțeleg mai bine integrarea componentelor hardware cu logica software într-un sistem automat. A fost o experiență practică utilă, care mi-a consolidat noțiunile studiate în cadrul laboratoarelor de PM. | ||
===== Download ===== | ===== Download ===== | ||
- | {{:pm:prj2025:avaduva: automatic_dryer.zip}} | + | {{:pm:prj2025:avaduva: dryer.zip}} |