Lavet af Alexander Jessen, Henrik Hansen og Mikkel Abildholt

Brug en motor, temperatursensor, lyssensor, vippe sensor mm. til at bygge et smart vindue, der sørger for et godt indeklima, er energieffektivt og beskytter mod røveri.

Til denne opgave kigger vi på, at forbedre indeklimaet for bla. studerende som sidder hjemme med online undervisning. Man kan nemt blive fortabt i sit studie, særligt om sommeren kan det gå hen og blive for varmt, hvis man glemmer at åbne et vindue. Derfor vil vi gerne udvikle et smart system, som kan regulere et rums temperatur ved automatisk at åbne og lukke et vindue, afhængigt af den målte temperatur i rummet, såvel som solindfald. Løsningen kommer desuden med et display, til at vise temperatur, samt sikring mod indbrud.

Stykliste

  • 1 x Arduino Uno board
  • 1 stk. Papkasse af cirka 28 cm x 38 cm
  • 1 x Phototransistor
  • 1 x DC motor
  • 1 x L293DNE H-Bro
  • 1 x TMP36 Temperature sensor
  • 1 x BL-XT660 Vippe sensor
  • 1 x I2C LCD
  • 1 x Rød LED
  • 1 x Active Buzzer
  • 2 x 10kΩ Modstand
  • 1 x 220Ω modstand

Beskrivelse af nøglekomponenter

Temperatursensor (TMP36)

Denne type temperature sensor, er en lav volt precisions sensor, som måler temperaturen i celsius. Dette gør den ved at lave et volt output som er proportional med temperaturen i celsius. Denne type sensor kan måle temperaturer mellem -40℃ til +125℃. Den tager en spænding på min. 2.7V og max. 5.5V. Sensoren giver et output på 750 mV når den måler en temperatur på 25°C. Ved brug af en 5V arduino kan man bruge de følgende ligninger for at omregne den analog måling til en temperatur.

Konverter analog værdi mellem 0-1023 til spænding på 0-5000 mV:
Spændingen ved pin i milliVolt = (analog værdi) * (5000/1024)

Konverter spænding til temperatur i celsius:
Temperatur i celsius = [(analog spænding i mV) – 500] / 10

Nedenfor ses et Tinkercad setup som styrer 3 LED’er, afhængigt af målingen fra temperatursensoren. Det tre LED’er lyser op ved forskellige temperaturmålinger, navnligt blå ved 15-20℃, grøn ved 20-25℃ og rød ved 25-30℃. Koden findes i bilag.

Vippe sensor (BL-XT660)

Denne type vippe sensor fungere ved at den har 4 ben, som hver rammer en bold. Denne bold triller rundt inde i en lille plastkasse. Når sensoren bliver vippet under 45°, vil den være en slukket tilstand, da ingen af benene vil ramme bolden. Ud over dette kan den drejes 360° rundt. Den tager en spænding på under 12V.

Phototransistor (HW5P-1)

Phototransistor, er en variabel modstand. Det vil sige, at den ændre sin indre modstand, afhængigt af, hvor meget lyst den opfanger. Denne type phototransistor kan tage en spænding på 3 – 15V.

DC motor

Denne type DC motor har et max RPM på 6100, ved 30g. Den tager en max spænding på 6.0V.

H-Bro (L293DNE)

Denne type H-Bro er en høj volt, høj strømstyrke med 4 kanaler, som er designet til at køre inducerende belastning såsom DC motorer, og skifte strøm transistorer. Den tager en spænding på max. 7V.

LCD display 16×2

Et LCD display bruges i dette projekt til at udskrive information fra relevante sensorer. Displayet er 16×2, hvilket betyder at det har 16 kolonner og 2 rækker. Dette giver displayet (16×2) 32 karakterer. Hver karakter består af (5×8) 40 pixels. Dette giver tilsammen displayet (32×40) 1280 pixels at håndtere. Grundet kompleksiteten af dette kommer displayet med en I2C interface påført. Interfacen gør det muligt at kommuniere med displayet serielt. Nedenfor ses billeder af en delløsning hvor displayet bruges til at udskrive antallet af sekunder siden sidste reset. Desuden bruges et potentiometer til at styre kontrasten af den udskrevne tekst. Koden findes i bilag.

Kredsløbsdiagram

Step-by-step til arduino setup

Her er vores opstilling af kredsløbet i tinkercad

