Automatic Nail Polish Dryer

Nume: Zugravescu Adina-Andreea

Grupa: 331CD

Introducere

Proiectul constă în dezvoltarea unui sistem automatizat care detectează prezența unei mâini și activează un mecanism de uscare controlat electronic. Scopul principal este uscarea rapidă și automată a lacului de unghii. Sistemul este activat de un senzor IR, iar pe durata funcționării (60 de secunde), timpul rămas este afișat pe un ecran LCD.

Ideea a pornit de la dorința de a automatiza un proces simplu, dar des întâlnit, oferind o soluție practică. Dispozitivul este ușor de folosit, eficient și util atât acasă, cât și în saloane.

Descriere generală

Senzorul IR transmite un semnal către Arduino printr-o intrare digitală. În funcție de starea citită, acesta generează un semnal PWM care, prin intermediul unui tranzistor MOSFET, controlează alimentarea ventilatorului de 12V. În paralel, Arduino comunică cu un LCD 1602 prin interfața I2C pentru a afișa un countdown de 60 de secunde, gestionat printr-un timer software implementat cu funcția millis().

Schema bloc a proiectului

Hardware Design

Lista de componente:

Diagrama circuit

Diagrama circuitului

1. Conectare senzor IR (KY-032):
   - GND la GND de pe Arduino
   - VCC la +5V de pe Arduino
   - OUT la pinul digital D2 de pe Arduino
   - EN lăsat neconectat
2. Conectare LCD 1602 cu interfață I2C:
   - GND la GND de pe Arduino
   - VCC la +5V de pe Arduino
   - SDA la pinul A4 de pe Arduino
   - SCL la pinul A5 de pe Arduino
3. Conectare ventilator 12V:
   - GND la drain al MOSFET-ului IRF520N
   - VCC la +5V de pe USB
   - Source-ul MOSFET-ului la GND
   - Gate-ul MOSFET-ului la pinul D3 (PWM) al Arduino, printr-o rezistență de 220Ω
4. Alte componente:
   - Diodă 1N4007 în paralel cu ventilatorul: catodul la +5V, anodul la drain
   - Rezistență de pull-down de 10kΩ între gate și GND (pentru a menține MOSFET-ul oprit când nu e activat)
   - Condensator ceramic de 47nF între +5V și GND pentru filtrarea alimentării

Notă: GND-ul Arduino și GND-ul alimentării externe sunt unite pe breadboard pentru a asigura masă comună.

Software Design

Mediu de dezvoltare: Arduino IDE

Biblioteci folosite:

  Wire.h – pentru comunicarea I2C cu LCD-ul
  LiquidCrystal_I2C.h – pentru controlul afișajului LCD 1602 cu interfață I2C

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”.

Algoritmi și structuri implementate:

  • 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

Funcții implementate:

  • setup(): configurarea pinilor, inițializarea LCD și Serial Monitor
    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);
    
  • loop(): verifică senzorul, declanșează ciclul de uscare și gestionează afișajul
    // Update every 1 second to monitor the status
    if (millis() - lastUpdateTime >= updateInterval) {
        lastUpdateTime = millis();

        // 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");
        }

        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();
            }
       }
    }
    
  • isHandDetected(): verifică dacă senzorul IR detectează o mână (semnal LOW)
    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;
    
  • handlePWMSpeedControl(): reduce progresiv viteza ventilatorului în ultimele 8 secunde
    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
        }
    }
    
  • resetDryingProcess(): oprește ventilatorul, afișează „Done!” și revine la starea „Ready”
    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;
    

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

Proiectul funcționează conform așteptărilor.

Video demonstrativ: https://youtube.com/shorts/mH0Pf0XKjyc?feature=share

Concluzii

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

Bibliografie/Resurse

pm/prj2025/avaduva/adina.zugravescu.txt · Last modified: 2025/05/29 18:03 by adina.zugravescu
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