Jun 05

Home Automation System – An engineering project (EE5)

Just as I did with our previous projects I’m going to elaborate on the ‘Engineering Experience’ project we’ve done this semester. We opted to build a home automation (Domotica) system from scratch. We, a team of 4 (clicky & clicky) electronics students at Group T University College, spent the last five months or so developing and building a system that, in theory, could be used to control and sense stuff in your house. Here’s some explanation on both hardware/electronics and software.


The essential hardware (excluding sensors such as temperature sensors, light sensors, switches, …):

We made a ‘sandwich’ of the Uno, Ethernet and XBee shields which acts as the core, the central coordinator or access point. From here all data is received from and sent to modules around the house. Thanks to the Ethernet connection, a MySQL database is hooked up and a webinterface is able to check and control the entire system. Unfortunately the Uno only has one serial IO channel, which caused some problems in the end due to both shields being connected to that one line. We fixed most of them by software filtering but looking back it would’ve been easier if we had for example an Arduino Mega, which has 3 serial channels.

Module End Device

Module End Device

Arduino Uno - Ethernet Shield - XBee Shield stack

Uno, Ethernet & XBee Shield 

As you can see on the left, the end device “module” is something we designed ourselves. An XBee is used to send over sampling data to the Access Point and to receive commands (set a digital pin to logical 1 or 0).

You can easily attach sensors to any of the 8 available XBee pins (which can be set either to DIO or ADC).

The programming of the XBee devices is done with a tool developed by Digi called X-CTU. We started out with a serial terminal to program the XBees but quickly switched to a more user-friendly application.



This program can be used to quickly change some parameters in the XBee’s firmware. The firmware can also be easily upgraded, which is a great thing since Digi seems to release a newer version every couple of months that introduces more features for the device.


XBees can either be used in transparent or API mode. For more complex actions one quickly leaves the simple transparent mode behind and uses the somewhat more complex API mode. This mode uses packets (frames) of data to send over information.

XBee API packet

XBee API packet



This was quite the challenge to be able to read the data, making sense of it and being able to use it to interpret voltages and status information. That’s why I developed a simple packet parser program in C# that quickly transforms any received data packet into human readable form. And so XBeeP was born!

We transfer data to and from the database by  letting the Arduino do PHP GET requests. Packet data is assembled and parsed on the webserver which translates it into usable information that can be shown on an interface. For ease of use we developed both a regular website and a mobile version with jQuery mobile.

Mobile Interface

Mobile Interface

Regular interface

Regular interface

User Restrictions

User Restrictions

With these bits of software, the possibilities are nearly endless, you can create cron jobs or do a check every time the Arduino fetches a page to automate things like turning on the lights when it gets dark. We’ve added a scheduler where you can set actions to be performed at a certain time. These can also be set to be repeated daily or weekly.

Some other features the webinterface has:

  • User rights management (see screenshot above)
  • Easy overview of your switches and the option to turn them on or off
  • Temperature/humidity graph
  • Motion Detection notifications


This was always just a proof of concept project but it turned out to be pretty usable. Of course, for a commercial project a lot more security would be added as well as the usage of “confirmation” packets a module would send to the access point to notify it has correctly received a command. Some more checksum calculations should be added as well to make sure there is no corruption of information along the way.

To conclude, if you look at Twine, which is somewhat similar I think this project is a beautiful example of home automation systems that allow a lot more interactivity between the system and its users. A funfact here is that if our project would be an actual commercial product on the market it would be cheaper than a Twine with something like $30 to $50 per module and $100-150 for the central access point.

Update: more photos of the finished product can be found at http://ee5.crombeen.be/

May 04

Basic Arduino-based XBee Packet Reader

A few days ago I was messing around with an Arduino board and a wireless shield mounted on it with a Series 1 XBee. Along with that another XBee was acting as a stand alone actuator. Unfortunately I had some troubles with reading the API packets the standalone XBee was sending back (X-CTU and any terminal really) displays the incoming data in a pretty much unreadable format for humans to directly interpret it. Garbled ASCII or HEX values aren’t particularly easy on the not-so-well trained eye. That’s why I decided to quickly whip up a packet interpreter program in the Arduino IDE.

Here’s my first basic version:

