# UCL-EMBEDDED WAKE-UP LIGHT WITH THERMOSTAT CONTROLLER

265

3

1

I found the inspiration to this project in the problem I am experiencing in the cold winter mornings. I would like the temperature to be below 18 degrees Celsius when I go to bed but be around 24 degrees when I wake up. It would also be preferable to not wake up in a pitch-black room. So, I decided to build a wake-up light that also can control the radiator valve.

### Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

## Step 1: INTRODUCTION

Function

The finished prototype should be able to turn on a light starting at a set time and reaching its max brightness after 30 minutes, or shorter for demonstration purposes. If the temperature is below the wanted 1 hour before wake-up a motor will turn on the heat by releasing a pin on the valve. After a set time the motor will close the valve and turn of the light. The current temperature and time is displayed on an OLED also showing if the heat has been turned on and if the light is on.

Time

The first step in the programming was to get the Arduino to display the current time and remember it even after a power failure. This is essential since the whole basis of the program is to act at given times of the day. This was done using a Real-Time-Clock module that has its own backup battery and can store time, date and day. Only the time is used in this project, but it would be possible to set that the program wouldn’t be activated in the weekend for example or between certain dates.

Temperature

A DHT22 sensor has been used reading the temperature and humidity. In this project I’m only interested in the temperature. But this could also be used if we would like to improve air quality.

Light

To be able to slowly turn on the light I have used a digital PWM signal that simulates a rising voltage. A value is added of 3 is added every 20 seconds until max 255 I s reached. If this is done directly on the Arduino it would only be possible to power a small LED. To get a stronger light we must have an external power source, I have used a 12-volt power supply since it’s the same that is required to drive the motor. These 12 volts is routed through a MOSFET that can handle a much higher current than an ordinary transistor. The PWM signal with a low voltage is then controlling a higher voltage. On the other side of the MOSFET is the light I have used a 10WATT halogen because I didn’t have a high power led available but that would be preferable.

Motor

I have used a NEMA17 stepper motor that is connected trough a DSV8825 driver to a 12-volt power supply. I have also added a relay that only powers on the motor and driver board when needed. This is because I experienced that the motor would vibrate slightly and warm the driver elsewise. To make the motor act like a linear actuator I have 3d printed a holder and a square actuator. When the motor turns it will unscrew or tighten the actuator pushing the valve. In the off position the valve is closed and when we want to open for the heat the actuator will retract towards the motor. This movement has been calculated to 4.8 revolutions á 200 steps = 960 steps. This is done in around 1 second. When the heat should be turned off the actuator will propel forward and push the pin inwards. A problem with the stepper motor is that it will not remember its position so if the power is removed between start and stop and it could result in errors resulting in a damaged actuator. This could be prevented using microswitches.

## Step 2: COMPONENTS

I have decided and worked with the following components, many of which can be exchanged or swapped out for better suitable parts. I would have liked to implement a Bluetooth controller, so it would be possible can change settings without connecting it to a computer, but this is not implemented yet.

1 Arduino Mega 2560 (With breadboard and jumper wires)

2 DHT22 Temperature and humidity sensor (I’m only interested in the temperature)

3 Real time Clock module 1302 (Clock with battery backup)