Gennemgang

  • Step 1: Tilslut din Arduino Uno til et breadbord. Her benyttes 5V outputtet fra Arduinoen, som tilsluttes til den positive linje på breadbordet. Ground på Arduinoen, bliver tilsluttet den negative linje på breadbordet.
  • Step 2: Tilslut det sekundære breadbord, ved at tilslutte de positive og negative linjer sammen.
  • Step 3: I det første breadbord, tilslut den første 1kΩ modstand til den negative linje på det første breadbord. Sæt den anden ende i linje j2 på breadbordet.
  • Step 4: På linje i2, tilsluttes en ledning, som føre hen til digital input 5 på Arduinoen.
  • Step 5: på linje f2-3 og g2-3, placeres tilt sensoren. Dette skal gøres med 4 hun-til-han ledninger.
  • Step 6: Sæt nu en ledning, som går fra linje j3, hen til den positive linje på breadbordet.
  • Step 7: Fra linje f10-17 og linje e10-17, placeres H-broen.
  • Step 8: H-broen skal have nogle ledninger tilsluttet, før DC-motoren kan tilsluttes. De følgende ledninger skal placeres: fra den positive linje på breadbordet, til j10. Fra j11 skal der gå en ledning til digital 2 på Arduinoen. Fra både j13 og j14, skal der gå en ledning til den negative linje på breadbordet. Fra g16 skal der gå en ledning til digital 4 på Arduinoen. Fra g17 skal der gå en ledning til digital 8 på Arduinoen. Til sidst skal der gå en ledning fra d17 til den positive linje på breadbordet.
  • Step 9: Tilslut nu DC-motoren. Her skal den negative ledning sidde i g12, og den positive skal sidde i g15.
  • Step 10: Tilslut nu den anden 1kΩ modstand, fra den negative linje til j24. For enden af denne modstand, i24, skal der gå en ledning til A1 på Arduinoen. Til højre for modstanden, j25, skal der gå en ledning til den positive linje.
  • Step 11: i f24 og f25, skal Phototransistoren sidde.
  • Step 12: Fra e22, skal der gå en ledning til den negative linje på breadbordet. Fra e27 skal der gå en ledning til digital 9. For enden af disse, c22 og c27, skal buzzeren sidde.
  • Step 13: fra den positive linje, skal der gå en ledning til j27, fra j28 skal der gå en ledning til A0 på Arduinoen. fra j29, skal der gå en ledning til den negative linje.
  • Step 14: I f27-29, skal temperatur sensoren sidde.
  • Step 15: Nu bevæger vi os over til breadbord nr. 2. Tilslut en ledning i digital 10. Denne ledning skal tilsluttes det lange ben på LED’en (Anoden). Fra det korte ben (Katoden), skal der tilsluttes en ledning, som føre hen til den negative linje på breadbordet.
  • Step 16: Her skal der tilsluttes en masse ledninger. Fra e14, skal der gå en ledning til den negative linje. fra e15, skal der gå en ledning til den positive linje. Fra e17, skal der gå en ledning til digital 13 på Arduinoen. Fra e18 skal der gå en ledning til den negative linje. Fra e19 skal der gå en ledning til digital 12 på Arduinoen. Fra e24 skal der gå en ledning til digital 11 på Arduinoen. Fra e25 skal der gå en ledning til digital 4 på Arduinoen. fra e26 skal der gå en ledning til digital 7 på Arduinoen. Fra e27 skal der gå en ledning til digital 6 på Arduinoen. fra i28 skal der sidde en 220Ω modstand, som går til den positive linje. Fra h28 skal der gå en ledning til e28. Til sidst skal der gå en ledning fra e29 til den negative linje på breadbordet.
  • Step 17: Tilslut nu LCD’en, så GND sidder i a14, og den sidste pin på LCD’en sidder i a29.
  • Step 18: Tilslut den positive ende af potentiometeret til den positive linje på breadbordet. Den negative ende af potentiometeret skal tilsluttes den negative linje på breadbordet.
  • Step 19: Tilslut det midterste ben fra potentiometeret til e16 på breadbordet.

Forklaring af koden

Koden herunder er inddelt i afsnit, hvori der følger en forklaring af den specifikke kode nedenunder. Først starter vi med deklarationer af den nødvendige data der skal bruges.

#include <LiquidCrystal.h>
 
LiquidCrystal lcd(6,7,4,11,12,13);
 