float vref = 3.3;
int resolution = 1024;
float result = 0;
byte join[2] = {0,0};
int numOfBytes = 0;
int sourceAddr = 0;
int numOfSamples = 0;
int data = 0;
byte adcStatus = 0x0;
float adcVal[6] = {0,0,0,0,0,0};
byte dioStatus = 0x0;
byte dioVal = 0x0;
void setup() {
void loop()
  numOfBytes = 0;
  sourceAddr = 0;
  numOfSamples = 0;
  data = 0;
  adcStatus = 0x0;
  for(int i = 0; i < 6; i++)
    adcVal[i] = 0;
  dioStatus = 0x0;
  if(Serial.available() >= 28) // Check for at least one complete frame
     if(Serial.read() == 0x7E) // Start at beginning of frame
       Serial.print("Start Byte: 0x7E");
//-------------- Number of Bytes in Frame ---------//       
       Serial.print("\nNr Of Bytes: ");
       join[0] = Serial.read();
       Serial.print(join[0], HEX); // MSB length
       Serial.print(" ");
       join[1] = Serial.read();
       Serial.print(join[1], HEX); // LSB length
       numOfBytes = join[1] + (join[0] << 8);
       Serial.print(" --> DEC Value: ");
//-------------- Source Address Checking ---------//       
       Serial.print("\nAddress Mode: ");
       Serial.print(Serial.read(), HEX); // 83 = 16bit address
       Serial.print("\nSource Address: ");
       join[0] = Serial.read();
       Serial.print(join[0], HEX); // MSB Address
       Serial.print(" ");
       join[1] = Serial.read();
       Serial.print(join[1], HEX); // LSB Address
       sourceAddr = join[1] + (join[0] << 8);       
//-------------- RSSI Checking ---------//  
       Serial.print("\nRSSI (signal strength in -dBm): ");
       Serial.print(Serial.read(), DEC); 
//-------------- Number of Samples in Frame ---------//   
       Serial.print("\nNr of Samples: ");
       join[0] = Serial.read();
       Serial.print(join[0], HEX); // MSB samples
       Serial.print(" ");
       join[1] = Serial.read();
       Serial.print(join[1], HEX); // LSB samples
       numOfSamples = join[1] + (join[0] << 8);
       Serial.print(" --> DEC Value: ");
//-------------- Channel Indicator  ---------//
       Serial.print("\nChannel Bitfield: ");
       adcStatus = Serial.read();
       Serial.print(adcStatus, BIN); // Neglecting D8
       Serial.print(" ");
       dioStatus = Serial.read();
       Serial.print(dioStatus, BIN);              
//-------------- Fetching Data word DIO ---------//     
       if(dioStatus > 0x0)
         Serial.print("\nData DIO: ");       
         Serial.print(Serial.read(), BIN);       
         Serial.print(" ");
         dioVal = Serial.read(); // Neglecting D8       
         Serial.print(dioVal, BIN);              
         Serial.print(" --> ");
         for(int i = 0; i <= 7; i++)
           if(bitRead(dioVal, i))
           Serial.print("  ");
         Serial.print("\nNo DIO data in frame");         
//-------------- Fetching Data word ADC ---------//
       if(adcStatus > 0x0)
         for(int i = 1; i <= 6; i++)
           if(bitRead(adcStatus, i))
             //Serial.print("\nData ADC #");
             //Serial.print(": ");         
             join[0] = Serial.read();     
             //Serial.print(join[0], BIN); // MSB Data
             //Serial.print(" ");
             join[1] = Serial.read();
             //Serial.print(join[1], BIN); // LSB Data               
             data = join[1] + (join[0] << 8); 
             //Serial.print(" --> DEC Value: ");
             result = (vref/resolution)*data;
             adcVal[i-1] = result;
             //Serial.print(" - Voltage: ");
         Serial.print("\nData ADC: ");         
         for(int i = 0; i < 6; i++)
           if(bitRead(adcStatus, i+1))
             Serial.print(": ");
             Serial.print("  ");
         Serial.print("\nNo ADC data in frame");          

This will output something like the following:

Start Byte: 0x7E
Nr Of Bytes: 0 10 –> DEC Value: 16
Address Mode: 83
Source Address: 50 0
RSSI (signal strength in -dBm): 35
Nr of Samples: 0 1 –> DEC Value: 1
Channel Bitfield: 100110 11101000
Data DIO: 0 10001000 –> D0L D1L D2L D3H D4L D5L D6L D7H
Data ADC: ADC0: 2.31 ADC1: 1.80 ADC4: 1.41


Personally, I like this layout, you can quickly see what the status is of every XBee IO pin. I was thinking of adding a graphical interface but then again the gain is little and it’s not really worth the effort.

If you have any questions, suggestions or feedback, please let me know and I’ll get back to you.

Update: Check out my GUI version, XBeeP.

Update 2: And just because I can, an improved version in PHP (the Arduino version contains some small errors in the logic).

$packet = "835678220005060002C003FF"; // Example input (only payload)
function parsePacket($packet)
   $bytes = str_split($packet, 2);
   foreach($bytes as $val)
    echo $val . " ";
   //$api_type = $bytes[0]; // ----> SHOULD ALWAYS BE 83!   
   $source = dechex(intval($bytes[2], 16) + (intval($bytes[1], 16) << 8));
   //$rssi = $bytes[3];
   //$samples = $bytes[5] + ($bytes[4] << 8);
   $adcStatus = (intval($bytes[6], 16) >> 1);
   $dioStatus = intval($bytes[7], 16);
   $c = 8;
   if($dioStatus > 0)
    $dioMSB = $bytes[$c++];
    $dioVal = intval($bytes[$c++], 16);
   if($adcStatus > 0)
      for($i = 0; $i <= 5; $i++)
        if($adcStatus & (1 << $i))
          $adcVal[$i] = (intval($bytes[$c+1+$i], 16) + (intval($bytes[$c+$i], 16) << 8));
          $adcString .= "ADC" . $i . " " . $adcVal[$i]/1024*3.3;
   echo "Source " .
        $source . " ADC " .
        decbin($adcStatus) . " DIO " .
        decbin($dioStatus) . " dioVal" .
        $dioVal . " adcval" .