Proiectul presupune proiectarea unui robinet care funcționează pe baza unui senzor de mișcare, aprinzându-se un led atunci când este pornit și începând să pâlpâie atunci când mai sunt 5 secunde până se oprește automat. Robinetul este dotat și cu un ecran care afișează ce temperatură are apa, dar și nivelul apei din rezervor. Când senzorul de mișcare nu detectează nimic atunci singurul lucru pe care îl va face proiectul este să afișeze temperatura apei și nivelul acesteia, acest afișaj apărând constant. Însă, când se detectează mișcare, atunci pompa este activată și începe să curgă apă și simultan se aprinde led-ul. În momentul în care nu se mai detectează mișcare, led-ul începe să pâlpâie timp de 5 secunde, apa curgând în continuare până la oprirea robinetului după trecerea timpului.
Robinetul poate fi integrat în locuințe din diverse motive. Principalul său scop este de a preveni risipa cu ajutorul senzorului de mișcare deoarece robinetul se deschide doar când este nevoie și se oprește automat când nu este utilizat. Tot pentru prevenirea risipei este integrat un senzor de nivel al apei din rezervor care permite utilizatorilor să vadă câtă apă se consumă, sporind conștientizarea asupra consumului. O altă motivație este monitorizarea temperaturii apei pentru a cunoaște momentele în care este apă caldă și pentru a atenua costul mare al facturii la căldură.
Celulele roz reprezintă dispozitivele de intrare care trimit date către μC.
Celulele mov reprezintă ieșirile μC-ului: un ecran LCD pe care se vor afișa datele primite de la senzori și pompa de apă care va fi controlată de mișcarea detectată.
Conectivitate:
Componentele le-am legat conform specificațiilor găsite pentru fiecare:
Pentru realizarea designului hardware am folosit Fritzing care m-a ajutat să vizualizez cum o să fie conectate componentele. Am ales acest tool pentru a putea importa biblioteci cu componentele mele exacte.
Schema electrica:
Rezultatul final al acestei etape este reprezentat în poza de mai jos:
Partea de software am dezvoltat-o folosind Arduino IDE cu ajutorul unor biblioteci externe precum “OneWire.h” și “DallasTemperature.h” pentru senzorul de temperatură, “Wire.h” și “LiquidCrystal_I2C.h” pentru ecranul LCD.
Global am inițializat cu false o variabilă care îmi spune dacă a fost detectată sau nu mișcare și mi-am făcut o funcție care îmi setează variabila cu true când există mișcare.
// MOTION INIT bool motionState = false; void motionDetected() { motionState = true; }
În setup activez rezistența de pull-up și configurez pinul cu întrerupere pentru a nu interoga senzorul încontinuu.
pinMode(motionSensorPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(motionSensorPin), motionDetected, RISING);
Am citit valoarea sa, urmând să o afișez pe ecran. Conform datasheet-ului, calibrarea se face diferit în funcție de ce valori sunt interpretate de către senzor. Am măsurat valorile date de acesta la diferite niveluri de apă (0, 0.5, 1, 2, 3, 4 cm) și folosind un tool online am găsit cea mai apropiată funcție care îmi aproximează nivelul apei: 0.00068162 * pow(waterLevel, 1.39958) - 0.129774
int waterLevel = analogRead(A3);
Folosind bibliotecile incluse am setat senzorul.
#define temperatureSensorPin 9 OneWire oneWire(temperatureSensorPin); DallasTemperature temperature(&oneWire);
Am inițializat senzorul în setup().
temperature.begin();
La final am citit valoarea senzorului, urmând să o afișez pe ecran.
temperature.requestTemperatures(); float temp = temperature.getTempCByIndex(0);
Am setat LCD-ul.
LiquidCrystal_I2C lcd(0x27, 16, 2);
Am inițializat LCD-ul.
lcd.init(); lcd.backlight(); lcd.setCursor(0, 0);
Și am afișat valorile citite de senzorul de temperatură și de cel de nivel al apei pe ecran.
// PRINT TEMPERATURE ON LCD lcd.print("Temp: "); lcd.print(int(temp)); lcd.print((char)223); lcd.print("C"); // PRINT WATER LEVEL ON LCD lcd.setCursor(0, 1); lcd.print("Nivel apa: "); lcd.print(0.00068162 * pow(waterLevel, 1.39958) - 0.129774); lcd.print(" cm");
Am definit pinii cu care o să lucrez și am inițializat timpul curent cu 0 pentru a putea lucra cu timere.
#define R 7 #define G 6 #define B 8 #define pumpPin 4 // LED BLINKING unsigned long currentTime = 0;
Am setat pinii ca fiind de OUTPUT și i-am pus pe LOW.
// LED pinMode(R, OUTPUT); pinMode(G, OUTPUT); pinMode(B, OUTPUT); // L293D pinMode(pumpPin, OUTPUT); digitalWrite(pumpPin, LOW);
Atunci când este detectată mișcare se pornește pompa, se aprinde led-ul albastru și se salvează timpul când a fost ultima oară detectată mișcarea. Când senzorul nu mai simte mișcare atunci pentru 5 secunde pompa și led-ul funcționează normal după care pentru alte 5 secunde pompa funcționează, însă led-ul își schimnă culoarea în roșu și începe să pâlpâie. După aceea, și pompa și led-ul se opresc.
if (motionState) { currentTime = millis() / 1000; digitalWrite(R, LOW); digitalWrite(B, HIGH); digitalWrite(pumpPin, HIGH); motionState = false; } if (millis() / 1000 - currentTime < 10) { if (10 - (millis() / 1000 - currentTime) <= 5) { digitalWrite(B, LOW); digitalWrite(R, (millis() % 100 > 50) ? HIGH : LOW); // LED pâlpâie Serial.println("LED blinking. Valve will close soon."); } } else { digitalWrite(R, LOW); digitalWrite(pumpPin, LOW); Serial.println("Valve closed and LED turned off."); }
Download: robinet_inteligent.zip
03.05.2024: Creare pagină și adăugare introducere și descriere generală
17.05.2024: Adăugare hardware design
19.05.2024: Adăugare software design
25.05.2024: Adăugare rezultate finale