4 OLED Display SSD1306 SPI 128x32 (Displays current time and temperature and if the heat or light is on.

5 MOD-MOSFET IRF5305S Power (Uses PWM signal from Arduino to control 12v current to the light)

6 DRV8825 (Driver for Stepper motor sets direction and steps)

7 Nema 17 stepper motor bipolar (Drives 3d print actuator)

8 Relay activated by 5v connects driver and motor to 12 volt.

9 Light (intended use was a 12v LED) but I have used a suboptimal 10watt halogen

10 Capacitor 100um connected between driver and 12 volt

11 Power supply 12 volt DC and 4170 mah

## Step 3: WIRING

The circuit diagram has been made using fritzing, all the components I have used is not available in the fritzing stock library. Parts have been substituted for the ones that closest resembles the actual components. Comments have been made describing the used parts and their connections.

## Step 4: PROGRAMMING

```// Library
#include <SPI.h>
#include <Wire.h>// Temperature Sensor
#include
#define TEMP_PIN 52
SimpleDHT22 dht22(TEMP_PIN);
// Real Time Clock Module
#include <SimpleDHT.h>
#define RTC_RST 38
#define RTC_DAT 40
#define RTC_CLK 42
DS1302 rtc(RTC_RST, RTC_DAT, RTC_CLK);

// Motor to radiator and Light Pins
#define RELAY 3 // relay 12v to motordrive
#define LIGHT 2 // 10 watt light

// Connections to DRV8825 driver for motor
const int DIR_PIN = 5;  // Direction
const int STEP_PIN = 4; // Step

// Motor steps per rotation
const int STEPS_PER_REV = 200;

// OLED Display 128x32 SPI
#define OLED_MOSI   11
#define OLED_CLK   12
#define OLED_DC    9
#define OLED_CS    8
#define OLED_RESET 10
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);Time t; // SET HEAT AND LIGHT START AND STOP TIMES

// Time when the radiator should be turned on and off if Temp is to low (Start 1h before Wake-Up end 15 min after)
const int Warm_Hour = 06;
const int Warm_Min = 00;
const int Cold_Hour = 07;
const int Cold_Min = 15;

// Time when the light should turn on and off (Start 30m before Wake-up end 15m after)
const int Light_Hour = 06;
const int Light_Min = 30;
const int Dark_Hour = 07;
const int Dark_Min = 15;

// Temperature that we want to have  ( if below this at given time heat should be activated)
const int Want_Temp = 24;// Time between reads
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;
long Read1 = 2000; //DHT
long Read2 = 1000; // RTC
long Read3 = 20000; // LED

// Variables
int brightness = 0;    // how bright the LED is 0-255
int fadeAmount = 3;    // how many points to fade the LED by 0-255
float temperature = 0; // with 2 decimal points in Celsius
float humidity = 0;   // not read in the Program
int err = SimpleDHTErrSuccess; //
int HEAT_ON = 0 ; // If one the heat has been activated

//Start Setup

void setup()
{ Serial.begin(9600);
rtc.halt(false);
// Uncomment and set time if needed
rtc.writeProtect(false);
rtc.setDOW(SUNDAY);        // Set Day-of-Week
rtc.setTime(06,59,00);     // Set the time (24hr format)
rtc.setDate(18, 11, 2018);   // Set the date to Day-Month-Year

// Define inputs and outputs
pinMode(TEMP_PIN, INPUT);
pinMode(LIGHT, OUTPUT);
pinMode(RELAY, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);

// Set pins to default setting
digitalWrite(LIGHT, LOW);
digitalWrite(RELAY, LOW);

// Start display
display.begin(SSD1306_SWITCHCAPVCC);
display.clearDisplay();
display.setTextColor(WHITE);
}

// LOOP Program

void loop()
// get current time stamp , only need one for both if-statements
{{ unsigned long currentMillis = millis();

// Read temperature and return error if not read properly
if ((unsigned long)(currentMillis - previousMillis1) >= Read2)
{ Serial.println("=================================");
Serial.println("Sample DHT22...");
previousMillis1 = currentMillis;
if ((err = dht22.read2(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess)
{
Serial.print("Read DHT22 failed, err=");
Serial.println(err);
previousMillis1 = currentMillis;
}

// Gets the current time in seperate hours and minutes and prints to serial monitor
if ((unsigned long)(currentMillis - previousMillis2) >= Read2)
{ t = rtc.getTime();
Serial.print(t.hour);
Serial.print(" hour(s), ");
Serial.print(t.min);
Serial.print(" minute(s)");
Serial.println(" ");
previousMillis2 = currentMillis;

// Print Day of Week , Date and time strings to serial monitor
{ Serial.print(rtc.getDOWStr());
Serial.print(" ");
Serial.print(rtc.getDateStr());
Serial.print(" -- ");
Serial.println(rtc.getTimeStr());
}

// Write time and temperature to diplay in wanted size and X&Y position
{ display.clearDisplay();
display.setTextSize(2);
display.setCursor(13, 0);
display.println((rtc.getTimeStr()));
display.setTextSize(1);
display.setCursor(7, 16);
display.print(((float)temperature));
display.print("c");
if (HEAT_ON  == 1) // Display Heat on OLED if activated
{ display.setTextSize(1);
display.setCursor(48, 16);
display.print("+HEAT");
}
if ( brightness >= 1) // Display Light on OLED if activated
{ display.setTextSize(1);
display.setCursor(84, 16);
display.print("*LIGHT");
}
display.display();
}

// If the temperature is below the wanted at set time  activate the Heat
if (t.hour == Warm_Hour && t.min == Warm_Min && Want_Temp >= ((float)temperature) && ((float)temperature) > 0 &&  HEAT_ON  == 0)
{ digitalWrite(RELAY, HIGH);
digitalWrite(DIR_PIN, HIGH); // High is Release
Serial.println("HEAT ON");

// Increment motor with 1 step every 500 microseconds until the goal off 960 steps is reached
for (int x = 0; x < (STEPS_PER_REV * 4.8); x++)
{
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(500);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(500);
HEAT_ON = 1;
if ( x >= 960)
{ digitalWrite(RELAY, LOW);
}
}
}

// Deactivate the heat at set time
else if (t.hour == Cold_Hour && t.min == Cold_Min && HEAT_ON == 1)
{ digitalWrite(RELAY, HIGH);
digitalWrite(DIR_PIN, LOW); // Low is Tight
Serial.println("HEAT OFF");
// Increment motor with 1 step every 500 microseconds until the goal off 960 steps is reached
for (int x = 0; x < (STEPS_PER_REV * 4.8); x++)
{
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(500);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(500);
HEAT_ON = 0;
if ( x >= 960)
{
digitalWrite(RELAY, LOW);
}
}
}
// Activate the light at set time
if (t.hour == Light_Hour && t.min == Light_Min && brightness == 0 )
{ analogWrite(LIGHT, brightness);;
Serial.println("LIGHT ON");
Serial.println(brightness);
brightness = brightness + fadeAmount;
}

// Increase light with PWM with 3 points(fadeAmount) every 20 seconds(Read3) until max 255
if ( brightness >= 1 && ((unsigned long)(currentMillis - previousMillis3) >= Read3) && brightness <= 253)
{ brightness = brightness + fadeAmount;
analogWrite(LIGHT, brightness);
Serial.println(brightness);
previousMillis3 = currentMillis;
}

// Deactivate the light at set time
else if (t.hour == Dark_Hour && t.min == Dark_Min)
{ brightness = 0;
Serial.println("LIGHT OFF");
Serial.println(brightness);
analogWrite(LIGHT, brightness);
}}}}}```

## Step 5: 3D PRINT AND MAKING OF ACTUATOR WITH HOLDER

Since the nema17 motor didn´t have any attachments when i bought it, i needed to make a thread to drive the actuator forward. This was made in brass since i had access to machinery. But this can also be done using only 3d printed plastic.

## Step 6: FINISHED PROTOTYPE

I would have liked to make the prototype in a neat little package, but since i want to use the parts for other projects and didn´t want to solder them it was hard to achive. The section with the lamp was originally designed for a electromagnet that i didn´t end up using since the radiator pin needed 1.2 kg of force to push.

## Step 7: CONCLUSION

Since this is my first arduino projekt i´m pretty satisfied with the results, the function is almost the one i set out to achive. I have learned more about coding in c++ along the way. A lot of the parts could have been better suitable and i could have soldered them but this would cost more time and money. This would allow me to make a 3d printed housing for the whole setup. I would also like to have been able to change the varibles via bluetooth or wifi without connecting the arduino to a computer but i didn´t find the time to implement this.

## Step 8: INSPIRATION

I have used the following sites as inspiration.

https://forum.arduino.cc/index.php?topic=518548.0

http://www.schmalzhaus.com/EasyDriver/Examples/EasyDriverExamples.html

https://dronebotworkshop.com/stepper-motors-with-arduino/

https://www.instructables.com/id/Controll-a-Stepper-Motor-With-the-DRV8825/

http://acoptex.com/project/168/basics-project-033c-l298n-dual-h-bridge-motor-driver-module-dc-6v12v-unipolar-or-bipolar-stepper-at-lex-c/#sthash.GoUZpaTh.VRwgStAr.dpbs

https://skillswappingspring12.wordpress.com/2012/03/02/using-mosfets-and-pwm-on-the-arduino/

https://maker.pro/arduino/projects/arduino-oled-temperature-display-real-time-clock

http://mertarduinotutorial.blogspot.com/2017/09/arduino-turn-on-off-anything-at.html

https://www.brainy-bits.com/connect-and-use-a-spi-oled-display/

## Recommendations

• ### Internet of Things Class

22,837 Enrolled