miercuri, 27 mai 2026

Fântână pentru Pisa

 Am achizitionat de pe Temu o fantana pentru animalele de companie, la un pret modic. Are o pompa, destul de silentioasa, cu debit reglabil. Am vrut sa o modernizez, astfel incat functionarea sa fie temporizata si numai la detectia pisicii.

Initial am incercat cu senzor PIR AM312, dar din cauza limitarilor senzorului (nu se poate regla timpul de detectie) am renuntat si am incercat cu senzor laser VL53L0XV2. 

Partea dificila este setarea in program a distantei de detectie ; dar se poate scrie un program simplu care sa afiseze pe monitorul serial momentul cand senzorul detecteaza corpul in miscare. In functie de acest prag se modifica corespunzator programul. Deocamdata functioneaza destul de bine...


 


#include "Adafruit_VL53L0X.h"

// Configurare Pini
const int pinPompa = 3; 
const int pinLedL = 13; 

// Parametri Proiect Finali
const int distantaPragMax = 170;   // 170 mm (17 cm) - Prag optim de siguranță
const int distantaPragMin = 15;    // Min 1.5 cm - Ignoră reflexiile parazite
const int secundeDetectie = 3;     // Trebuie să stea 3 secunde continuu
const int secundePompa = 180;      // Pompa merge 3 minute
const int minutePauza = 3;         // Pauză de siguranță de 3 minute după băut

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
  pinMode(pinPompa, OUTPUT);
  pinMode(pinLedL, OUTPUT);
  digitalWrite(pinPompa, LOW);
  digitalWrite(pinLedL, LOW);

  Serial.begin(9600);
  while (!Serial) { delay(1); } 

  Serial.println("--- Fantana Pisa ---");

  if (!lox.begin()) {
    while (1) {
      digitalWrite(pinLedL, HIGH); delay(100);
      digitalWrite(pinLedL, LOW); delay(100);
    }
  }
  Serial.println("Sistem pornit si calibrat. Pregatit pentru utilizare.");
}

void loop() {
  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false); 

  // Verificăm dacă apare un obiect în zona de băut (între 1.5 cm și 17 cm)
  if (measure.RangeStatus != 4 && measure.RangeMilliMeter >= distantaPragMin && measure.RangeMilliMeter < distantaPragMax) {
    
    Serial.print("[Detecție] Obiect la ");
    Serial.print(measure.RangeMilliMeter);
    Serial.println(" mm. Începe monitorizarea de 3 secunde...");

    unsigned long startDetectie = millis();
    bool prezentaContinua = true;
    int contorSecunde = 0;

    // --- MONITORIZARE 3 SECUNDE ---
    while (millis() - startDetectie < (secundeDetectie * 1000)) {
      lox.rangingTest(&measure, false);
      
      // Dacă pisica pleacă sau se îndepărtează peste 17 cm, anulăm totul 
      if (measure.RangeStatus == 4 || measure.RangeMilliMeter > distantaPragMax || measure.RangeMilliMeter < distantaPragMin) {
        Serial.println("[Anulare] Pisica a plecat înainte de termen.");
        prezentaContinua = false;
        break;
      }
      
      delay(100); 
      contorSecunde++;
      if (contorSecunde % 10 == 0) {
        Serial.print("... confirmat ");
        Serial.print(contorSecunde / 10);
        Serial.println(" sec.");
      }
    }

    // --- DETECȚIE VALIDATĂ ---
    if (prezentaContinua) {
      Serial.println(">>> PISICA CONFIRMATA! PORNESTE POMPA (3 MINUTE) <<<");
      digitalWrite(pinLedL, HIGH);
      digitalWrite(pinPompa, HIGH); 

      // Ciclul de funcționare 3 minute
      for (int s = 1; s <= secundePompa; s++) {
        delay(1000);
        if (s % 30 == 0) {
          Serial.print("Pompa rulează de ");
          Serial.print(s);
          Serial.println(" secunde.");
        }
      }

      Serial.println("<<< Timp expirat. Oprire pompă. >>>");
      digitalWrite(pinPompa, LOW);
      digitalWrite(pinLedL, LOW);

      // --- PERIOADĂ DE PAUZĂ (3 MINUTE) ---
      Serial.println("Intrare în pauza de 3 minute...");
      for (int i = 1; i <= (minutePauza * 2); i++) {
        delay(29900);
        digitalWrite(pinLedL, HIGH); delay(100); digitalWrite(pinLedL, LOW);
      }
      Serial.println("Pauză terminată. Sistemul revine în Stand-by.");
    }
  }

  // Heartbeat Stand-by la fiecare 10 secunde
  static unsigned long timpUltimaClipire = 0;
  if (millis() - timpUltimaClipire > 10000) {
    digitalWrite(pinLedL, HIGH); delay(50); digitalWrite(pinLedL, LOW);
    timpUltimaClipire = millis();
    Serial.println("Stand-by: Monitorizare activă...");
  }
}