This shows you the differences between two versions of the page.
pm:prj2023:ndrogeanu:aerconditionat [2023/05/28 14:27] eduard_costin.popa [Software Design] |
pm:prj2023:ndrogeanu:aerconditionat [2023/05/29 14:40] (current) eduard_costin.popa [Software Design] |
||
---|---|---|---|
Line 39: | Line 39: | ||
===== Software Design ===== | ===== Software Design ===== | ||
- | <code> | ||
- | #include <dht11.h> | ||
- | #include <Wire.h> | ||
- | #include <Adafruit_GFX.h> | ||
- | #include <Adafruit_SSD1306.h> | ||
- | #define BUTTON_INCREMENT 2 | ||
- | #define BUTTON_DECREMENT 3 | ||
- | #define BUTTON_MODE 4 | ||
- | #define DHT11PIN_OUTSIDE 7 | ||
- | #define DHT11PIN_INSIDE 6 | ||
- | #define SCREEN_WIDTH 128 | ||
- | #define SCREEN_HEIGHT 64 | ||
- | |||
- | Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); | ||
- | |||
- | dht11 DHT11; | ||
- | |||
- | int INA_OUTSIDE = 9; | ||
- | int INB_OUTSIDE = 10; | ||
- | int incrementButtonState = HIGH; | ||
- | int decrementButtonState = HIGH; | ||
- | int lastIncrementButtonState = HIGH; | ||
- | int lastDecrementButtonState = HIGH; | ||
- | unsigned long lastDebounceTime = 0; | ||
- | unsigned long debounceDelay = 50; | ||
- | |||
- | unsigned long previousTemperatureTime = 0; | ||
- | long referenceTemperature = 25.00; | ||
- | const unsigned long temperatureInterval = 2000; | ||
- | |||
- | bool buttonModeState = false; | ||
- | bool buttonModePressed = false; | ||
- | |||
- | |||
- | bool fanOn = false; | ||
- | bool mode = false; | ||
- | |||
- | void setup() { | ||
- | pinMode(BUTTON_INCREMENT, INPUT); | ||
- | pinMode(BUTTON_DECREMENT, INPUT); | ||
- | pinMode(BUTTON_MODE, INPUT_PULLUP); | ||
- | pinMode(INA_OUTSIDE, OUTPUT); | ||
- | pinMode(INB_OUTSIDE, OUTPUT); | ||
- | digitalWrite(INA_OUTSIDE, LOW); | ||
- | digitalWrite(INB_OUTSIDE, LOW); | ||
- | Serial.begin(9600); | ||
- | |||
- | |||
- | if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 | ||
- | Serial.println(F("SSD1306 allocation failed")); | ||
- | for(;;); | ||
- | } | ||
- | delay(2000); | ||
- | display.clearDisplay(); | ||
- | |||
- | display.setTextSize(1); | ||
- | display.setTextColor(WHITE); | ||
- | } | ||
- | |||
- | void loop() { | ||
- | unsigned long currentMillis = millis(); | ||
- | if (digitalRead(BUTTON_MODE) == LOW) { | ||
- | if (!buttonModePressed) { | ||
- | buttonModePressed = true; | ||
- | buttonModeState = !buttonModeState; | ||
- | } | ||
- | } else { | ||
- | buttonModePressed = false; | ||
- | } | ||
- | |||
- | if (!buttonModeState) { | ||
- | display.clearDisplay(); | ||
- | display.setCursor(0, 10); | ||
- | display.println("Mode: Manual"); | ||
- | display.setCursor(0, 25); | ||
- | display.print("Temp (C): "); | ||
- | display.println((float)DHT11.temperature, 2); | ||
- | display.setCursor(0, 40); | ||
- | display.print("Temp limit (C): "); | ||
- | display.println(referenceTemperature); | ||
- | display.setCursor(0, 52); | ||
- | display.print("Fan: "); | ||
- | if (fanOn) { | ||
- | display.println("ON"); | ||
- | } | ||
- | else { | ||
- | display.println("OFF"); | ||
- | } | ||
- | display.display(); | ||
- | |||
- | |||
- | int reading_increment = digitalRead(BUTTON_INCREMENT); | ||
- | int reading_decrement = digitalRead(BUTTON_DECREMENT); | ||
- | |||
- | if (reading_increment != lastIncrementButtonState) { | ||
- | lastDebounceTime = millis(); | ||
- | } | ||
- | if ((millis() - lastDebounceTime) > debounceDelay) { | ||
- | if (reading_increment != incrementButtonState) { | ||
- | incrementButtonState = reading_increment; | ||
- | |||
- | if (incrementButtonState == LOW) { | ||
- | referenceTemperature++; | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | lastIncrementButtonState = reading_increment; | ||
- | |||
- | if (reading_decrement != lastDecrementButtonState) { | ||
- | lastDebounceTime = millis(); | ||
- | } | ||
- | |||
- | | ||
- | if ((millis() - lastDebounceTime) > debounceDelay) { | ||
- | if (reading_decrement != decrementButtonState) { | ||
- | decrementButtonState = reading_decrement; | ||
- | if (decrementButtonState == LOW) { | ||
- | referenceTemperature--; | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | lastDecrementButtonState = reading_decrement; | ||
- | |||
- | if (currentMillis - previousTemperatureTime >= temperatureInterval) { | ||
- | previousTemperatureTime = currentMillis; | ||
- | DHT11.read(DHT11PIN_OUTSIDE); | ||
- | | ||
- | if ((float)DHT11.temperature > referenceTemperature) { | ||
- | if (!fanOn) { | ||
- | digitalWrite(INA_OUTSIDE, LOW); | ||
- | digitalWrite(INB_OUTSIDE, HIGH); | ||
- | fanOn = true; | ||
- | | ||
- | } | ||
- | } | ||
- | else { | ||
- | if (fanOn) { | ||
- | digitalWrite(INA_OUTSIDE, LOW); | ||
- | digitalWrite(INB_OUTSIDE, LOW); | ||
- | fanOn = false; | ||
- | } | ||
- | } | ||
- | } | ||
- | display.display(); | ||
- | |||
- | } | ||
- | else { | ||
- | display.clearDisplay(); | ||
- | display.setCursor(0, 10); | ||
- | display.println("Mode: Auto"); | ||
- | |||
- | if (currentMillis - previousTemperatureTime >= temperatureInterval) { | ||
- | previousTemperatureTime = currentMillis; | ||
- | |||
- | DHT11.read(DHT11PIN_OUTSIDE); | ||
- | float temperature_outside = DHT11.temperature; | ||
- | DHT11.read(DHT11PIN_INSIDE); | ||
- | float temperature_inside = DHT11.temperature; | ||
- | display.setCursor(0, 25); | ||
- | |||
- | display.print("Temp outside(C) "); | ||
- | display.println(temperature_outside, 2); | ||
- | |||
- | display.setCursor(0, 40); | ||
- | display.print("Temp inside(C) "); | ||
- | display.println(temperature_inside, 2); | ||
- | |||
- | if (temperature_inside <= temperature_outside) { | ||
- | if (!fanOn) { | ||
- | digitalWrite(INA_OUTSIDE, LOW); | ||
- | digitalWrite(INB_OUTSIDE, HIGH); | ||
- | fanOn = true; | ||
- | display.setCursor(0, 52); | ||
- | display.println("Fan: ON"); | ||
- | display.display(); | ||
- | } | ||
- | } | ||
- | else { | ||
- | if (fanOn) { | ||
- | digitalWrite(INA_OUTSIDE, LOW); | ||
- | digitalWrite(INB_OUTSIDE, LOW); | ||
- | fanOn = false; | ||
- | display.setCursor(0, 52); | ||
- | display.println("Fan: OFF"); | ||
- | display.display(); | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | } | ||
- | } | ||
- | </code> | ||
+ | <note tip> | ||
+ | In functia de setup am setat pinii aferenti componentelor folosite si am configurat modul de afisare al displayului, | ||
+ | verificand in prealabil daca acesta functioneaza. | ||
+ | In functia de loop am inceput prin a verifica cu ajutorul unui boolean in ce stare | ||
+ | se afla programul (auto/manual). In functie de valoarea acestuia, se intra pe una dintre cele 2 ramuri logice. | ||
+ | Pe prima ramura (manual) se verifica daca este apasat unul din cele doua butoane de incrementare/decrementare si temperatura prag se | ||
+ | modifica dupa caz. Ulterior se citeste temperatura de la senzorul exterior si, daca se respecta | ||
+ | conditia de temp. ext > temp. prag , se opreste ventilatorul, in caz contrar se porneste. | ||
+ | Pe ramura de auto se procedeaza similar ca mai sus, cu exceptia faptului ca nu exista butoane, | ||
+ | if-else-ul pentru oprirea si pornirea ventilatorului are ca si conditie ca temp. ext > temp. int. | ||
+ | Problemele de sincronizare le-am rezolvat utilizand conceptele de la laborator, ajutandu-ma | ||
+ | de functia auxiliara millis() pentru a verifica daca a trecut un anumit timp de la ultima verificare. | ||
+ | </note> | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
+ | <note tip> | ||
+ | Controlul aerului conditionat se poate realiza in 2 moduri, automat si manual. In modul manual, utilizatorul alege o temperatura mai mica decat cea indicata de senzorul de exterior pentru ca ventilatorul sa porneasca si sa raceasca aerul pana se ajunge la aceasta. Odata ce temperatura indicata de senzor ajunge la pragul dorit, ventilatorul se va opri. Cel de-al 2-lea mod de functionare, cel automat, implica ca temperatura indicata de senzorul de interior sa fie mai mica decat cea indicata de senzorul de exterior ( unde se afla ventilatorul ). In acel moment, ventilatorul porneste si raceste aerul pana se ajunge la temperaturi egale in cele 2 medii, moment in care se opreste. Utilizatorul poate alterna in cele doua moduri puse la dispozitie printr-un buton, iar in modul manual stabilirea temperaturii prag dorite se alege prin apasarea celorlalte 2 butoane puse la dispozite ( incrementeaza / decrementeaza temperatura ). Detaliile despre modul de functionare curent, precum si starea ventilatorului (oprit/pornit) dar si temperaturile indicate de senzori sau de catre utilizator pot fi vizualizate pe un ecran OLED de 0.96". | ||
+ | </note> | ||
===== Concluzii ===== | ===== Concluzii ===== | ||
+ | Acest proiect m-a ajutat sa consolidez mai bine notiunile invatate la aceasta materie si sa le aplic intr-un mod practic. Sunt cateva lucruri care puteau fi imbunatatite pentru a evita problemele prezente: | ||
+ | -> senzorii indica temperaturi diferite cateodata desi sunt situati unul langa altul => calibrarea senzorilor | ||
+ | -> izolarea unuia dintre senzori si manipularea temperaturii intr-un mod automat pentru a ilustra mai bine functionarea aerului conditionat => de exemplu punerea senzorului de interior intr-o cutie izolata si racirea acestuia cu ajutorul unor pastile de racit | ||
+ | |||
===== Download ===== | ===== Download ===== | ||
+ | {{:pm:prj2023:ndrogeanu:332cc_popa_eduard.zip|}} | ||
===== Jurnal ===== | ===== Jurnal ===== | ||