Project tutorial

Home Automation using Raspberry Pi 2 and Windows 10 IoT © CC BY-NC

Automated Home using Raspberry Pi 2 (Windows 10 IoT Core) and Arduino.

  • 248,503 views
  • 89 comments
  • 602 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
For each room you want to automate, take separate Arduino UNO.
×1
R8326274 01
Raspberry Pi 2 Model B
×1
11026 02
Jumper wires (generic)
×1
12002 04
Breadboard (generic)
×1
LDR (Light Dependent Resistor)
LDR provides different voltage reading for different light intensity.
×1
13285 01
PIR Motion Sensor (generic)
Passive IR detects human presence.
×1
Relay (generic)
You can use any kind of relay module. No of relay will depend upon how many devices you want to control. [NoOfDevices = NoOfRelay]
×1
Siemens Contactor (3TF32 00-0AP0)
Contactor is going to be used to control water-pump of maximum rating of AC3: 16A 415VAC. Before purchasing contactor, please check ratings of your water-pump and your contry dependencies if there. "3TF32 00-AP0" is capable to drive up-to 16A and 415VAC water-pump. This contactor operates usinf in-built coil. Coil ratings are (specific to 3TF32 00-0AP0 only) 250VAC.
×1
Miniature Circuit Breaker (1P C16A)
MCB is attached before contactor to protect water-pump from electrical faults and overload. Here MCB also have specific ratings. Our contactor is of 16A and thus I have used 16A MCB. You can modify according to your convenience.
×1

Apps and online services

Ide web
Arduino IDE
To write Arduino firmware. Have explain in the article.
Vs2015logo
Microsoft Visual Studio 2015
Community edition is commanded and its free for up-to five users. But you can use higher than it if you have purchased licensed copy of Visual Studio 2015.
10
Microsoft Windows 10 IoT Core
As a primary OS, which controls the devices via Arduino and provides management console.

About this project

In today's era, technology can enhance human life. Technology is evolving decade by decade. Automation was a science fiction earlier but not today. By combining latest technology with home, we can build an awesome home. With the Raspberry Pi and Windows 10, we can build a home automation system that is capable of operating home devices automatically.

Getting Started

Before starting the project, lets understand basics first. Consider the following image (Overall Configuration)

A Raspberry Pi 2 will serve as a master device. For each room, want to automate, an Arduino UNO is needed. Arduino UNO will act as a secondary controller, which takes command from the Raspberry Pi 2 and operates specific device. Here, Raspberry Pi 2 and all Arduino UNOs are connected together on a I2C bus. All Arduino UNOs act as slaves. Each Arduino UNO have unique I2C slave address on the bus. You can add /remove Arduino UNOs(rooms) that is explained later in this project.

Configuration for Room

Now considering room scenario, an Arduino UNO will control devices and reads sensor data. Periodically, Raspberry Pi requests for the sensor data collected by Arduino UNO. The figure "Room Architecture" depicts how the Arduino UNO will connects with the devices and sensors. Each room have multiple controllable devices(i.e. Light(s), Fan, Wall Socket(s), etc.), one PassiveIR (to detect human presence in the room), one temperature sensor (LM35 to collect room temperature) and LDR (to detect light intensity near room window).

Device Address Mapping

The most important part is how we will identify devices? Its simple. We will make device address by combining room number with device number.

For example:

Room Number 1 having three devices.
Device address will be:
  • R1\Dev0
  • R1\Dev1
  • R1\Dev2

So up till now we know the overall configuration. In short, a Raspberry Pi will act as primary controller. Each room have its own one Arduino UNO which act as slave of Raspberry Pi. Communication between Raspberry Pi and Arduino UNO will be done using I2C.



Schematics

To make it more easy, lets start implementing for first room. Refer schematic to connect components in proper way.

Note: I2C address for Room 1's Arduino is 0x40. You can change address but make sure to change it back in Aruino's sketch and room's slave address in the app provided below, too. Note that each Arduino resides on the bus must have unique slave address.

I2C Bus Stripe: To attach more than one Arduino you can use I2C Bus Stripe as show below.

The relay shown in the schematic are operated by 5VDC. You may have different rating of coil to drive relay. In such situation you need logic level converter circuit.

