Pin Sleep Xbee with Arduino Host

Making it work.

I got everything to function with a rather messy board setup as shown below.

The output from the Arduino shows the delta T between messages received from the end-devices.  It is pretty close to the calculated ones. I will change the duration to be 15 minutes later on but for debugging purposes 10s intervals for pin sleep is tolerable.

 Code

The following are the libraries were referenced.

Arduino library for communicating with XBees in API mode – I used both Java and C++ versions for this.

Standard Template library (STL) for AVR – I wanted some maps and other stuff in the dev environment.

Streaming C++ style Output – print and println gets to be a pain after a while

Ardunio Modbus Slave - I used this for my energy monitoring project as well and hacked in a modbus function 6. Since then, a new library that includes function 6 has been deployed, but I still used the older version as I wrapped the C++ class – SerialModbusSlave and did not feel like manually merging code.

 HardwareSerial

I leveraged the serial ports available in the Mega2560 and created global variables to reference instances of the serial port as follows:

Which allowed me to do things like the following:

I can change ports around in one spot in the code rather than find an replace things.

I opted to over design things a bit as I wanted to avoid changing the code later on as tacit information tends to be forgotten over time. What I wanted to do is be able to provision new end devices without changing the arduino code and follow a simple 4 step process:

  1. update to appropriate firmware in XBee, set Pan ID, and API mode 2
  2. utilize the home grown Java app to set up the details such as IO types and lines  ( I am thinking of adding a clone function to make this even simpler)
  3. wire up xbee related circuitry
  4. provision the end device in the Arduino via Mango HMI over Modbus

The following illustrates the concept in a non-formal way of describing software. When a ioresponse is received from an end device I look up the corresponding meshdevice entry in map using the string representation of the address64. I was thinking of using int64_t  type rather than a string as the string takes more space but that is not at a premium at this point.

The address64 string for managed end devices are stored in eeprom and loaded on setup(). Provisioning of end devices are sent over modbus from the HMI host and written to eeprom as well. Yes overkill, but t I want to evolve the system and focus on some abstraction to allow the evolution the meshdevice representation. All the smarts to evolve will be confined in one class. The tacit information like how to provision and communicate with the HMI, etc. will hopefilly remain static.

Map of Meshdevices

A map of using the STL for AVR to reference the MeshDevice is as follows:

And updating meshdevices is coded as follows and will change later on as the error handling is uber weak.

Modbus Register Buffer

Lastly the mapping to modbus style registers are set up as clusters for each device and terminated with a set of register to accept commands and address64 strings from the host. The code for it is rather simple and I will shoehorn this later on. Up to 13 discrete (digital) and 5 analog I/O are reserved for each device. What is used depends on how the XBee device is configured which is explained in the XBee datasheet 90000976_D Datasheet

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The prototype basically implemented the following data flow model. The issue for me is battery powered end device is not green enough of a solution for me.  I’m thinking of exploring energy harvesting to help things along. The plan was to also send battery voltage level on the end device to the SCADA host to generate low battery alarms. Still, it would be nicer to tap into ambient environment (vibration, etc) to generate energy to help power the end device. This will be explored later.

Pin Sleep Xbee and Documentation Rant

Well everything is wired up and works as planned. Sort of. The journey there was not simple. The datasheets on the xbee around sleep modes covers everything one needs to set that up. The problem is that it is not a first pass approach for a newbie. I had to scratch my head a few times. Specifically the following:

Pin Sleep for periods longer than 5 seconds caused the end device to send information every 30 seconds or so. In the back of my mind, I knew that the coordinator and router handled all the registration process for end devices and that if one of them went MIA then it would be removed from the child table entry. It did not dawn on me that I had to set the SP/SN on the coordinator and router to a value that is longer than the sleepiest end device. I thought those parameters were to be used for just sleep mode configuration. Alas, I was wrong and perusing the data sheet it states for the SN value.

