This shows you the differences between two versions of the page.
pm:prj2025:avaduva:adina.zugravescu [2025/05/29 15:26] adina.zugravescu [Software 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 | ||
- | **Descrierea codului aplicației** | + | **Descrierea codului aplicației:** |
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”. | 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”. | ||
- | **Algoritmi și structuri implementate** | + | **Algoritmi și structuri implementate:** |
- | * Sistem pe stări logice: standby → activare → rampă PWM → finalizare → standby | + | * Sistem pe stări logice: standby → activare → rampă PWM → finalizare → standby \\ |
+ | * 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 \\ | ||
+ | * Afișare dinamică pe LCD: mesajele și countdown-ul sunt actualizate în timp real \\ | ||
+ | * Optimizare a mesajelor transmise în Serial Monitor: evitarea afișărilor redundante \\ | ||
- | * Temporizare non-blocantă cu <code>millis()</code> – folosită pentru countdown și control treptat al ventilatorului | + | **Funcții implementate:** |
+ | * 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(); | ||
- | * Control PWM gradual: <code>analogWrite()</code> cu valori 200 → 150 → 100 → 50 în ultimele 8 secunde | + | // If not currently drying and a hand is detected |
+ | if (!drying && isHandDetected()) { | ||
+ | drying = true; | ||
+ | startTime = millis(); | ||
+ | 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"); | ||
+ | } | ||
- | * Afișare dinamică pe LCD: mesajele și countdown-ul sunt actualizate în timp real | + | if (drying) { |
+ | unsigned long elapsed = millis() - startTime; | ||
+ | unsigned long remaining = (dryingDuration - elapsed) / 1000; | ||
- | * Optimizare a mesajelor transmise în Serial Monitor: evitarea afișărilor redundante | + | lcd.setCursor(4, 1); |
+ | lcd.print("Time: "); | ||
+ | lcd.print(remaining); | ||
+ | lcd.print("s "); | ||
- | === '''Funcții implementate''' === | + | // Handle gradual PWM ramp-down in the last 8 seconds |
- | * <code>setup()</code>: configurarea pinilor, inițializarea LCD și Serial Monitor | + | handlePWMSpeedControl(); |
- | * <code>loop()</code>: verifică senzorul, declanșează ciclul de uscare și gestionează afișajul | + | |
- | * <code>isHandDetected()</code>: verifică dacă senzorul IR detectează o mână (semnal LOW) | + | |
- | * <code>handlePWMSpeedControl(elapsed)</code>: reduce progresiv viteza ventilatorului în ultimele 8 secunde | + | |
- | * <code>resetDryingProcess()</code>: oprește ventilatorul, afișează „Done!” și revine la starea „Ready” | + | |
- | === '''Validare funcționalități''' === | + | // Check if the drying duration has expired |
- | * Ventilatorul pornește automat la 200 PWM când senzorul detectează o mână | + | if (elapsed >= dryingDuration) { |
- | * LCD-ul afișează countdown-ul de 60 de secunde în timp real | + | // Automatically reset drying process when the time expires |
- | * În ultimele 8 secunde, PWM-ul este redus gradual: 150 → 100 → 50 | + | fanState = 0; |
- | * După terminare, este afișat „Done!”, urmat de revenirea la „Ready” | + | resetDryingProcess(); |
- | * Pe Serial Monitor se afișează „Hand detected”, valorile PWM și „Fan state: 0” după finalizare | + | } |
+ | } | ||
+ | } | ||
+ | </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; | ||
- | === '''Elemente de noutate''' === | + | if (elapsedTime >= 52000) { // After 52 seconds, start ramp-down |
- | * Rampă inteligentă de coborâre a turației ventilatorului pe finalul ciclului | + | int pwmValue = 0; |
- | * Countdown afișat pe LCD fără blocare (fără <code>delay()</code>) | + | |
- | * Cod curat, modularizat, ușor de extins | + | |
- | * Diagnostic și urmărire prin mesaje în Serial Monitor | + | |
- | === '''Optimizări realizate''' === | + | // Ramp down the PWM speed to 150, 100, 50 over the last 8 seconds |
- | * Eliminarea variabilelor nefolosite din versiunile anterioare | + | if (elapsedTime <= dryingDuration - 7000) { |
- | * Evitarea afișării repetate prin memorarea valorii PWM precedente | + | pwmValue = 150; |
- | * Cod structurat în funcții dedicate cu responsabilitate unică | + | } else if (elapsedTime <= dryingDuration - 4000) { |
- | * Afișare eficientă pe LCD fără suprascrieri inutile | + | 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); | ||
+ | |||
+ | lcd.clear(); | ||
+ | lcd.setCursor(5, 0); | ||
+ | lcd.print("Ready"); | ||
+ | drying = false; | ||
+ | </code> | ||
+ | |||
+ | **Validare funcționalități:** | ||
+ | |||
+ | Ventilatorul pornește automat la 200 PWM când senzorul detectează o mână. | ||
+ | LCD-ul afișează countdown-ul de 60 de secunde în timp real. | ||
+ | Î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 130: | 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}} |