const int controlPin1 = 2;
const int controlPin2 = 3;
const int enablePin = 8;
const int ldrSensorPin = A1; //lyssensor (phototransister)
const int tempSensorPin = A0;
const int tiltSensorPin = 5;
const int ledPin = 9;
const int buzzerPin = 10;
 
int tempSensorValue = 0;
int ldrIndoorSensorValue = 0;
int ldrSensorValue = 0;
int tiltSensorValue = 0;
int motorEnabled = 0;
int motorSpeed = 0;
int motorDirection = 1;
 
float voltage = 0;
float temp = 0;
 
bool windowStateOpen = false;
bool expectedWindowState = false;

Først importeres et bibliotek for LCD displayed, hvilket tillader os at bruge prædefineret funktioner til at printe beskeder på skærmen. Derefter defineret hvilke pins LCD’en er sat til på arduionen. Herefter defineres der alle de forskellige data’er, startende med konstanterne, hvilke er de værdier vi ikke vil have skal ændre sig gennem koden. Disse bliver brugt til at navngive de tilsluttede pins hvor både kontakten til h-broen, og derved motoren findes, samt sensorerne. Herefter deklareres der de integers som skal holde værdierne af målingerne, efterfulgt at floats og bools.

void setup(){
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.clear();
 
  pinMode(tiltSensorPin, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(enablePin, LOW);
 
}

Dette afsnit bruges til at definere hvilken type vores pins skal være. Her sættes de pins sensorerne sidder i til at være input, da de skal modtage data. De pins som sidder til h-broen bliver sat til output, da de skal sende data. Derefter startes der med at sende en besked til h-broen, hvor den bliver sat til at være slukket. Dette gøres for at undgå motoren starter med at kører uønsket.

void loop(){
  tempSensorValue = analogRead(tempSensorPin);
  ldrSensorValue = analogRead(ldrSensorPin);
  tiltSensorValue = digitalRead(tiltSensorPin);
 
  voltage = (tempSensorValue/1024.0) * 5.0;
  temp = (voltage - 0.5) * 100;
 
  if(tiltSensorValue == 0){
  	windowStateOpen = false;
	} else {
  	windowStateOpen = true; 
	}
  
  if(windowStateOpen != expectedWindowState){
	delay(5000);
    if(!expectedWindowState){
  	lcd.clear();
      lcd.print("INDBRUD");
      tone(buzzerPin,3000,5000);
      digitalWrite(ledPin, HIGH);
	} else {
  	lcd.clear();
      lcd.print("I AM BROKEN");
      digitalWrite(ledPin, HIGH);
	}
  } else

Herfra starter den del af koden som kontinuerligt køres når der er strøm til boardet. Først hentes og gemmes der værdierne af sensorerne, hvorefter værdien for temperatursensoren bliver omregnet til den tilsvarende temperatur. Dertil tjekkes der for hvilken tilstand vinduet er i, om det er åbnet eller ej. Det er tilt-sensorens ansvar, og hvis vinduet er mere end 45 grader åbent sætter koden værdien til at være sand. Under 45 grader tæller vinduet som lukket, hvilket er et sikkerhedsbrug som kunne fikses ved brug af et accelerometer i stedet for tilt-sensoren.

Herefter begynder den primære del af loopet som styrer hvornår motoren skal kører. Først tjekkes der dog om vinduets tilstand er som den forventede tilstand. Dette gøres for at tjekke om der har været indbrud, da tilstanden af vinduet burde tilsvare tilstanden som koden forventer den i. Tilt sensoren bruges her til at være sikkerhedskontrollen.

   }    
   if(temp > 27){
        digitalWrite(controlPin1, HIGH);
        digitalWrite(controlPin2, LOW);
   	   analogWrite(enablePin, 200);
        expectedWindowState = true;
    	   delay(250);
        analogWrite(enablePin, 0);
	   } else if ( temp < 21 && ldrSensorValue < 800){
        digitalWrite(controlPin1, LOW);
        digitalWrite(controlPin2, HIGH);
        analogWrite(enablePin, 200); 
        expectedWindowState = false;
    	   delay(250);
        analogWrite(enablePin, 0);
	   } else if (ldrSensorValue >= 800 && temp > 20){
        digitalWrite(controlPin1, HIGH);
        digitalWrite(controlPin2, LOW);
        analogWrite(enablePin, 200);
        expectedWindowState = true;
    	   delay(250);
        analogWrite(enablePin, 0);
	   } else {
        digitalWrite(controlPin1, LOW);
        digitalWrite(controlPin2, HIGH);
        analogWrite(enablePin, 200);
        expectedWindowState = false;
    	   delay(250);
        analogWrite(enablePin, 0);
	}

Denne del af loopet tjekker hvilken temperatur der er i rummet, samt hvor meget lysindfald der er udefra. Ud fra disse to værdier vil vinduet enten åbne eller lukke. Værdierne der bestemmer hvornår koden køres er op til brugeren selv at bestemme, dog synes vi at disse grænser passede fint til vores behov.

    lcd.setCursor(0,0);
    lcd.print("Temperatur: ");
	lcd.print(temp);
    lcd.setCursor(0,1);
	if(windowStateOpen){
      lcd.print("Window: Open");
	} else if(!windowStateOpen){
      lcd.print("Window: Closed");
	}
  }
 
  delay(3000);
}

