DIY Hacking your own Home Automation System

Written by: roboguru

Picture of DIY Hacking your own Home Automation System20150428_115053_zpsdkzkr5og.JPGFI75YIPI7VQSSYN.jpeg

A home automation system should be able to turn on/off appliances such as lights, fans, entertainment systems, etc. A system that is wireless yet independent from the Internet, but most importantly, DIY and open-source because I want to understand how it works.

Why re-invent the wheel?

Someone was nice enough to do most of the work for us ;-)

The CoreConduit: Garden Controller System is a project I created that can easily accommodate home automation applications with an understanding of how it works and what changes need to be made. Remember to make every attempt to respect licenses and credit those for their hard work.

Step 1: Review the CoreConduit: Garden Controller System

Picture of Review the CoreConduit:  Garden Controller System

The Coreconduit: Garden Controller System does more than we need for human living conditions so let's see what it is doing so we can make some changes. The author of the Instructable drones on and on about healthy plants requiring attention and boredom until,

"...I've programmed into the Arduino a function I called, "TheDecider" that makes decisions based on maintaining optimum environmental conditions for growing plants. I added 2.4Ghz Wireless Radio Transceiver modules and a modular receiver system so that data is transmitted to within 1000 feet."

Nice! We should take a look at this, "TheDecider"

Another plus for this project is:

"With safety in mind, I chose not to use relays that expose AC currents. Instead, I chose to use Remote Controlled Wireless Outlets for controlling lights, pumps, fans, heaters, and humidifiers."

Step 2: Download the source-code

Picture of Download the source-code

Download the source-code from GitHub.

The Instructable explains:

"In the source-code I created a base foundation for managing, transmitting, and receiving "sensor" objects and "appliance" objects. This project could easily be modified to work with other environments in which control is achieved by reading sensors and operating appliances based on programmed rules. You'll need to make a few adjustments to the source-code in order for it to work properly with your wireless outlets. To make the changes, you'll need to find out what the codes are that your wireless remote control uses and the outlets are programmed to receive. I have included a sketch for installing onto your Arduino Uno* w/ protoshield to set the Real-Time Clock to the current time and step you through the process of acquiring the codes. You will need to insert the 433Mhz Receiver module (as pictured) and upload this sketch, StartCore.ino to the Arduino Uno* and open up the serial console for that port so that you can receive data from the Arduino."

Let's make one!!

"After you complete the process of acquiring all of the codes from your remote you can copy and paste directly into TheDecider.h header file where I have indicated."

Step 3: Build the controller

Picture of Build the controller20150501_104324.jpg

Parts: ( links provided as reference )

Optional Parts:

  • Arduino Uno R3* or Pro Mini*
  • Real-Time Clock Module
  • Optional: nRF24L01 Adapter with 3.3v regulator
  • connector wires
  • Display Option LCD w/ buttons Shield + Arduino Uno R3*
  • 2 x 4-pin male header connector wires
  • SD Card Option SD Card Shield + Arduino Uno R3*
  • connector wires

Internet Connectivity Option


Step 4: Some assembly required

Picture of Some assembly required20150330_113811.jpgRF Modules.jpgArduino2RTC.jpg20150327_183134.jpgF9YPTQSI7VQLGV3.jpeg

Start by figuring out what codes your own particular wireless remote AC outlets use. The source-code assumes that there is a 433Mhz receiver on pins 2 (ground), 3 (Data), 4 (Vcc) and a real-time clock module connected via I2C using A5 (SCL), A4 (SDA), Vcc, ground.

Step 5: Programming wireless remote AC outlets

Picture of Programming wireless remote AC outlets

  • Load the sketch StartCore.ino into your preferred Arduino programming environment.
  • Compile and upload the sketch to your Arduino Uno.***
  • Set the Serial Port to the appropriate port and select "19200" as the baud rate.
Opening portPort openDEBUG MODE?received:  1DS1307 configured Time=09:50:04, Date = Jun  2 2015
  • Press the remote control "On" buttons in numerical order: 1 - ON
