Zigbee Wireless Relay Control and Power Monitoring System


We designed a system for wirelessly controlling relays and monitoring current.  This is used for a home load simulation.  By wirelessly turning relays on and off by sending commands from a PC to a microcontroller we can change the total load (current) to our simulated home.  For wireless communication, we used XBee Series 2 Zigbee RF modules.  One of these modules was connected to a microcontroller and the home load simulation, while another was connected to the PC, which was used for collecting and displaying data as well as for relay monitoring and control.

Rationale and sources of your project idea

This project was proposed by a research/project team here at Cornell working on a so-called “Smart Home Energy Monitoring System.”  Our points of reference within this group are Professor John Belina ([email protected]) and Kamil Bojanczyk ([email protected]).

What this group is working on is an energy-monitoring system for a home using alternative energy sources.  A very high-level block diagram of this system is shown below:


In the above diagram, the “Magic Box” essentially exists to route energy between the house, the various energy sources (for example, a solar cell or the electric grid), and an energy storage unit (such as a rechargeable battery).  In this project, we will “black box” this Magic-Box system, and instead focus on another portion of this energy monitoring system, which involves sending data regarding energy usage and various energy loads (by wirelessly controlled relays) to a PC in order to display and monitor energy usage within the home.

  • Our project focuses on the House to In-Home Display (IHD) part of this system.  What our project does is the following:
  • Simulates a home by using resistors to model various appliances or groups of appliances
  • Allows a user to wirelessly turn on and off various sets of appliances by controlling relays
  • Monitors total power consumption and current in this home
  • Wirelessly transmits the above data to a PC, displaying the data on a graph that shows real-time power consumption in the home (or simulated home)

Our simulated “home” consists of 7 appliances, each modeled by a resistance (a load).  These 7 loads are all in parallel, and are fed voltage from a 5 V DC source (the microcontroller).  In a real house, the source voltage would be 120 V AC (in the United States at least).  We considered attempting to implement this, but considering the practical dangers of “playing around” with 120 V AC circuits as well as the fact that a relay control system shouldn’t depend on the voltages being fed through the relays led us to decide to stick with 5 V DC circuits for testing and simulation.

Zigbee Wireless Relay Control and Power Monitoring System

Background Theory

What we have built is a simple transmission system based on the Zigbee routing and networking protocol.  This protocol and its details are discussed in greater detail in the Standards section (below); in this section, we focus on underlying network theory and the role this theory played in our project.

Data networks (and transmission systems) are typically divided into various layers based on functionality.  This is sometimes called a “protocol stack” (in our case, we are using a “Zigbee stack”).  Essentially, the lower the layer, the closer we are to worrying about actual physical electrons flying around.  Conversely, the higher the layer, the less we are worrying about physical constraints and the more abstract the data structures are that we are dealing with and manipulating.

The most famous of these layering models is the Open System Interconnection (OSI) Reference Model, which is shown below:


Figure 2. The OSI Reference Model (Source: http://en.wikipedia.org/wiki/OSI_model)


The functionality of each layer (or group of layers) is described in a bit more detail below.

Physical Layer

The physical layer’s job is to move individual digital bits from one place to another.  The protocols in this layer depend on the actual physical medium.  For example, in a wireless system, the actual physical medium is simply the atmosphere.

Link Layer

A network’s link layer routes a series of bits (sometimes called a datagram) from one node in a network to another.  This can happen through a series of intermediate switches (or routers).  Protocols at this layer provide more robust and full-featured services than protocols at the physical layer.  WiFi is one example of a link-layer protocol.

Network and Transport Layers

Again, since these layers are higher in the model, protocols at this layer typically are more full-featured than protocols at the link or physical layers.  Protocols at these layers use the link layer’s routing capabilities to move the aforementioned datagrams between nodes in a network.  The Internet Protocol (IP) is probably the most famous network layer protocol, while the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP) are two examples of well-known and widely-used transport-layer protocols.  Certain higher-level functionality is more prevalent in these two layers than in lower levels.  For example, flow control – controlling the transmission rate between nodes in order to lower congestion on the network (realizing that even just a two-node transmission system can be considered a “network”) – and reliable transmission (ensuring that a packet is actually received) are two features commonly implemented in the network and transport layers.

Session, Presentation, and Application Layers