My initial thoughts were that I don’t have any messages sent from the host as they are initiated by the end device upon waking so why bother to change the defaults on the coordinator and router? Then I started questioning the datasheet version I was using. Although the datasheet supported the firmware version of the xbee, I did not pay attention to the differences between OEM (doc # 9000976a) vs non-oem (doc #9000976d). The d version has a lot more updates and included a section on child poll timeout. That was the aha moment for me to get things to work.

To quote the datasheet “D” and not in “A”.

Rant

What is the difference between A and D from the front page? A Hardware line not in previous versions and the absence of OEM. Nice change log.

Now as a hobbyist, I have to ramp up on a lot of fronts and time wasting, although annoying, is par for the course. When one googles xbee and sleep modes, etc. there is a lot of chatter. I’m sensing the XBee evolution and corresponding documentation suffers from a quality issue around information management. What is the cost of ignoring quality in productivity losses in companies? A lot.

Perhaps the problem was between the chair and keyboard in this case. If I compare the effort in  ramping up on the arduino vs xbee, the arduino is a no brainer. I can focus on algorithms and more cerebrally challenging problems. I can’t say that for the XBee.

I’ll get into the mechanics next.

Sleep Mode – Timer Setup

Upgraded to wordpress 3.2. Quite painless.

Setting up the Timer

I received my components from digikey to finish the mesh based data collection prototyping. One of the components is the LTC6991 timer chip. I never soldered surface mount devices before so I did my share of reading up on it. Mine turned out functional but not the best looking. Hats off to those who make it look easy. The IC is TSOT-23 and I purchased a breadboard friendly board to solder it to.

 

 

 Note US penny is same diameter as Canadian penny.

This chip is awesome and worked flawlessly. The datasheet has all the information and includes a sample-circuit for a self-resetting timer. The vendor also has an excel based calculator to facilitate resistor value calculations. It does not have provisions for the  resistor/capacitor portion self-resetting portion of the circuit. One can refer to the datasheet to get the formulas to compute those. For my experiment, the circuit used from the datasheet is reproduced below.

Solve the above equation for R_{pw} to get

R_{pw} = \frac{-t_{pulse}}{C_{pw}\cdot ln(1.429/3.3)}  (1)

where
C_{pw} = 4.3 nF
t_{pulse} = 55 to 56 ms  I may have to lengthen the pulse duration later.

 

R_{pw} came to 15.4 M\Omega  and I had a couple of 7.68 M\Omega 1% resistors available. Close enough.

The rest of the components values where calculated from the the vendor tool.

R_{set}= 118k\Omega \approx 120k\Omega
R1 = 392k\Omega
R2 = 1M\Omega

I wanted a period of 10 seconds and active low. That is a very high duty cycle that you would not get with a 555 timer. The final solution will have around 5 minutes between pulses but for testing purposes, 10 seconds is easier.

The output from the scope below shows (click on it for zoom). The period is 10.1s.

The pulse came in at 57ms as shown below.


Now time to move on to setup the arduino and Xbee integration.

Sleep Mode

I opted for hardware driven sleep mode (SM=1) in the XBee. I felt that that cyclic sleep mode (SM=4) to be a pain to setup. I felt that that keeping the XBee asleep for extended durations, the device would be MIA from host. With a hardware based sleep, I could use a swith to to force  it awake, configure remotely with the software tool I wrote, flick the switch back to the timer based sleep. Simple in my mind.

The tested scenario is illustrated below and it worked as planned. The XBee would be taken out of sleep for 30 ms and back to sleep for 100 seconds. As stated earlier, the power consumption does not lend itself to using batteries. xbee visio

I found this link for an alternative to the 555 and will look into it.  I would also not require a level shifter and can operate from a single 3.3 battery. This would surely extend the battery life as it would remove the dependency on the 78L33 and 555.  Now I just need to deal with the LM35 and other sensors and I think I have a way to deal with that and that is to keep them “offline” when sleeping. More experimentation.

Estimated Battery Lifetime

The resulting solution must run on batteries (coin type ideally) and I wanted to get a sense of the operating time between battery changes.  The spreadsheet utilized the cells in red as variables. Assuming a wake up during of 30ms and sending a sample every 100 seconds, I can run for an acceptable amount of time.  The problem occurs when I include a 78L33 level converter, 555 timer, and a sample sensor like the LM35. I will need to look into this as this might be a show stopper on the battery only constraint.

I have set up my test circuits to using a 555 timer and create a 99% duty cycle for a duration of 100 seconds or so. It does wake the xbee up and transmits to the host software. Now I need to re-evaluate things from a power consumption side.

I will measure the actual current when I build the prototype.

Device Current
Xbee Sleep 0.01 mA
Xbee TX 45 mA
Xbee RX 50 mA
Battery 200 mAh
555 timer 0.1 mA
LM35 0.06 mA
78L33 5.5 mA
Level Converter (5 to 3.3 V)
Sleep Period 100 seconds
Tx 1 per wakeup
Rx 1 per wakeup
Wakeup Duration 30 ms
Aprrox Wakeups per 24 hr 864 count
Approx wakeup duration per 24 hr 25920 ms
XBee Current per wakeup 95 mA
Xbee mA per 24 hours consumed during wakeup 0.684 mA
Xbee mA per 24 hours consumed during sleep 0.009997 mA
mA per 24 consumed 555 2.4 mA
mA per 24 consumed LM35 1.44 mA
mA per 24 consumed 78L33 132 mA
# of days for one battery w/o 78L33 44.0 days
# of days for one battery 78L33 1.0 days
# of days for one battery w/o 78L33,555, LM35 288.0 days

XBee API Mode

So now that I have the latest firmware installed on a coordinator, router, and 2 end devices all set up for PAN ID=47, it is time to write some software to experiment with the other settings. I am not a fan of the X-CTU software and decided to write a simple test application to configure my devices. The vision is to use X-CTU software to upgrade the firmware, set the API mode, and Pan ID. After that, the rest of the provisioning would occur from the software I wrote to configure the devices. I want to commission new XBees for the “field” with just a few clicks of a mouse. I tend to forget things after a while so tacit information should be captured in the software.

I used the Java API for Digi XBee/XBee and jformdesigner within Eclipse to write a simple application as shown below. The software I wrote allows me to discover devices and drill down a given device to change parameters.

xbee discover

I also needed a way for me to experiment with I/O settings and sampling modes as well. This allows me to configure a device and poll the data values. The XBee sheet I use is found here.

xbee io

In the end, the goal is to have the end device send their values after a sleep time so I added a listen that posts IO from end devices along with deltaTs between samples.

xbee listen

Time to experiment.

New Project – Xbee Mesh Network and Data Collection

I needed a project to dabble and distract me in a constructive manner.  The goal for this project is to build a low power data collection network to sample  slow changing analog data such as temperature, ambient lighting, among other things. The constraint given was to use XBee Series 2,  run in API mode, and operate on batteries.

I purchased 5 XBee Series 2s to experiment with. I used X-CTU software to configure the Xbee chips as per the last project I did. The difference this time is I did not want to use AT mode but API mode to give me more control over XBee interactions from the Arduino host software. The  project context is as shown below.

Arduino to-be

The XBee USB Explorer was used and I soldered break away pins and a push button switch between ground and reset.   When I first load an XBee, I select the proper port with default settings. Query the device and you should get a dialog box pop up as shown below.

xctu read new

My XBees don’t come with the latest firmware and perusing the web about which is the latest for the Series 2 indicated that that the ZB supersedes the ZNet stuff.   This is where the push button approach comes in and described here. I picked the XB24ZB firmware with the correct device type. I included 1 Coord, 1 Router, and 2 End Devices. I used a PAN ID of 47 to setup the devices and ensured that I included that in my firmware configuration.

x-ctu default

I  get the following error and that is where the push button wiring that connects reset to ground comes in. I just push the switch for a couple of seconds, release, then upgrade continues. I has something to do with the new firmware and default sleep mode and described here.

x-ctu programmingOnce the new firmware is installed, I head back to the PC Setting tab and select API mode as shown below and set the include escape character as well.

x-ctu api

Now I see the the latest firmware upgrade.