How to wire device with relay board?

WARNINGPlease make sure that the device is disconnected from the wall outlet and outlet is switched-off. Parent observation is required for small children.
WARNING: IN CASE OF ANY PROBLEM, SHUT DOWN HOUSE'S MAIN LINE OR ROOM'S TRIPPER LIKE MCB OR ELCB AND CALL ELECTRICIAN. PARENT OBSERVATION IS REQUIRED.

All done at hardware side. Now its time to build software.


Software

Our project consists of a Raspberry Pi 2 and Arduino UNO. Raspberry Pi 2 software developed in Visual Studio 2015. I am assuming that reader is aware with project creation for Raspberry Pi 2 in Visual Studio 2015. I am also assuming that user have intermediate knowledge of Arduino framework, Visual C# and Windows Universal XAML.

If Arduino is new for you, please refer this link. For Raspberry Pi 2 beginner, please refer this link.

Let's understand software in following formation:

  1. Protocol (How Raspberry Pi 2 and Arduino talks)
  2. Class Structure (How Raspberry Pi 2 maintains such complicate devices and rooms)
  3. User Interface (Wire-frame)


Protocol (How Raspberry Pi 2 and Arduino Talks over I2C)

Before going further, lets first decide how Raspberry Pi and Arduino talks. To make a reliable protocol, we must first have clear objectives or goals for the communication. In consideration of this project, goals are:

  • Read sensors
  • Read device's state
  • Set device state

Lets start defining protocol first. Protocol define rules to communicate over the bus. Protocol is nothing more than byte sequence.

I have defined protocol for sending and receiving bytes. Sending bytes are fixed of three while receiving byte array is of fourteen bytes.

Refer following schematics to understand protocol defined for this project ('X' denotes random value or '0', it will be ignored while communicating):



Class named 'I2C_Helper' contains implementation of protocol in PRi2's Universal app project. This class is available in Universal Windows Project. To open it: Goto Solution Explorer > Library > Communication folder. On Arduino side, it is easy to understand I2C library.

If you are newer to I2C of RPi2 (Windows IoT Core), refer this link. If you are newer to Arduino's I2C, refer this link. There is an article available for Arduino I2C Communication with RPi2 (Windows IoT Core) written by Christiano Faig.


Now, we have defined a proper communication scheme that is able to give status and values of sensors, devices and also provides accessibility to set device state.


Class Structure (How Raspberry Pi 2 Maintain Objects)

As discussed first, this project considered whole home. Home consists of multiple rooms and room consists of multiple devices. Thus the OOP structure of such configuration is shown below:

Primary class "Home" consists of multiple room objects as generic list of room (List<Room>). Home class provides static method to load and save home object on the Pi to use them later.

Room consists of devices as generic list of devices (List<Device>) and sensor structure to encapsulate all sensors into one.

Device consists of details of them and functions to turn on and off them using protocol Mode - 2. AmbientLight, PassiveIR and Temperature class provides access to the room's environmental data. Room object maintain sensor data and periodically refresh them using protocol Mode - 0.

Note: Class diagram is provided in project. To view it, goto 'Solution Explorer' and double click on 'ClassDiagram.cd'.


User Interface

Any application must be user-friendly. To make user-friendly application, start with wire-frame. Assume that you are going to use your own application and find out the main objectives and how to integrate them in such way that they will be most easy to end-user.

In this application's scenario, our main objectives are:

  • Room Management
  • Device Management
  • External Services like GSM Communication, Internet Communication, etc

To do so, I have splitted problem into:

  1. Home Page: Provides basic device status information, date-time and lock
  2. Favorite Devices: Direct access to favorite devices
  3. Room Page: Provides access to configured rooms and their devices
  4. Common Water Devices: Water-pump and Geyser
  5. Settings/Configuration: Provides management of rooms and their devices

Wire-frame:

Wire-frame:

Based on the wire-frame, I have developed UI which is shown next. You can download complete source code. Link to the download is provided at the end of the article.

I am assuming that you are familiar with XAML(people having WPF background will have advantage). XAML Source code of the project is well commented so I am not going to explain it here as its not feasible. If you are newer to WPF, refer this link for getting started with WPF and MSDN link as a reference.
 Dashboard Home page with date, time, status icons and lock button.


