Introduction: Arduino Controlled Room Heating System

The first thing that came to my mind when I started micro-controller programming was to set an automatic room heating cum humidifier system. Bangalore has a very confusing weather - especially for new-comers. The temperature is generally moderate, but nights can sometimes become very cold. However, on other days, the nights are warm and if you have a heater on - it becomes uncomfortable. Also, since the weather is generally moderate - automatic heating solutions are not available commercially.

Hence, one of the first projects I made on an arduino was a temperature and humidity controller.

Features:

  1. Controls a 2-relay board - one for a room heater and one for a humidifier.
  2. Checks the temperature and humidity every 10 minutes - this can be set in the code
  3. The algorithm is very simple - Switch off the heater if the temperature goes 1 degree above the set-point and switch it on again if it goes below the set-point. This is similar to most commercial systems.
  4. The humidifier gets switched on if the humidity is below 40% and gets switched off if it goes above 60%.
  5. Uses the EEPROM to save the preset
  6. Has one button that is used to change the preset - single click to increase the temperature by 1 degree, long press to decrease the temperature by 1 degree. The temperature circles between 25 and 30 degree centigrade.

Step 1: Electronics

  1. Atmega 328P-PU (without bootloader)
  2. 16 MHz Crystal
  3. 2 x 22 pf capacitors
  4. LM 7805
  5. 1 uF + 10uF Electrolytic capacitors
  6. 10k Resistor
  7. DHT11 Breakout Board or similar (http://cgi.ebay.in/ws/eBayISAPI.dll?ViewItem&item=...)
  8. 2 Channel Relay Board
  9. 1 push-button switch
  10. 16x2 character LCD
  11. 10k pot
  12. 9-12V 1Amp power supply
  13. Extension cord
  14. Wires
  15. General purpose PCB

Instructions for creating and using a "standalone arduino" can be found at http://dushyant.ahuja.ws/2013/10/standalone-arduin...

Step 2: The Circuit

The Fritzing layout is above. I know it looks extremely confusing – but this was the best I could do (this was my first attempt at using fritzing).

The circuit is actually very simple:

  1. Relay 1 is connected to pin A1
  2. Relay 2 is connected to pin A2
  3. A switch is connected to between pin A5 and ground - it uses an internal pullup resistor to maintain a HIGH value
  4. DHT 11 is connected to pin 13
  5. LCD pins D4-D7 are connected to pins 5-8
  6. LCD RS pin is connected to pin 11
  7. LCD EN pin is connected to pin 12
  8. The NO sockets of the relays need to be connected between the 110/220 V power and the plug point
  9. Details to connect the LCD can be found at: https://learn.adafruit.com/character-lcds/wiring-a...

Step 3: The Code

The code utilises the following libraries (and all thanks to the authors of these libraries):

  1. OneButton: http://www.mathertel.de/Arduino/OneButtonLibrary.a...
  2. DHT11: http://playground.arduino.cc/main/DHT11Lib
  3. Timer: https://github.com/JChristensen/Timer
  4. EEPROM & LiquidCrystal: both part of the Arduino IDE
#include "OneButton.h"
#include "EEPROM.h"
#include "Timer.h"

#define RELAY1 A1           // Connect humidifier to Relay1
#define RELAY2 A2           // Connect heater to Relay2
#define TEMP_SET 25         // Starting Temperature
#define MAX_TEMP 30         // Max Temperature
#define HUM_SET 40          // Threshold humidity
#define HUM_SET2 60
#define SWITCH_PIN A5       // Connect the switch between pin A5 and ground
#define CYCLE 10           //Time in minutes for each cycle

#include "LiquidCrystal.h"
#define LCD_RS 11           // * LCD RS pin to digital pin 12 - Green
#define LCD_EN 12           // * LCD Enable pin to digital pin 11 - Yellow
#define LCD_D4 5            // * LCD D4 pin to digital pin 5 - Blue
#define LCD_D5 6            // * LCD D5 pin to digital pin 6 - Blue
#define LCD_D6 7            // * LCD D6 pin to digital pin 7 - Blue
#define LCD_D7 8            // * LCD D7 pin to digital pin 8 - Blue

#include "dht11.h"
#define DHT11PIN 13

dht11 DHT11;
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
int temp_set;
Timer t;
OneButton button1(SWITCH_PIN, true);

void setup() {
  pinMode(DHT11PIN, INPUT);
  pinMode(LCD_RS, OUTPUT);
  pinMode(LCD_EN, OUTPUT);
  pinMode(LCD_D4, OUTPUT);
  pinMode(LCD_D5, OUTPUT);
  pinMode(LCD_D6, OUTPUT);
  pinMode(LCD_D7, OUTPUT);
  pinMode(RELAY1, OUTPUT);
  pinMode(RELAY2, OUTPUT);
  lcd.begin(16, 2);
  Serial.begin(9600);
  if(EEPROM.read(0) >= MAX_TEMP+1){
    EEPROM.write(0,TEMP_SET);
    temp_set=TEMP_SET;
  }
  else {temp_set=EEPROM.read(0);}
  lcd.print("Setpoint: ");
  lcd.print(temp_set);            // Display the setpoint temperature for 2 sec
  delay(2000);
  checkTemp(0);
  t.every(60000*CYCLE,checkTemp,(void*)0);
  button1.attachClick(tempPlus);
  button1.attachPress(tempMinus);
}

void loop() {
  // put your main code here, to run repeatedly: 
  button1.tick();
  t.update();
}

void tempPlus(){
      Serial.println("Plus");
      temp_set++;
      if (temp_set > MAX_TEMP) temp_set = TEMP_SET; // Cycle between TEMP_SET and MAX_TEMP
      lcd.clear();
      lcd.print("Setpoint: ");
      lcd.print(temp_set);
      EEPROM.write(0,temp_set);
      delay(1000);
      checkTemp(0);
}

void tempMinus(){
      Serial.println("Minus");
      temp_set--;
      if (temp_set < TEMP_SET) temp_set = MAX_TEMP; // Cycle between TEMP_SET and MAX_TEMP
      lcd.clear();
      lcd.print("Setpoint: ");
      lcd.print(temp_set);
      EEPROM.write(0,temp_set);
      delay(2000);
      checkTemp(0);  
}

void checkTemp(void* context)
{
  int chk = DHT11.read(DHT11PIN);
  // Serial.print("Read sensor: ");
  /* switch (chk)
  {
    case DHTLIB_OK: 
               // Serial.println("OK"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
               // Serial.println("Checksum error"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
               // Serial.println("Time out error"); 
                break;
    default: 
                lcd.println("Unknown error"); 
                break;
  }*/
  lcd.setCursor(0, 0);
  Serial.println(DHT11.humidity); 
  lcd.print("Humidity: ");
  lcd.print((float)DHT11.humidity, 2);
  lcd.setCursor(0, 1);
  lcd.print("Temp: ");
  lcd.print((float)DHT11.temperature, 2);
  Serial.println(DHT11.temperature); 
  if(DHT11.humidity < HUM_SET2){ 
    digitalWrite(RELAY1, HIGH);
    Serial.println("H1");
  }
  if (DHT11.humidity > HUM_SET) {
    digitalWrite(RELAY1,LOW);
    Serial.println("H0");
  }
  if(DHT11.temperature < temp_set){ 
    digitalWrite(RELAY2, HIGH);
    Serial.println("T1");
  }
  if (DHT11.temperature > temp_set){
    digitalWrite(RELAY2,LOW);
    Serial.println("T0");
  }
}

Step 4: Assembly

The assembly was slightly difficult as fitting the entire circuit, LCD, Relay board and power adapter inside the extension cord was a tight fit. However, you can see how everything was fit inside in the photgraphs above.

Also, this would depend a lot on the model of your extension cord and hence there is no "right way"

Step 5: Final Result

Features:

  1. Controls a 2-relay board - one for a room heater and one for a humidifier.
  2. Checks the temperature and humidity every 10 minutes - this can be set in the code
  3. The algorithm is very simple - Switch off the heater if the temperature goes 1 degree above the set-point and switch it on again if it goes below the set-point. This is similar to most commercial systems.
  4. The humidifier gets switched on if the humidity is below 40% and gets switched off if it goes above 60%.
  5. Uses the EEPROM to save the preset
  6. Has one button that is used to change the preset - single click to increase the temperature by 1 degree, long press to decrease the temperature by 1 degree. The temperature circles between 25 and 30 degree centigrade.

Step 6: Extending the Functions

The following pins are accessible from the outside:

  1. RX and TX pins
  2. Reset pin (to program the arduino)
  3. pin 13
  4. Two sets of +5 and GND

By replacing the DHT11 and reprogramming, this can be used as a smart power strip. Some of the uses I could think up are:

  1. Replace the DHT11 with a soil hygrometer - can be used to switch on a pump to water plants when the soil becomes dry.
  2. Replace the DHT11 with an LM35 or PT100 - and create a sous vide cooker
  3. Connect a Bluetooth HC-05 module to the RX and TX ports - an voila - a bluetooth controlled power strip that can be controlled from a mobile phone
  4. Replace the DHT11 with a PIR sensor, and the heaters with a lamp - and you get a motion controlled lamp

Suggestions welcome - please let me know how you would extend this in the comments below.

Step 7: References and Links

  1. Original blog post: http://dushyant.ahuja.ws/2013/11/standalone-temperature-and-humidity-control/
  2. Project Github: https://github.com/dushyantahuja/Smart-Power-Strip

Further Assembly details:

  1. Standalone Arduino: http://dushyant.ahuja.ws/2013/10/standalone-arduino/
  2. LCD Assembly: https://learn.adafruit.com/character-lcds/wiring-a-character-lcd

The code utilises the following libraries (and all thanks to the authors of these libraries):

  1. OneButton: http://www.mathertel.de/Arduino/OneButtonLibrary.a...
  2. DHT11: http://playground.arduino.cc/main/DHT11Lib
  3. Timer: https://github.com/JChristensen/Timer
  4. EEPROM & LiquidCrystal: both part of the Arduino IDE
Home Technology Contest

Second Prize in the
Home Technology Contest

Epilog Challenge VI

Participated in the
Epilog Challenge VI