Navn på jeres automationsløsning

Smart home med lys- og varmekontrol

Navn på gruppemedlemmerne / forfatterne

Jakob Kuhrt Gamborg – Jajoe18

Peter Andreas Brændgaard – pebra18

Malte Bukrinski – mabuk18

Introduktion

Vi har lavet et rum hvor vi ønsker at kontrollere temperaturen via et vindue som kan åbne og lukke automatisk, samt en ventilator som kan få luften i bevægelse i rummet. Ydermere har vi en pære som bliver styret af en bevægelsessensor, lyssensor samt tidspunkt på døgnet. Til at styre temperaturen har vi benyttet os af en temperaturføler. 

Video gennemgang af løsningen

Opbygning af hardware fra TinkerCad

Husk at beskrive hvorfor og hvordan I har valgt at lave de enkelte løsninger

Der bruges en spændingsdeler i samspil med photoresistoren, for at give den rigtige spænding til transistoren for at lampen lyser. Ifølge databladet går photoresistoren fra 100 kΩ ved mørke til omkring 8 kΩ ved normalt lys (https://cdn.sparkfun.com/datasheets/Sensors/LightImaging/SEN-09088.pdf). Output spændingen af en spændingsdeler gives ved følgende formel:

Vout = R2R1+R2 *Vin

Vi er interesseret i at der er høj output spænding, når photoresistoren er mørk, i.e. den har høj modstand. Samtidigt, skal der være lav outputspænding, når photoresistoren er lys. Ved at prøve os lidt frem fandt vi ud af den bedste kombination, som vi kunne lave med de modstande, der var til rådighed, var 25 kΩ. Det gav os følgende output spændinger:

Mørkt: Vout = 10000025000+100000 *5=4V

Lyst: Vout = 800025000+8000 *5=1.21V

Foran lysdioden er der selvfølgelig en modstand. Den er sat til 220 Ω for at være på den sikre side. Lysdioden kan tage max 75 mA (http://69.195.111.207/tutorial-download/?t=3mm_and_5mm_LED_Kit ), men lyser fuldt allerede ved 20 mA. En modstand på 220 Ω vil give 5V/220Ω = 22.7 mA ifølge ohms lov. 

Alle andre dele er simple inputs eller output alt efter delen. 

Kredsløbsdiagram

Opbygning af program

#include <dht.h>
#include <Servo.h>
#include <RTClib.h>
#include <Wire.h>

#define servoPin 6
#define dhtPin 7
#define motorPin 4
#define lightPin 8
#define motionPin 2
Servo servo;
RTC_DS1307 rtc;
dht dht;
int angle = 10;
int maxTemperature = 23;
int minTemperature = 20;
int lastMovement = 0;
int noMovementTime = 5;  
int startNightTime = 21;
int stopNightTime = 8;
int temperature;
uint32_t windowOpenTime = 0;
uint32_t minimumWindowOpeningTime = 10;
uint32_t windowOpeningInterval = 60;
DateTime now;
DateTime windowOpenDateTime;
bool isWindowOpen;

void setup() {
  Serial.begin(9600);
  setupRtc();
  
  servo.attach(servoPin);
  servo.write(angle); 
  pinMode(motorPin, OUTPUT);
  pinMode(lightPin, OUTPUT);
  pinMode(motionPin, INPUT);
}

void loop(){ 
  dht.read11(dhtPin);
  now = rtc.now();
  
  Serial.print("Time: ");
  printDateTime(now);

  setTemperature();
  printTemperature();
  ShouldVentilatorRun(); 
  ShouldThereBeLight();
  ShouldWindowOpen();
  printsWindow();

  Serial.println("");
  delay(1000);
}

void ShouldVentilatorRun(){
    if(temperature > maxTemperature ) {
      Serial.println("Is Ventilator On? Yes");
      digitalWrite(motorPin,HIGH);
   } else {
      digitalWrite(motorPin,LOW);
      Serial.println("Is Ventilator On? No");
  }
}

void ShouldWindowOpen(){
  if(isWindowOpen){
    // Close window
  if((temperature < maxTemperature) && compareTime(windowOpenDateTime+ TimeSpan(0,0,0,minimumWindowOpeningTime),now) == -1){
    servo.write(angle);  
    windowOpenDateTime = DateTime(now);
    Serial.println("Now Closing window");
    isWindowOpen = false;
  }
    // Open window
  } else if (!isWindowOpen){
    if(temperature > maxTemperature){
    servo.write(angle*6);
    windowOpenDateTime = DateTime(now);
    isWindowOpen = true;
  }
    if (compareTime(windowOpenDateTime+ TimeSpan(0,0,0,windowOpeningInterval),now) == -1) {
      servo.write(angle*6);
      windowOpenDateTime = DateTime(now);
     Serial.println("Opening window at interval time");
     isWindowOpen = true;
    }
  }
}
                               
void ShouldThereBeLight(){
  int isThereMotion = digitalRead(motionPin);;
  if (now.hour() > stopNightTime && now.hour() < startNightTime ) {
    if(isThereMotion == HIGH ) { 
      Serial.println("Is there motion? Yes");
      digitalWrite(lightPin,HIGH);
      }
      
    if(isThereMotion == LOW ) { 
      Serial.println("Is there motion? No");
      digitalWrite(lightPin,LOW);
      }
  } else { digitalWrite(lightPin,LOW); }
      
}

int compareTime(DateTime time1, DateTime time2) {
  if(time1.hour() > time2.hour()) {
    return 1;
    }
  else if(time2.hour()> time1.hour()) {
    return -1;
    }
  else {
    if(time1.minute() > time2.minute()) {
      return 1;
      } else if(time2.minute()> time1.minute()) {
        return -1;
      }
   else {
    if(time1.second() > time2.second()) {
      return 1;
      } else if(time2.second()> time1.second()) {
    return -1;
      }
    }
    return 0;
    }
}

void printDateTime(DateTime time) {
    Serial.print(time.hour());
    Serial.print(":");
    Serial.print(time.minute());
    Serial.print(":");
    Serial.println(time.second());
  }

void printTemperature() {
    Serial.print("Temperature: ");
    Serial.println(temperature);
  }

void setupRtc() {
   while (!Serial); // for Leonardo/Micro/Zero
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
   // if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
   // following line sets the RTC to the date & time this sketch was compiled
   // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    rtc.adjust(DateTime(2021,04,28,12,0,0));
   // }
  }

    void printsWindow() {
    Serial.print("Is window open? ");
    if(isWindowOpen){
        Serial.println("Yes");      
      } 
    if(!isWindowOpen) {
        Serial.println("No");
      } 
    Serial.print("OpenTime: ");
    printDateTime((windowOpenDateTime+ TimeSpan(0,0,0,windowOpeningInterval)));
   }

   void setTemperature() {
      if(dht.temperature != -999) {
        temperature = dht.temperature -4;
      }
   }
  

Output fra consolen

På billedet overfor ses et output fra konsollen, som vi har brugt til at debugge programmet. Her ses et eksempel hvor vinduet bliver åbnet, for at få frisk luft ind i lokalet, i demoen en gang i minuttet, normalvis en gang i timen, trods maks temperatur på 24 grader ikke er nået.

Dette print viser at når temperaturen er over 23 grader, åbner vinduet, og ventilatoren tændes.

Flow og tilstandsdiagrammer

Funktioner

Programmet har 2 hovedfunktioner; styring af lys og styring af temperatur. Lyset tændes på baggrund af tidspunktet på dagen. Hvis det for eksempel er et kontor, skal der ikke være tændt lys om natten. Lyset styres også af en bevægelsessensor, så der ikke er lys, hvis der ikke er nogen i rummet. 

Temperaturen kan reguleres ved hjælp af at åbne/lukke vinduer og tænde/slukke for en ventilator. En temperatursensor styrer hvorvidt, der er behov for at regulere temperaturen. Hvis det ikke er for varmt, så åbnes vinduet stadig med et regelmæssigt interval for at sikre et godt indeklima. 

Prioriteringer

Der er ikke som sådan indbygget prioriteringer i programmet. Der burde nok være noget sikring, der gør at ing slukkes som default. 

Opbygning af den samlede fysiske prototype

Hvordan er samspillet mellem mekanik, elektronik og software?

Koden har tre centrale metoder. En til hver aktuator; lys, vindue og ventilator. Hver metode håndterer logikken for hvorvidt aktuatoren skal være tændt eller slukket. 

Lys

Arduinoen outputter strøm til en modstand og en lysdiode. Efter lysdioden er der en transistor. Transistoren styres af photoresistoren. Photoresistoren indgår i en spændingsdeler sammen med en 25 kΩ modstand for at sikre, at transistoren for den rigtige spænding. 

Vindue

Vinduet styres af en servomotor, som er koblet direkte i arduinoen. En servomotor har tre pins; 5V, ground og signal.

Ventilator

Ventilatoren er bare en simpel DC-motor, som er får sine 5V direkte fra Arduinoen. 

Tid

Tiden styres af et RTC modul, som bruger I2C. Den kobles til Arduinoen i SCL og SDA inputs. 

Bevægelsessensor

Bevægelsessensoren outputter direkte til Arduinoen, som bruger det til at vurdere om lyset skal tændes. Bevægelsessensoren kan indstilles til at outputte i længere tid efter en registreret bevægelse for at styre hvor længe lyset skal forblive tændt. 

Konklusion

hvor godt løser jeres løsning de oprindelige problemstillinger?

Løsningen virker godt med at regulere temperaturen. Vinduet åbner og lukker som ønsket. Ventilatoren kører også som ønsket. Lyset tænder også, når der er bevægelse i rummet. Vinduet åbner også med et vist interval selvom temperaturen ikke er for høj, så et ordentligt indeklima vedligeholdes.

Der mangler at blive implementeret ordentlig håndtering af strømsvigt, så for eksempel vinduet ikke bliver efterladt åbent. 

Perspektivering

Hvad kan man gøre for at gøre den bedre?

Knapper til manuelt at interagere med systemet ville nok være at foretrække, hvis det skulle bruges i virkeligheden. Alle delene ville man nogle gange gerne aktivere uden for de definerede situationer. Måske har man brug for et mørkt rum eller man har lavet mad og der skal luftes ud. 

Leave a Reply