So, have already developed UI. Hope you can modify it upto your needs. Feel free to comment for the help.


How to configure?

I have tried to make this software as easy as possible. With minor configuration, you can operate devices directly using this Raspberry Pi 2. Step-by-step configuration is shown below:


How do I control water-pump and geyser using this app?

You can attach water-pump and geyser same way you add device. But you can't attach water-pump or geyser directly to the relay board to power them up. It will blow-up relay board as well as hazardous.

WARNING: DO NOT CONNECT WATER-PUMP OR GEYSER DIRECTLY TO RELAY-BOARD. IT IS HAZARDOUS. YOU NEED CONTACTOR TO OPERATE HIGH CURRENT DEVICES LIKE WATER-PUMP OR GEYSER. IF YOU DO NOT KNOW, PLEASE CONSULT ELECTRICIAN. YOU CAN FIND DETAILS ABOUT CONTACTOR BELOW IN PART LIST.

To operate water-pump or geyser, connect water-pump or geyser with contactor and connect contactor's coil with relay board. So now, when you operate device, relay activates contactor's coil and thus pump or geyser starts/stop. Before purchasing contactor, please make sure its coil rating and contactor's rating. Contactor are available in so many variety. So verify it with your water-pump's rating. It is advisable to purchase slightly higher rated contactor than your water-pump's rating.

WARNING: DO NOT TOGGLE DEVICES QUICKLY. IT MAY FRY DEVICE AND MAY LEAD TO ELECTRONIC SHORT-CIRCUIT. IN CASE OF ANY PROBLEM, SHUT DOWN HOUSE'S MAIN LINE OR ROOM'S TRIPPER LIKE MCB OR ELCB.


How do I deploy this solution to Raspberry Pi 2?

You can refer this link to understand deployment process.


How do I register this app as startup app?

Lot's of hobbyist wants their application start right after the Raspberry Pi 2 boots. To do so, read my article: Windows 10 IoT Core : Setting Startup App


Known Issues

Arduino Bootup

When Arduio boots, it flickers D13 pin. It is good to do not connect any relay pin on D13 because when Arduino boots or reboots, D13 will be flickerd once and if any device connected with Relay (controlled via D13) will flicker, too.

Solution: There are two options: first one, simply do not connect realy with D13. Second one is bit complicated. You can rewrite Aruino's OptiBoot firmware that do not use D13 while booting and burn that bootloader to Arduino.

Clock Issue

Raspberry Pi 2 does not have on-board Real Time Clock chip. Thus it is not possible to maintain time after power-failure or fresh boot. Thus external RTC must be attached and programmed to maintain date time.

Solution: NTP can be used but needs Internet connection or even Arduino can deals with RTC and Raspberry Pi requests for the date time at boot. It is also good to attach external RTC directly with RPi 2.


Debugging Issue

I had faced many issues while developing Universal App in C#. Universal app is superset of WinRT and thus so much asynchronous operation needed to be performed. If error arises in  asynchronous operation, it becomes headache to solve. Whenever any exception or error occurred, most of time I faced following screen:


No point to the error prone line, no programmer friendly message, nothing. I have to place so many breakpoint to find out the cause of the error. In debugging, sometimes universal app just shuts-down without any prior notice and suddenly my watch window becomes useless. The cause of the behavior is described at this link.

Solution: Place breakpoint before the expected error prone line.

In short, at this moment (while this article was published) universal app is great but lacks of debugging features as conventional Windows application have.


Future

There is no limitation when it comes to features, new ideas or even to overcome existing limitation. But it is not feasible to add each and every feature at once. At this release, this article lets you understand real power of Raspberry Pi 2 and Windows IoT. Windows Universal XAML is great GUI framework for Windows 10 IoT & Raspberry Pi 2 have good graphics processor on board. By combining these two, an extraordinary looking GUI solution can be created. In addition, Raspberry Pi 2 have 900MHz quad-core CPU, which is quite awesome for multi-threaded (in UWP, Task) solutions. This is the basic to intermediate project for those who wants to learn fundamentals of embedded and software system (i.e. I2C bus communication, how to operate appliances, custom protocol design, OOP design for real-world application and wire-frame).

