Introduction: UCL-EMBEDDED WAKE-UP LIGHT WITH THERMOSTAT CONTROLLER

About: automation student

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.

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 #include <Adafruit_SSD1306.h>

#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://www.ti.com/lit/ds/symlink/drv8825.pdf

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://www.youtube.com/watch?v=0mYwr933rz8

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

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/now-for-two-at-once

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/