Her sendes data til LCD-displayed om hvad den skal vise. I dette eksempel vises temperaturen samt vinduets tilstand. Herefter er der et 3-sekunders delay for at få opsætningen til at kører mere flydende.

Flow/Tilstandsdiagram

Flowdiagram

Tilstandsdiagram

Guide til konstruktion af pap-model

Step-by-step guide til mål og kasse udskæringer

  1. Tegn 4 linjer. 2 af linjerne skal være ca. 6,5cm og 2 af linjerne skal være ca. 8cm.
  2. Skær et hul i pappet, enten med en kniv eller en saks.
  3. Tag det lille stykke pap, og skær et hul i midten af pappet, som er ca. 0,5cm x 0,5cm. Her kommer vippe sensoren til at være.
  4. I toppen af det udskårne hul, skæres der et udsnit på 4,5cm x 2,5cm. I dette udsnit skal DC-motoren placeret.
  5. Sæt det lille stykke pap fast på DC-motoren (Gerne på et lille plast stykke, som vist på billederne)
  6. Ved siden af hullet i papkassen, bliver Phototransistoren placeret.
  7. Vend derefter papkassen 90 grader, og skær et 2,5cm x 7,5cm udsnit. Her kommer LCD’en til at sidde.
  8. Ved siden af dette udsnit, omkring 2cm mellemrum, lave her et udsnit der er 1cm x 1cm. Dette hul skal bruges til Potentiometeret.

Muligheder for viderebygning

I fremtidige versioner af robotten, kunne man eventuelt tilføje en sensor, som kan registrere, om glasset i vinduet bliver smadret, da robotten lige nu, kun kan finde ud af om vinduet bliver åbnet uden at robotten har startet med at åbne vinduet.

Ud over dette, kunne man også tilføje en knap, så man kan åbne vinduet manuelt, eksempelvis hvis nu at man har brændt noget mad på ell.lign. Så man kan lufte ud, uden at robotten selv mener hvornår det korrekte tidspunkt, at åbne vinduet er på.

En anden tilføjelse kunne være, at tilføje en fugtigheds sensor. Dette ville være en god tilføjelse, hvis nu man eksempelvis har været i bad el.lign. og derfor har brug for at få åbnet et vindue, da der hurtigt kan godt hen og føles meget klamt i boligen.

Konklusion

Video af roboten

Bilag

Link til test videoer

https://drive.google.com/drive/folders/1U3qPkoeoxVOzz-c5p8LrIE2ZF_uyz6CZ?usp=sharing

Temperatursensor delløsning kode

int baselineTemp = 0;
int val = 0;

void setup()
{
  pinMode(A0, INPUT);
  Serial.begin(9600);

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
}

void loop()
{
  // set threshold temperature to activate LEDs
  baselineTemp = 15;

  val = analogRead(A0);
  float mv = (val/1024)*5000;
  float celsius = (mv-500)/10; 
  Serial.print("Temperature = ");
  Serial.print(celsius);
  Serial.print(" C");
  Serial.println();
  
  if (celsius < baselineTemp) {
    digitalWrite(2, HIGH);
    delay(300);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
  }
  if (celsius >= baselineTemp && celsius < baselineTemp + 5) {
    digitalWrite(2, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
  }
  if (celsius >= baselineTemp + 5 && celsius < baselineTemp + 10) {
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
  }
  if (celsius >= baselineTemp + 10 && celsius < baselineTemp + 15) {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, HIGH);
  }
  if (celsius >= baselineTemp + 15) {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, HIGH);
    delay(300);
    digitalWrite(4, LOW);
  }
  delay(300); // Wait for 300 millisecond(s)
}

LCD display delløsning kode

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}

Leave a Reply