mySwitch.setPulseLength(188);unsigned long mySwitchOn[] = { 24,21811
  • continue pressing, pausing to wait for the numbers to appear on the monitor.
  • 2 - ON, 3 - ON, 4 - ON, 5 - ON.
mySwitch.setPulseLength(188);unsigned long mySwitchOn[] = { 24,21811,21955,22275,23811,29955 };
  • repeat the same process for the "Off" buttons.
unsigned long mySwitchOff[] = { 24,21820,21964,22284,23820,29964 };
  • Last step here is to select the output code and copy & paste it intoTheDecider.h file. near the top of the file where there are default values that look similar.

*** If you have any problems compiling, the most common reason is missing library files. Please double-check that you have all the necessary listed files.

Step 6: Identifying appliances

Picture of Identifying appliances

Now that the controller is programmed with the codes for our AC outlets, we need to know what number goes to what appliance.

  • Open the sketch for the controller
  • Locate the sensor and appliance object definitions
// Initialize AppliancesAppliance Appliance_IntakeFan  = {101, APPLIANCE_INTAKE_FAN, true, DEFAULT_TIME, OFF, NULL };Appliance Appliance_ExhaustFan  =  {102, APPLIANCE_EXHAUST_FAN, true, DEFAULT_TIME, OFF, &Appliance_IntakeFan };Appliance Appliance_Humidifier = {104, APPLIANCE_HUMIDIFIER, true, DEFAULT_TIME, OFF, &Appliance_ExhaustFan};Appliance Appliance_Light =  {103, APPLIANCE_LIGHT, true, DEFAULT_TIME, OFF, &Appliance_Humidifier};Appliance Appliance_Heater = {106, APPLIANCE_HEATER, true, DEFAULT_TIME, OFF, &Appliance_Light};Appliance Appliance_FeedPump = {105, APPLIANCE_PUMP, true, 0, OFF, &Appliance_Heater};
  • Verify pin numbers correspond according to the outlets and appliances. The pin numbers over 100 are so numbered to indicate that they correspond to remote AC outlets rather than directly from an Arduino pin.

Step 7: Going wireless

Picture of Going wireless20150408_073050_zpstpi2etrr.JPG20150501_104507.jpgnrfAdapter..jpg

Now that the controller is programmed with the codes for our AC outlets, we can add the nRF24L01 module.

Using the DuPont Rainbow ribbon with 2.54mm female connectors so that I can make custom wire connectors:

  • Pin number on Arduino / Wire Color / nRF24L01 Pin
  • Pin 9 : Orange / CSN "Chip Select"
  • Pin 10: Yellow / CE "Chip Enable"
  • Pin 11: Green / MOSI "Master Out, Slave In"
  • Pin 12: Blue / MISO "Master In, Slave Out"
  • Pin 13: Purple / SCK "System Clock"
  • Vcc 3.3v* Red (if not using Uno, optional adapter board with voltage regulator)
  • Ground. Brown

Wire color coding looking at the nRF24L01 component side with the crystal oriented on top - from bottom right, going up: Brown | Orange | Purple | Blue. Left from bottom going up: Red | Yellow | Green | NC

More amazing information on connecting the nRF24L01 to Arduino.

Step 8: Receiver side

Picture of Receiver sideFLPKRUAI8FQSN06.jpeg

The Receiver source-code assumes that it is going to be compiled and executed on an Arduino Uno or ProMini connected to an nRF24L01, same as The Controller. As part of the Garden Controller System, the Receiver will send alerts via attached LCD Display and/or audible alert from a piezo connected on pins 2 (ground), 3 (signal), 4 (Vcc). For use in home automation projects, the alerts system can be removed or the rules customized according to the desired effect.





Step 9: Break it down

Picture of Break it down

Now we have our very own Garden Controller System.

Wait! I mean, very own DIY Home Automation system. By default, the controller is programmed with a lot of rules that we need to comment-out. Open-upTheDecider.h file once again.

bool TheDecider( void )
{  bool r = false;  time_diff = 0;  time_now = now();
// update app.ready if it's been 5 minutes since last change.
Appliance * app = &Appliance_FeedPump;
 for (; app != NULL; app = app->next ){   	time_diff = (time_now - app->timestamp);	if (time_diff > 300) { app->ready = true; } }  
This code is stepping through all of the "appliance" objects and verifying that we have waited at least 5 minutes before checking the appliance since the last change.  The code makes sense when you are controlling fans and garden grow lights but for home automation purposes, this can be reduced.  I personally wouldn't set it below 30 seconds.

The next chunk of code in TheDecider function makes sure that the sensor data for humidity and temperature is functioning as expected:

if ( Sensor_Humidity.value == 0 ){ 	Appliance_Humidifier.ready = false;}	if ( Sensor_Temp.value == 0 ){	Appliance_ExhaustFan.state = true; Appliance_ExhaustFan.ready = false;	Appliance_IntakeFan.state = true; Appliance_IntakeFan.ready = false;}

The following code is for regulating temperature by controlling fans:

// RH Rangeif (Appliance_Humidifier.ready == true) {	// IF the humidity is less than the minVal and the Humidifier is OFF	// THEN turn ON the Humidifierif ((Sensor_Humidity.value < Sensor_Humidity.minVal) && (Appliance_Humidifier.state != true)){ r = true; Appliance_Humidifier.state = true;myAppliance(&Appliance_Humidifier, false);}		// IF the humidity is less than the minVal, turn ON the PUMPif ( (Sensor_Humidity.value < Sensor_Humidity.minVal) ){r = true; Appliance_FeedPump.state = true;myAppliance(&Appliance_FeedPump, false);}...

The next chunk of code is evaluating whether a photocell is receiving light and what action should be taken.

// IF the light reading is greater than the minVal// AND the ExhaustFan is ON - THEN turn OFF Light(s)if ( Appliance_Light.ready ){if ( (Sensor_Light.value > Sensor_Light.minVal) && (Appliance_ExhaustFan.state == true) ){ r = true; Appliance_Light.state = false; myAppliance( &Appliance_Light, false );}// IF the light reading is less than the minVal// THEN turn OFF lightsif (Sensor_Light.value < Sensor_Light.minVal){ r = true; Appliance_Light.state = false;myAppliance(&Appliance_Light, false); }} 

The remaining rules are for regulating a water pump. We can remove or comment them out. TheDecider function ends with:

/* ToDo: */
return r; }





Step 10: Timing is everything!

Picture of Timing is everything!

Inside both the Controller_nRF.ino sketch and Receiver_nRF.ino basic timers are used to create a state machine in which flags are set and continuously checked.

Timer Objects with built-in flags:

Timer Timer_Log	= { TIMER_LOG, 300000UL, true, false, 0, NULL };<br>Timer Timer_rxData = { TIMER_RX_DATA, 2500L, true, false, 0, &Timer_Log };Timer Timer_Save_Settings = {	TIMER_SAVE_SETTINGS, 3600000UL, true, false,  0, &Timer_Log };Timer Timer_Sensor_Read	= { TIMER_SENSOR_READINGS, 5000UL, true, false,  0, &Timer_Save_Settings };Timer Timer_Alerts = { TIMER_ALERTS, 60000UL, true, false,  0, &Timer_Sensor_Read };

timing is in microseconds. According to the default source code the Timer_Log has a frequency of 5 minutes.

Inside the loop of Controller_nRF.ino and what actions are to be taken:

if ( clockFlag == true ) {	if ( checkTimer( &Timer_Log ) ) {  checkAppliances(); }	if ( checkTimer( &Timer_Sensor_Read ) ) { keepAlive(); readSensors(); TheDecider(); }}





Step 11: Going further...

Picture of Going further...

Using Arduino Uno, Pro Mini, nRF24L01, and other open-source modules opens the door to many possibilities. We now have a wireless framework for sending data objects for sensors, appliances, alerts, etc, using a controller for remote AC outlets and sensor inputs and a receiver for exploring development of a user interface. TheDecider can be updated to perform any number of tasks based on sensor and user inputs. What the receiver does in response to the data it receives is up to you.

Enjoy tinkering!!

Interested in Hydroponics?