In future, we can add capability to communicate over remote devices using RadioFrequency or InfraRed instead of I2C bus. Web-management portal using Azure can be integrated for mobile devices. Further the real automation will be integrated like event based operation, timed operation with RTC chip. For example, turn on backyard lights at 7:00 P.M. and turn back them off at 10:00 P.M.; a good example for event based is to turn on garden's lights when ambient light intensity decreased below specific intensity and so on. So there is no limitation for this new Windows 10 IoT Core platform for Raspberry Pi 2.


Good Luck & Be Safe :)

Feel free to ask for help or questions.

Schematics

Schematic for one room
You can add multiple room by attaching individual Arduino with unique I2C slave address on the bus.
%5benhanced%20updated%5d%20main%20circuit%20diagram
Fritzing Schematic File
Fritzing file containing complete schematic.
Home Automation Schematic - Anurag S Vasanwala.fzz

Code

Arduino SketchC/C++
/*
	Arduino Sketch v0.4

	This sketch is written for "Home Automation using Raspberry Pi 2 and Window 10 IoT"
	Refer this link: https://www.hackster.io/AnuragVasanwala/home-automation

	This sketch is tested on Atmega328p only.

	This sketch prepares an Arduino device as slave	device on I2C bus operated by
	Raspberry Pi 2 running Windows 10 IoT Core.

	Objectives:
		+ Periodically collect sensor data (Function: loop)
		+ OnRecevive, collect 3-bytes mode instruction
		  and performa operation based upon it. (Function: ReceiveData)
		+ OnRequest, send 14-bytes response array based
		  on selected mode by OnReceive. (Function: SendData)
	
	This sketch is provided as it is without any WARRANTY. You can use it for personal as well as
	commercial use.

	I am not liable for any loss of data or injuries caused by this sketch.
*/

#include <Wire.h>  
#define _DEBUG_

/* Arduino's I2C Slave Address */
#define SLAVE_ADDRESS 0x40

/* PIN DECLARATION */
int Pin_AmbientLight_LDR = A0;
int Pin_PassiveIR = 2;
int Pin_Temperature = A1;

/* Global Variable */
volatile short Value_AmbientLight_LDR, Value_Temperature;
volatile bool Value_PassiveIR;

/* Protocol Variable */
byte Mode, Pin, Value;
byte Response[14];