These layers are essentially the end-result of a networking protocol stack.  For example, a web browser resides in the application layer.  These layers make use of all of the lower layers to send data between nodes on a network, and then use their own protocols for manipulating that data.  A web browser renders HTML but uses lower-level protocols to send HTML between nodes in a network.

Our Project

The part of our project that we implemented basically deals with the network layer and above.  The XBee chips (which are discussed in much greater detail later in the report) and firmware allow us to “black box” the Data Link and Physical layers, and the open source Xbee-API and Xbee-Arduino software packages greatly simplified our work in the network layer.  Thus, it was not strictly necessary for us to have a deep understanding of the underlying physical, link, and network layer protocols used, but a brief discussion of this is warranted nonetheless.

The physical layer protocol/standard used in Zigbee systems is IEEE 802.15.4 (http://www.ieee802.org/15/pub/TG4.html).  This is a wireless standard that operates, in North America, in the range of 2400-2483.5 MHz or 902-928 MHz.  Zigbee, and most importantly our chips, operate in the higher 2.4 GHz range, so that is the range we will briefly discuss here.  The data transmission rate is up to 250 kilobits per second.

Logical Structure

A block diagram of our system is shown below.  As you can see there are seven relays which are controlled by the MCU.  The MCU gets its command from the Xbee Chip which is wirelessly transmitted from another Xbee chip that is connected to the PC.  The user can specify from the PC which relays they want to turn on and off.  Also all seven of the relays load goes through a .2 ohm power resistor which goes through an optoisolator to keep it safe from the MCU and finally to the Xbee chip.  This gets transmitted back to the PC to be displayed on a graph in a GUI.

Figure 3.  High-level design overview of our project.

Hardware/Software Tradeoffs

We didn’t really have much hardware/software tradeoffs because we didn’t have a budget constraint since we were working for a project team.  However we did decide to use an Arduino board instead of the STK500 which we were used to.  This required less software for us to write.  It seemed much less tedious to write certain tasks in Arduino such as turning on an LED.  We were interested in expanding our knowledge of other hardware/software that were similar but not exactly the same as what we had learned throughout the semester.  Other than that we did not have to do any other sort of tradeoff between hardware and software.


The most relevant standard for our project is the Zigbee wireless networking standard, which is IEEE 802.15.4.  The reason we chose Zigbee over WiFi (802.11) or another RF standard was twofold.  First, it consumes a very low amount of power, which could be very useful on the MCU-end of our transmission system (see Tentative Design section).  And second, it is (apparently) of much lower complexity than WiFi, making it easier to implement.  It has a lower data rate than WiFi (only up to 250 Kbits/second) but is still easily capable of transmitting the relatively low amounts of data that are necessary in this domain.  The main feature of this standard is the necessity of achieving technological simplicity, low operation cost, and low manufacturing cost without sacrificing flexibility or generality.

Software Details


The software portion of this project consists of two main applications: one for an Arduino-based microcontroller unit, and another for the PC.  Arduino, as discussed in the hardware section, is an “open-source electronics prototyping platform” based on Atmel microcontrollers (in our case, an ATMega328) and its own Arduino programming language.  This language is very similar to C/C++, and the programming paradigm is almost exactly the same as it is when writing in C for AVR-GCC and Atmel MCU’s.

On the PC side, we used Java to interact with an XBee chip connected through either a serial or a USB port (in other words, the XBee is recognized as a serial device on the PC).

Evolution of Software Design

The reason for choosing a Java-Arduino based system is simple: we found a pair of very well-documented open source (GPLv3) projects implementing an API for data transmission using XBee chips and the Zigbee protocol.  These projects are:

–          XBee-API: This is for the PC side.  It is a Java software library with the goal of providing “a flexible and simple to use API to interact with XBee radios.

–          XBee-Arduino: This is very similar to the XBee-API package (and was written by the same person), but is for Arduino-based micrcontroller platforms rather than PCs.

We had originally intended to implement much simpler (read: dumber) pieces of software ourselves to provide a minimal subset of the functionality found in the above two packages.  However, as we learned more and more about the XBee chips and their operation, we realized our project would be much better if, rather than reinventing the wheel, we focused on learning how to use and extend solutions that were already available.  The stages of our high-level software design (and intentions) are briefly outlined below.

  1. We originally looked into using either Java or C# for the PC side of our application.  These are the two programming languages we were most familiar with, and are also two of the most widely-used and full-featured languages available today.  We spent about a week researching how to communicate through serial ports in these two languages, and found out that C# offered much better support for this.  However, the downside to C# is that its not nearly as multi-platform friendly as Java is.  Java is implemented and updated as a runtime environment on all major operating systems (Windows, Mac OS, Linux) whereas C#  is a “standard” language (in the sense that anyone can read the language specification and write a compiler for it) but is generally used for Windows development using Visual Studio.  An open-source alternative to Visual Studio, called Mono, is available, however, so we also looked into using this during the first week.
  2. After realizing in our first week of research that serial communication with Java was someone nontrivial and with C# might be difficult on non-Windows platforms, we turned to Python.  We found an open-source library called pySerial that makes serial communication very easy with Python.  The downside to this, however, was that neither one of us was (or is) very familiar with Python, and learning an entire new language in just a few weeks (in addition to implementing our project) could be difficult.  Still, we decided to take a run at using pySerial to communicate with the XBees on the PC side, and other Python libraries for the a relay control GUI and a real-time power consumption plot in our simulated house.
  3. The last and final stage of the evolution of our software design/intentions was our discovery of XBee-API and XBee-Arduino with roughly 2.5  weeks to go on the project.  At this point, we had played around with Python serial communication and the use of XBees in transparent mode (see the XBee Software and Operation section below for details on this; transparent mode essentially allows you to use two XBees as a “dumb” serial line replacement).  Our project was definitely doable using this, but we realized that using the XBee-API and XBee-Arduino software would allow us to make our software much better at the cost of learning a pair of new open source APIs as well as a new (or semi-new, since Arduino uses Atmel microcontrollers) hardware platform.
  4. The last major change we made was in deciding what to use when implementing the GUI on the PC side.  We needed a GUI for two things: first and foremost, for controlling relays and monitoring the status of those relays (essentially seeing whether or not they are open or closed), and second, for monitoring total power consumption (or current) in the house.  We originally wanted to make a fairly complex application for this, and base it on the Eclipse Rich Client Platform.  The Eclipse RCP essentially allows users to build “rich” client applications using various Eclipse plug-ins and extensions.  This, however, proved to be far too time consuming and complicated for our simple application needs.  Thus, we eventually settled on simply using both Java’s Swing GUI toolkit and Eclipse’s Standard Widget Toolkit (SWT) to build a simple GUI and graph.

Software Design, Microcontroller Side

On the MCU side, we essentially just have a main loop (note, however, that in Arduino, rather than writing an infinite loop in main, you simply write a function called loop() which does the same thing) that checks to see if a new XBee packet has arrived using the XBee-Arduino API.

If a new packet has arrived, we need to do the following:

  1. First, make sure that the packet is a Zigbee packet carrying a payload.  If this is the case, proceed.
  2. Send an acknowledgement to the sender, letting the code on the PC know that we’ve received the packet.
  3. Wait to see if the sender gets the acknowledgement.  If debugging, print whether or not the sender got our acknowledgement.
  4. Now, using the String library on Arduino, construct a new string representing the payload that was sent from the PC.
  5. Parse this payload, looking for the commands RON and ROFF.  Our command format is RON01 for turning pin 1 on, ROFF07 for turning pin 7 off, etc.  Each relay is hooked up to a pin, so you can turn on and off relays in this manner.  You can send multiple commands per packet, our payload parser simply looks for each of those commands somewhere in the string, and the payload must begin with the String “CMD “.
  6. If RON or ROFF commands exist and are valid, simply turn on or off the pins that are signaled.  If both RON and ROFF commands for the same pin are in the same payload, turn the pin (relay) off.

Software Design, PC Side

All of the PC-side code was written in Java using Eclipse.  The code can be found on Google Code here.  The Javadoc documentation for our code is found here.  This provides the lowest-level overview of our code and software design as it is generated directly from comments written in the source code.  However, understanding a piece of software simply by looking at the Javadoc documentation can be difficult, so here we’ve provided a higher-level overview of our entire software design.

The design of our underlying software (not including the GUI) can be summed up in the following equation:

XbeeManager + RelayManager => XbeeRelayManager => XbeeSWTGui

 Zigbee Wireless Relay Control and Power Monitoring System schematic

Basically, we created an underlying API for controlling and monitoring relays in some generic way.  This API consisted of Relay objects, which are used to model relays (see the Javadoc for specific functionality and properties), and XbeeManager objects, which are used to manage local Xbees and send commands to remote Xbees on the PC using the XBee-API software.  We then combined the functionality of these two classes to create an XbeeRelayManager class, which extends RelayManager and makes use of XbeeManager to send commands.

XbeeManager sends commands as follows: given a command to send to the remote Xbee and the address of that Xbee, as well as an Xbee object from the Xbee-API software (representing the local XBee chip itself), perform the following steps:

  1. Construct a payload for a packet to send to the remote XBee.
  2. Construct a new packet to send to that XBee from the payload, addressed to the XBee specified.
  3. Now, attempt to send the packet, setting the timeout value to 10 seconds (this could be changed).
  4. Wait now, up to 10 seconds, for an acknowledgement from the remote XBee.  If no ACK is received within that timeframe, an XBeeTimeoutException occurs, and the send fails.
  5. If, on the other hand, an acknowledgement packet is received within 10 seconds, we know that the command was successfully sent to the remote XBee.  In this case, we can simply return true indicating our success.
  6. If we weren’t successful, return false or throw an exception (if something worse than a timeout occurred, such as the address of the remote Xbee not being found).

XbeeRelayManager simply uses the command-sending functionality of XbeeManager to turn on and off relays as well as update the status of those relays.  See the javadoc for these classes for a more detailed overview of their functionality.

Now for the main program: XbeeSWTGui.  To run the PC portion of our code, simply run the main section of this class.  What follows is an overview of what happens in main.  First, here are two screenshots showing the two windows that are launched by main:

Figure 4.  The power consumption graph, which is updated in real time.

Figure 5.  The relay control window.  You can select “appliances” (relays) and turn them on and off.

  1. First, begin by reading in the configuration file for this program.  I currently have the location of this file set to /home/casey/defaultCurrent.config; you will need to edit the code to change this location.  A sample config file is shown below:

The comments in the config file explain pretty much exactly what is going on here.

# The maximum age, in seconds, of an item that should be displayed

# on the graph of power consumption



# Actual measured Vcc you are putting across your entire load

# circuit (default is 5.0 if you don’t put anything here)



# Value of the resistor we are measuring voltage across



# Number of relays in the circuit.  You need to then specify

# 4 things for each relay, numbering them 1 to this number.



# You need to specify these for each relay

# They are, in order:

#   1 The label of the relay (will appear in the

#     GUI’s table displaying the relays

#   2 The number of the relay (will appear in the

#     GUI table displaying the relays

#   3 The pin number on the Arduino board that controls

#     this relay.

#   4 The XBee pin that is monitoring this relay.




































# The address of the local (connected to PC) XBee



# The Serial High:Serial Low address of the remote

# XBee.  In this example, SH:SL = 0x0013a200403db15b.










  1. Next, we need to construct a new instance of PowerPlotter, which is used for plotting the power consumption in the house.  See the next section for more details on PowerPlotter’s operation.
  2. Now, we need to construct our relay control window.
  3. Construct a new XBee instance.  As stated previously, this class is a part of the open source Xbee-API package, and represents an Xbee connected locally to the PC.
  4. We now add everything to our relay control window.  This includes a File menu (which currently does nothing) and a Relay menu, which is used for turning relays on and off and for updating the status of those relays.
  5. For each item in the Relay menu – turning relays on, turning relays off, and updating the displayed status of all of the relays – we need to add a selection listener (which is called when the user clicks on one of those options).

The selection listener for turning relays on and the listener for turning relays off are very similar, and they work as follows:

  1. Iterate through each item in the table which contains a list of relays and their properties (pin number on the Arduino board, pin number on the Xbee, and their current status) and see which relays are checked.
  2. For all of the relays that are checked, turn them on (or off, depending on which button was pressed and thus which listener was called).

The selection listener for updating the status of the relays is a bit different.  When this menu item is clicked, we simply iterate through all of our relays and their corresponding entries in the table and update the column in the table corresponding to the status of each relay based on that relay’s current status (each Relay object holds a property telling us whether that relay is on, off, or uninitialized, where uninitialized corresponds to a relay that we have not yet sampled as being on or off.

  1. Now, we simply add all of our relays to the table.  As stated in (1), relays are all specified in the configuration file for this program.
  2. Start up the XBee object by associating it to a serial port on the PC.
  3. The last thing we need to do is add a packet listener to our XBee object, which corresponds to the XBee chip connected to the PC.  This packet listener functionality is a part of the XBee-API open source package.


Our packet listener works as follows: when a packet is received, we want to check if the packet is an IO sample response (see the XBee configuration section below for more details here; in short, we have the remote XBee chip set up to monitor the relays using their on‐board digital IO pins and the current to the simulated house with the one of the XBee’s onboard analog IO pin and 10‐bit A/D converter, and it sends samples back to the PC every 3 seconds). If it is, then we need to update our graph of the power consumption by the house and update the status of all of the relays that have updated data in this sample response.


  1. The rest of the code is for starting up the relay control GUI and is standard and uninteresting.


PowerPlotter is the last class that bears discussion. It works as follows:

  1. When it is constructed, we do everything that is necessary to set up the graph. For plotting, we use the open source JFreeChart library, and our code is based off of some examples provided with that library.
  2. This class has one method, and it is simply used for adding a new item to the graph.

Xbee Configuration: A Brief Primer

The physical aspects of the Xbee chips are introduced in the hardware section (below).  Here, we will discuss the software aspects of the configuration.

There are two different modes of operations that Xbees can run in.  They are:

  1. Transparent mode
  2. API mode

In transparent mode, the Xbees essentially act as a dumb serial line replacement.  In other words, each Xbee simply forwards everything that comes in through its antenna to its Din port, and sends everything that comes in through its Dout port through its antenna and into the air.  This is functionally equivalent to simply having a serial line connected between the two Xbee chips.

In API mode, Xbee operation is not nearly as simple.  API stands for Application Programming Interface, and in this mode you can send commands to and from the Xbees to perform various tasks.  Further, it is in this mode that the Zigbee protocol is used for Xbee Series 2 chips.  In other words, whereas transparent mode acts as a dumb serial line replacement, API mode unleashes the full power of the Xbees and allows us to construct a real wireless network consisting of our two devices.

When in API mode, there are three more modes that each Xbee chip – or any chip on a Zigbee network – can operate in.  These modes are:

  1. Coordinator mode
  2. Router mode
  3. End Device mode

These modes are essentially listed in order of decreasing functionality.  Coordinators are the most powerful nodes in Zigbee networks, and can coordinate activity within one network while also interacting with the outside world.  Other nodes in the network “report to” the coordinator.  Router nodes have the capability of forwarding packets from one node to another (acting as an intermediary in the network, or a router).  End device nodes cannot act as routers but can communicate with routers or the network coordinator.  On series 2 Xbee chips (which we used), it is necessary to change the firmware on the chips to change between API and transparent mode and also between Coordinator, Router, and End Device mode.

In our application, we used the Xbee connected to the PC as a coordinator, and the remote Xbee as an end device.  This allowed us to use the Xbee connected to the PC to send commands to a remote Xbee, and also to set up automatic I/O sampling on the remote Xbee.  Xbees that are within the network of a certain coordinator are said to be “associated” with that coordinator node.

To configure Xbees, you can use Digi’s own X-CTU software, which was created specifically for configuring Xbee and similar chips offered by Digi, or you can simply connect to the Xbee chips via a serial terminal (such as Hyperterminal) and send them a series of commands.  You can also use a network coordinator to send commands to be executed on a remote Xbee within that coordinators network.  The Xbee chips have various registers that store different parameters.  For example, the parameter AP is what determines whether the Xbee is in transparent or API mode.  When AP=0, transparent mode is enabled.  When AP=2, API mode is enabled (AP = 1 also enables API mode, but with slight differences that we won’t discuss here).  Refer to the manual for other parameters, and see below for our configuration, which provides an example.

For changing Xbee firmware, X-CTU must be used (for all intents and purposes, it would be possible to change it without X-CTU, but this wouldn’t be practical for most users with a limited amount of time).

Our Xbee Configuration

The configuration parameters that we changed on our two Xbees are described below.

PC Side: The Coordinator

For this Xbee, we began by flashing the firmware so that we were operating in API mode and as a Coordinator.  We did this using X-CTU, as described above.

Next, we ran the following series of commands in order to configure the coordinator:

# Reset default settings
# Set to API mode
# Set the personal area network (PAN) ID
# Note that the end device needs to have this
# same PAN ID in order to associate itself
# with this coordinator
# Set this node’s string identifier
# Write our configuration so its not lost on reboot
# Restart

MCU Side: The End Device

For this Xbee, we began by flashing the firmware so that we were operating in API mode and as an End Device.  Again, we did this using X-CTU, as described above.

Next, we ran the following series of commands in order to configure the end device.

# Reset default settings
# Set to API mode
# Set PAN ID
# Set node’s string identifier
# Now, configure the Xbee to send IO samples to its coordinator
# every 0xbb8 (roughly 3000) milliseconds
ATIR 0bb8
# Now set D2,D3,D4,D5,D6,D11,D12 to digital inputs
# Each of these is used to monitor one relay
ATD2 3
ATD3 3
ATD4 3
ATD5 3
ATD6 3
ATP1 3 # P1 is D11
ATP2 3 # P2 is D12
# Now set D0 to analog input, using the Xbee’s built-in 10-bit
# A/D converter, which reads 1.2 V as 1023 and 0 V as 0.
ATD0 2
# Write config
# Restart

One more note regarding the Xbee’s on-board Analog-to-Digital converter: there are 4 pins that can be used for analog input right on the Xbee chips, and each of these has a 10-bit A/D converter that saturates at 1.2 V.  Thus, in order to get an accurate reading, you shouldn’t attempt to read values much greater than 1.2 V.  As described in the hardware section, we set our current-measuring resistor to a value such that when all of the loads (relays) were turned on, we’d get voltage readings just below 1.2 volts, and thus around 1020 on the 10-bit A/D conversion.

Why use Xbee IO to monitor relays controlled by the MCU?

We made the decision to use the Xbee’s own IO ports as monitors for the relays and for the current and power to the load for a couple of reasons.  First, it allowed us to take full advantage of how powerful the Xbee chips really are.  We were at first viewing them as simple RF modules, but in reality, they are almost microcontrollers in and of themselves.  They are capable of digital and analog IO, have tons of pins (see the manual for the official guide, but here: http://code.google.com/p/xbee-api/wiki/XBeePins for an unofficial one), and can be set up to automatically sample these pins and send all the values to the network coordinator at regular intervals ranging from just a few milliseconds to 65 seconds.

The second reason for doing this was as for simple redundancy: we were using the MCU to turn on and off the relays, so simple assuming that the data we were getting back from the MCU regarding those pins wouldn’t be as accurate as having two different readings, one from the Xbee (sent at regular intervals) and another from the MCU (sent to acknowledge receipt of commands to turn on and off relays).  We were able to separate the “checking” from the “setting” of the values.

Hardware Details

Our system consisted of an Arduino board with an Atmel Mega328 microcontroller, two Series 2 Xbee chips, and seven relays.

Arduino Board

The reason why we chose to use Arduino was because it is an open source software package that can be used with our Xbee chips.  It has an Atmel Mega328 MCU so we were able to do all the functions (ISR, configuring ports, etc) that we learned throughout the four labs beforehand.  Since we were familiar with a Mega644 MCU and not a Mega328 MCU we became very proficient at reading datasheets and figuring things out on our own.  The Arduino board was also useful in that it had a usb connection to that made it much more convenient to connect to our laptop.

Xbee Chip

We used two Series 2 Xbee chips, more specifically 802.15.2 Series 2 Chip Antenna Xbee chips.  It has an on-chip antenna that has a range of 300 feet indoors.  It is also powered by 3.3 Volts.  We had originally wanted the much simpler Series 1 chips.  Series 1 Xbee chip is based on the IEEE 802.15.4 WPAN specification.  It supports point-to-point, and point-to-multipoint communication.  It also has 6 analog and 8 digital I/O pins, with 6 pins shared between digital and analog.  It is much simpler and does not require a firmware change to switch between Coordinator and End Device, or AT mode.  Series 2 is ZigBee compliant.  ZigBee introduces mesh networking, where networks can be extended beyond typical wireless range limits through the use of routers.  This radio supports 4 analog and 11 digital I/O pins, with 4 pins shared between digital and analog.  Some pros of the Series 2 chips are that it consumes less power and we can extend the range of the network beyond the limit of a single transmission by adding routers.  Some cons are analog inputs can only measure voltages between 0 and 1.2, requiring a voltage divider to step down from the reference voltage of 3.3V.  Another con is that it requires separate firmware for API and transparent (AT) mode.  You can’t switch between API and transparent mode with the same firmware as with Series 1, instead you have to choose between installing the API firmware, or transparent firmware.  Additionally, the firmware is specific for Coordinator, and Router/End Devices.

Since we got the Series 2 chip we needed to configure one chip to be a coordinator and another to be an end device.  We became familiar on doing this by the X-CTU program.  This required some researching and trial and error but we were able to configure each chip.

Since each needs 3.3 volts to power it we got a regulated Xbee Explorer board and a regulated USB explorer board.  This way we could connect one of the Xbee chips to the PC via the USB explorer board and the other to the Arduino board via the explorer regulated board.  The boards needed 5 volts to power it up and were pluggable into our breadboard after soldering on some pin headers.  The connection of the Xbee chip to the Arduino board to send and receive packets are as follows: 5V from Xbee chip to 5V on Arduino Board, Gnd from Xbee chip to Gnd on Arduino Board, Dout on Xbee chip to Rx on Arduino board, and finally Din on Xbee chip to Tx on Xbee chip.


We used 7 mechanical relays and connected them to resistors to serve as our appliances for our simulated home.  The way the relays were connected goes as follows: there are 2 control pins.  The first one goes to the MCU pin and the second one goes to the MCU gnd.  Also there are 2 other pins on the relay and the first of these two goes to the resistor that serves as an appliance and the second goes to VCC (5V).  We also attached an LED connected in series with a 330 ohm resistor to the control pins of the relay that go to the MCU.  The reason for this was so that we know when we turn on specific relays from the PC whether they actually turn on.  At first we used this for debugging purposes but then we decided that it would be better to leave them since they are a good visual aid for people.  The resistor value that we have for each appliance, the pins on the arduino board and Xbee chip, as well as the relay that controls it is as follows:

Relay Resistor Value (ohms) Appliance Arduino Board pins Xbee pins
1 100,000 Base 2 D2
2 68,000 Lights 3 D3
3 36,000 Fridge 4 D4
4 18,000 Water Heater 5 D5
5 14,000 Dishwasher 6 D6
6 3600 Dryer 7 D11
7 3000 Oven 8 D12


We had all the above appliances in parallel and connected them to each other.  So in order to measure the current that is going through when various appliances were turned on we needed to add a resistor in series with it and this was sent to pin A0 of the Xbee chip.  Also as mentioned above the Series 2 Xbee chip only measures a voltage from 0 to 1.2V so our calculations needed to address that.  So we had to find the max current that we would get and that would happen when all appliances were on and the value of the resistance would be 1283 ohms (Vcc= 4.82 V).  So we set the equation as follows:

Solving these equations simultaneously you get:

So we needed something a little below 425 ohms and we used 408 ohms.

Things We Tried that Did Not Work (Hardware)

At first we wanted to implement an optoioslator, HCPL-7520, to be used with our system.  We got this idea from a final project in 2008, Powerbox: smart AC outlet with metering and control by Cliff Jao and Xi Guo. We figured this would be a good bonus to our system and that if someone wanted to run 120V AC through our system they would be able to.  After many, many hours of trying to figure out why it wouldn’t work the way it was supposed to and consulting with Bruce, Professor Belina, and the TA’s  we decided to scrap it for our final project.  The HCPL-7520 was a 8 pin dip IC.  On one side you had VCC, Gnd, Vin+, and Vin-.  This was connected to your main circuit.  On the other side you have, VCC, Gnd, Vref, and Vout.  This was connected to the microcontroller.  By using the VCC and Gnd on both the microcontroller and the prototype board we ensured that they were isolated.  The way in which the HCPL-7520 was supposed to work was that when the Vin was between -.2V to .2V our Vout was supposed to resemble a nice linear line as shown below:


For more detail: Zigbee Wireless Relay Control and Power Monitoring System

This Post / Project can also be found using search terms:

  • yhs-ddc_bd
  • ZigBee High Voltage Relay
Clip to Evernote

Leave a Comment

(Spamcheck Enabled)

Read previous post:
1080p video over Cat-5 up to 300m long
1080p video over Cat-5 up to 300m long

The AD8122 is a triple, high speed, differential receiver and equalizer that compensates for the transmission losses of UTP and...

Scroll to top