In the past few weeks I have been working hard at a few projects for end-of-term at Uni. One of the projects is what I called "SmartHome", for Embedded computing [link] course, is a home monitoring [link] application. In the course the students were given an LPC2148 arm7-MCU (NXP) based education board, implemented by Embedded Artists [link]. My partner Gil and I decided to work with ZigBee extension modules [link] to enable remote communication.

Here are the steps we took to bring this project to life.

The Idea

Our vision is to create a home monitoring and controlling system, that will enable tracking different sensors around the house and also control switches.The system should be centralized by a master controller, and also wireless so it will not need cumbersome wiring throughout the house. We would also like the system to be easily controlled by a PC, so visual information could be displayed to the user, as well as allow manual control of the electronic switches.

Such a system will be able to automatically:

The Hardware

As I mentioned, we were given an LPC2148 education board [link], implemented by Embedded Artists, that boasts a 12Mhz ARM CPU, and many peripheral subsystems. Among the systems are: LCD screen, numerous LEDs, a LED matrix, a fan, analog dials, USB and UART I/O and more. The boards also has a port for connecting a ZigBee module to enable RF communication, but it doesn't contain the actual module. Since we needed remote communication between our stations, we bought 3 XBee modules from Maxstream [link].

The Software

The LPC boards can be programmed very easily using tools provided by Embedded Artists, such as GCC with Newlib for compiling (both Win and Linux), and Flashmagic (for windows) or lpc21isp for loading the compiled program. We used these tools for programing the "embedded" part of the application, for the PC client we used Java with SWT and serial port connectivity (RxTx for Windows and Linux).

Embedded program

The embedded program on the LPC board has two parts: A master and A client. The system has only one master, and up to 3 clients. The master gathers information from the clients, and controls their behavior according to the user requests. For communication between the master and clients we created a communication protocol that has only a few simple messages:

All commands / responses have a unified structure described here:

General struct:
 ___________________________________________ _____
|    OP   | To | From | <----- DATA ------> | EOM


POLL (response)
_ ____________ ______ ______ ________
 | Temperature| ADC0 | ADC1 | Button |

_ _________

This way we had a very easy implementation of the communication module, since we always had to look for only 14 bytes on the wire.

Communication with ZigBee module

To jumpstart our implementation we used the examples provided by Embedded Artists for operating the ZigBee module [link]. The communication with the ZigBee module is on the UART1 port of the MCU. The example code takes care of opening the correct GPIO pins, setting the IRQ masks to enable interrupts and provides a very simple API for transmitting and receiving characters with the XBee over UART (described in uart.h and uart.c files).

We took the XBee example code and expanded it to be able to recieve and send data between two stations. That means setting up each station's module with it's ID, address, channel and target address by AT commands [spec, see page. 28]: ATID, ATCH, ATMY and ATDL. Two other key features are putting the module into command mode (rather than transmit mode) to set the mentioned parameters, this is done by '+++' to enter command mode and ATCN to exit. Once we had a decent framework to communicate between the stations, we started to build the logic.

The master station logic is like so:

  1. Initialize XBee module.
  2. INIT all client stations, and see which station answers - these will be our "up" stations.
  3. Loop:
    1. POLL each "up" station in a loop.
    2. Take care of any OPERATE requests from the PC client.

This way, the client's logic boils down to just looping, testing for any request and taking care of it. Both client and master share most of the code, so only the main process code is essentially different. The example code uses a framework called "Preemtive OS" to allow multitasking / processes (code was bundled in the examples).

Communication with PC

Communication between the master and PC client also required some lightweight "protocol". The communication is again over UART (0 this time, 1 is used by XBee), only now the PC is doing a UART-over-USB with the board. The protocol we ended up with supports these features:

This is an incomplete set of features, but it's representative of the idea we want to present.

PC client program

The PC client we built using Java, so it would (and should) be portable between OSs. The GUI was built with the SWT, using the eclipse Visual Editor plug-in which simplified the process. Communication with the LPC board is done over the serial port of the board, as I mentioned the PC creates a virtual COM port using a USB-to-UART driver (FTDI, bundled with windows) [link].

To test the GUI we created a "simulator", that mimics the operation of a master station, that is shown in the video above.

The high-level design of the program is described in this inheritance UML diagram:

Our PC client uses serial-port connectivity based on the old javax.serial APIs. Though these APIs have been abandoned by Sun, and there is no official Win32 implementation bundled with the JDK (only for *NIXs/Solaris), a project named RxTx is upkeeping an implementation of this API for windows [link].

The Code

We are releasing the code under the BSD license, for everyone to use, enjoy, learn and expand. It is available via the blog's SVN repo: PC Client (requires RxTx serial port impl and SWT)

svn checkout http://morethantechnical.googlecode.com/svn/trunk/SmartHomePCClient
Embedded program (includes all dependencies)
svn checkout http://morethantechnical.googlecode.com/svn/trunk/smarthome_embedded/final project

To compile the master program "make" in the master directory, and you'll get an "xbee_master.hex" file, same goes for the client in the client directory (these directories don't contain code, only a makefile). Then you have to upload the hex into the board, this is done either by "make deploy" (if you have lpc21isp), or FlashMagic on Win. Java is compiled as usual... just remember the dependencies.

We would like to thank Sivan Toledo for the guidance, loaned hardware and inspiration.

And thanks all for listening!

Roy Shilkrot & Gil Ramon