void setup()
{
	// Initialize pins
    pinMode(Pin_AmbientLight_LDR, INPUT);
    pinMode(Pin_PassiveIR, INPUT);
    pinMode(Pin_Temperature, INPUT);
    pinMode(0, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(13, OUTPUT);
    pinMode(A2, OUTPUT);
    pinMode(A3, OUTPUT);

#ifdef _DEBUG_
    Serial.begin(9600);
#endif
	
	// Initialize I2C Slave on address 'SLAVE_ADDRESS'
    Wire.begin(SLAVE_ADDRESS);
    Wire.onRequest(SendData);
    Wire.onReceive(ReceiveData);
}

void loop()
{
  // Read LDR
  //         Arduino supports 10-bit Analog Read.
  //             Thus we need to convert it into 8-bit.
  Value_AmbientLight_LDR = analogRead(Pin_AmbientLight_LDR);
  Value_AmbientLight_LDR = map(Value_AmbientLight_LDR, 0, 1023, 0, 255);
  
  // Read PassiveIR value
  Value_PassiveIR = (digitalRead(Pin_PassiveIR) == HIGH) ? true : false;

  // Read Temperature Sensor and Convert Voltage into Celsius
  Value_Temperature = (short)((float)(analogRead(Pin_Temperature) * 0.48828125));
  
  // Wait for 100 ms
  delay(100);
}

// Callback for I2C Received Data
void ReceiveData(int byteCount)
{
	// Read first byte which is Protocol Mode
  Mode = Wire.read();

	// Read second byte which is Pin. Only Valid for Mode 2
  Pin = Wire.read();

	// Read third byte which is Pin-Value. Only Valid for Mode 2
  Value = Wire.read();

	// Signal specified pin if Mode 2 is received
  if (Mode == 2)
  {
      digitalWrite(Pin, Value);
  }

#ifdef _DEBUG_
    Serial.print(Mode);
    Serial.print(" ");
    Serial.print(Pin);
    Serial.print(" ");
    Serial.println(Value);
#endif
}

void SendData()
{
    switch (Mode)
    {
        case 0: // Mode: Read Sensor
            Response[0] = (byte)Value_AmbientLight_LDR;

            // Value_PassiveIR is boolean so that we need to convert it into byte
            Response[1] = (byte)((Value_PassiveIR == true) ? 1 : 0);
            
            // Response[2] byte is Sign byte for Temperature
            //         0 - -ve Temperature
            //         1 - +ve Temperature
            Response[2] = (byte)((Value_Temperature < 0) ? 0 : 1);
      
            Serial.println(Value_Temperature);
            
            // -ve Temperature can't be sent in byte. Convert it into +ve equivalent
            Response[3] = (byte)((Value_Temperature < 0) ? (Value_Temperature*(-1)) : Value_Temperature);
            break;
        case 1: // Mode: Read Devices State
            Response[0] = (digitalRead(0) == HIGH) ? 1 : 0;
            Response[1] = (digitalRead(1) == HIGH) ? 1 : 0;
            Response[2] = (digitalRead(3) == HIGH) ? 1 : 0;
            Response[3] = (digitalRead(4) == HIGH) ? 1 : 0;
            Response[4] = (digitalRead(5) == HIGH) ? 1 : 0;
            Response[5] = (digitalRead(6) == HIGH) ? 1 : 0;
            Response[6] = (digitalRead(7) == HIGH) ? 1 : 0;
            Response[7] = (digitalRead(8) == HIGH) ? 1 : 0;
            Response[8] = (digitalRead(9) == HIGH) ? 1 : 0;
            Response[9] = (digitalRead(10) == HIGH) ? 1 : 0;
            Response[10] = (digitalRead(11) == HIGH) ? 1 : 0;
            Response[11] = (digitalRead(12) == HIGH) ? 1 : 0;
            Response[12] = (digitalRead(A2) == HIGH) ? 1 : 0;
            Response[13] = (digitalRead(A3) == HIGH) ? 1 : 0;
            break;
        case 2: // Mode: Set Device State
            Response[0] = (digitalRead(Pin) == HIGH) ? 1 : 0;
            break;
        default:
            break;
    }

	// Wire back response
  Wire.write(Response, 14);
}
Raspberry Pi 2 (Windows Headed App) Software

Issues

Voltage Level-Shifter Missing
Issue #1
almost 2 years ago - 1 comment

The schematic showing connection between RPi2 and Arduino is wrong configures. RPi2 works on 3.3V while UNO works on 5V. Thus voltage level-shifter is needed.
One of the hackster found that Room Page sometimes shows wrong device status.
See all issues

Comments

Author

Asv2
Anurag S. Vasanwala
  • 4 projects
  • 310 followers

Additional contributors

Published on

September 28, 2015

Members who respect this project

RajaduraiDefault11377302 10200611221719246 6763793697954554754 nWq avatar 1 150x150LogofactoryDefaultDefaultImg 4080

and 594 others

Project replicated by

RajaduraiMail illustrationAdambenzDefaultSeipekmDefaultDefaultDefault
See similar projects
you might like

Similar projects you might like

Mini CNC: A Handmade Masterpiece

Project showcase by Mr-M

  • 2,156 views
  • 2 comments
  • 14 respects

Arduino UNO High Precision Counting Scale

Project showcase by Fedeasche

  • 4,027 views
  • 5 comments
  • 19 respects

USBcycle: Ride Through Your Virtual World!

Project showcase by Tazling

  • 2,461 views
  • 0 comments
  • 7 respects

Arduino Controlled Piano Robot: PiBot

Project tutorial by Jeremy Yoo

  • 2,144 views
  • 0 comments
  • 7 respects

Automation of Railway Models Part 3 - Bidirectional Line

Project showcase by Steve_Massikker

  • 998 views
  • 2 comments
  • 10 respects
Add projectSign up / Login