preload
Feb 14

On my desk i have a JeeNode, equipped with a Pressure sensor. This JeeNode is also controlling a XBee Series 2 module which is configured as Zigbee End Device. All this is battery powered. Calculations on power usage of the JeeNode+Sensor+XBee are good enough to expect an acceptible battery life. A Sparkfun XBee RS232 holds another XBee module, configured as Zigbee coordinator. This setup has been operating for more than a week now. It all looks stable enough to go ahead and connect the Zigbee network (ok, it’s only 2 nodes right now :-) ) to my Domotica system and  actually do something with it; something different from logging the incoming pressure data to a text file and reviewing this file periodically to see if everything is still up and running; so i added another (the 16th) interface to my Domotica system: Zigbee! :-)

In fact all the hard work had already been done in an earlier stage where i created an API-mode interface for Zigbee; in essence, the only thing left to do was making this interface ‘talk’ to the rest of the Home Automation system, add some records in the database for this new sensor type and write a routine that would convert the incoming packets to the measured values of temperature and pressure.

Zigbee interface

Wow! It’s great to see my first Zigbee based sensor really working! The pressure data is being stored in the database, so in a few hours i can start creating an additional web page to show a pressure chart… and here it is!

BMP085 Pressure sensor data

BMP085 Pressure sensor data

Next on the list: finding a suitable, small housing, making a light sensor, a motion sensor, humidity sensor, … the list is to long! :-)

Tagged with:
Feb 14

Now that i have 2 JeeNodes up and running for more than a week and everything’s working fine, it’s time to do some calculations on power usage of the sensors. First thing i wanted to know was how much power a combination of a sensorless Jeenode and XBee module was using, so i created a sketch that would give me some ‘inside’ information about what was going on inside the Jeenode. The sketch i made informs me about a couple of things, like:

- the timespan the JeeNode is awake to power up the XBee, send a packet to the XBee and wait for it to finish transmission;

- the timespan the XBee is powered to send that packet of 10 bytes.

Battery powered JeeNode

With these numbers i should be able to roughly calculate the power usage of this sensor. The power that is used by the JeeNode while it’s awake is about 35 mA, while the XBee uses around 40 mA while transmitting. When both the JeeNode and XBee are in deep sleep, the combination of both uses only 60 μA.

The time measurements i did to find out the timespans mentioned above gave me the following figures: the total time the JeeNode is awake to read a sample from the Pressure sensor, wake the XBee, transmit the data and go back to sleep is 40 ms. The time that the XBee is awake is around 25 ms. With a sample interval of 30 seconds, and a 2000 mAh battery, i have calculated a battery life of more than a year; increase the interval to 60 seconds (still good enough for this type of information) and batteries should survive more than 2 years… i think.

Just ask me in a year or so ..

But good enough to go ahead with the expedition! :-)

Tagged with:
Jan 31

The fact that in the setup i made yesterday, the XBee module sometimes had trouble setting up the connection was troubling me, so i tried to figure out what was going on. My guess was that the CTS line was not monitored, so i built a counter into the loop that waits for CTS to get high; and made this counter part of the packet payload so that i could monitor what was going on; this counter  was always 1, meaning CTS was high at the time the first CTS check was done!

Hmm, seeing that, the error was found very quickly: CTS was attached to the wrong digital input, so CTS wasn’t monitored at all… fixed the wiring and now everything’s OK.

Second thing i changed was for the sake of convenience: the new sketch does the temperature and pressure calculations “on board”, so now the payload immediately shows value that are easily interpreted. I also took the time to create a small Delphi program that uses my XBee API to log all the packets that are received in a more readable style:

31-1-2010 20:43:30:Packet payload=[2 215 100159]
31-1-2010 20:43:41:Packet payload=[7 215 100150]
31-1-2010 20:43:52:Packet payload=[0 215 100153]
31-1-2010 20:44:03:Packet payload=[0 215 100156]
31-1-2010 20:44:14:Packet payload=[0 215 100166]
31-1-2010 20:44:25:Packet payload=[5 215 100156]
31-1-2010 20:44:36:Packet payload=[10 215 100159]
31-1-2010 20:44:47:Packet payload=[0 215 100150]
31-1-2010 20:44:59:Packet payload=[0 215 100156]
31-1-2010 20:45:10:Packet payload=[0 214 100153]

The first value is the time in milliseconds that it takes for the CTS to become high, the second value is the temperature in 1/10th of a degree and the last value is the pressure in mbar.  Neat :-)

Tagged with:
Jan 30
JeeNode connected to XBee

JeeNode connected to XBee

Here you see my first setup of a JeeNode with pressure sensor connected to a XBee Series 2 module.  And it’s working! With Hyperterminal i captured the raw data coming in on my XStick:

XBee API mode packets with sensor data

XBee API mode packets with sensor data

The ‘experts’ will immediately recognize the first character (tilde, ~) as being the frame header of a XBee packet. The payload on the first line is ‘26311 39767′. All characters before that are XBee API frame related as well as the last character, which is the checksum. When you have a look at the code you can see what the payload is made of.

This is absolutely very cool; it think in total it has cost me an evening to put this all together; something i would have never dared dreaming about a year ago!

But there’s still a lot to do:

There seems to be a timing issue in the code, cause i saw the XBee having a bit of trouble joining the PAN. Maybe give it some more time in the setup routine, or give some more time during powering up the XBee to send a new sample… we’ll see.

I need to write some software on PC-side to test reliability of it all.

How long will the batteries survive? I haven’t got a clue… and how am i going to test this? For example, i can’t switch off my PC now, cause the XStick is powered by it; XStick not powered means no PAN means the XBee will keep on searching for the PAN and will use much much more power…

To make the whole package smaller, i need to stop using the pin headers on the JeeNode and just solder the wires right onto the board.

A big step ahead, but still a lot of questions to be answered…

Here’s the code that is currently running on the JeeNode:

#include <Ports.h>
#include <RF12.h>
#include "PortsBMP085.h"
#include <avr/sleep.h>
#include <NewSoftSerial.h>

NewSoftSerial XBSerial = NewSoftSerial(2, 3);
PortI2C two (2);
BMP085 psensor (two);

int pinXBee=7;                        // to Control XBee on/off
int pinCTS=6;                         // to monitor CTS

static int SampleInterval = 1000;     // 60000;
static int HeartBeatInterval = 10000; // 300000;
static int CTS=0;                     // value of XBee CTS pin

struct {
    int16_t temp;
    int32_t pres;
} payload;

static void lowPower (byte mode) {
    // prepare to go into power down mode
    set_sleep_mode(mode);
    // disable the ADC
    byte prrSave = PRR, adcsraSave = ADCSRA;
    ADCSRA &= ~ bit(ADEN);
    PRR &= ~ bit(PRADC);
    // zzzzz...
    sleep_mode();
    // re-enable the ADC
    PRR = prrSave;
    ADCSRA = adcsraSave;
}

EMPTY_INTERRUPT(WDT_vect); // just wakes us up to resume

static void watchdogInterrupts (uint8_t mode) {
    MCUSR &= ~(1<<WDRF); // only generate interrupts, no reset
    cli();
    WDTCSR |= (1<<WDCE) | (1<<WDE); // start timed sequence
    WDTCSR = bit(WDIE) | mode; // mode is a slightly quirky bit-pattern
    sei();
}

static byte loseSomeTime (word msecs) {
    // only slow down for periods longer than twice the watchdog granularity
    if (msecs >= 32) {
        for (word ticks = msecs / 16; ticks > 0; --ticks) {
            lowPower(SLEEP_MODE_PWR_DOWN); // now completely power down
            // adjust the milli ticks, since we will have missed several
            extern volatile unsigned long timer0_millis;
            timer0_millis += 16L;
        }
        return 1;
    }
    return 0;
}

static MilliTimer SampleTimer;     // Interval for reading a sample from the BMP085
static MilliTimer HeartBeatTimer;  // forced maximum interval (Heartbeat)

static byte periodicSleep (word msecs) {
    // switch to idle mode while waiting for the next event
    lowPower(SLEEP_MODE_IDLE);
    return SampleTimer.poll(msecs);
}

static void Send (const void* ptr, byte len) {

  unsigned long tXB1;    // time XBee was woken up
  unsigned long tXB0;    // time XBee was put to sleep

  Serial.println("Sending payload");
  HeartBeatTimer.set(0);

  CTS = HIGH;
  tXB1=millis();
  // wake up Xbee
  digitalWrite(pinXBee,LOW);

  // wait for CTS to become LOW
  do
  {
    CTS=digitalRead(pinCTS);
  } while (CTS != LOW);

  // wait 2 msec otherwise data will be received all messed up
  delay(2);

  // send dummy data
  XBSerial.print(payload.temp);
  XBSerial.print(" ");
  XBSerial.println(payload.pres);  

  Serial.print(payload.temp);
  Serial.print(" ");
  Serial.println(payload.pres);  

  // wait again for XBee to finish transmission
  delay(2);

  // switch off XBee
  digitalWrite(pinXBee,HIGH);
}

static int16_t prevTemp;           // save previous temp value
static int32_t prevPres;           // save previous temp value

// this code is called once per second, but not all calls will be reported
int ReadSensor() {

    int16_t temp = psensor.measure(BMP085::TEMP);
    int32_t pres = psensor.measure(BMP085::PRES);

    Serial.print("Readings: ");
    Serial.print(temp);
    Serial.print(' ');
    Serial.print(pres);
    Serial.println(' ');

    int changed = (temp != prevTemp) || (pres != prevPres);
    prevTemp = temp;
    prevPres = pres;

    payload.temp = temp;
    payload.pres = pres;

    changed = 1;            // force sending always during testing
    return changed;

}

void setup() {

  // setup XBee
  pinMode(pinXBee,OUTPUT);
  digitalWrite(pinXBee,LOW);
  pinMode(pinCTS,INPUT);
  digitalWrite(pinCTS,LOW);   // really necessary?
  delay(10);

  XBSerial.begin(9600);
  // give XBee some time to join PAN
  delay(5000);

  // let the world know we're here
  XBSerial.println("\n[TempPres]");
  Serial.println("\n[TempPres]");

  watchdogInterrupts(0); // 16ms
}

void loop() {
    if (periodicSleep(SampleInterval)) {
      // sensor values changed or heartbeat interval elapsed?
      if (ReadSensor() || (HeartBeatTimer.poll(HeartBeatInterval)))
      {
         Send(&payload, sizeof payload);
       }

    }
}
Tagged with:
Jan 30

I don’t own a weather station, nor do i intend to buy one, but i always did like the idea of having a pressure sensor. Now i have :-)

This BMP085 based pressure sensor doesn’t only do pressure, but can also measure the temperature. Time to hook it up to a JeeNode!

Due to the fact that our plans for today had to be canceled by the bad weather, i had some extra time to test this Pressure Sensor. First i had to solder the 2nd JeeNode i bought last week, cause it was still unassembled in it’s plastic bag. Soldering a JeeNode is quite easy to do; it’s really hard to do something wrong… This time i left the RF12 radio off because i wanted to use one of my XBee modules to send the raw measured values. And i attached a battery holder, cause eventually this is my goal: a battery powered pressure sensor.

I installed the Ports library, uploaded the BMP085 demo sketch from the Ports Library examples  to the JeeNode and everything ran fine:

BMP 26265 39759 225 99390
BMP 26260 39755 225 99372
BMP 26267 39761 226 99400
BMP 26263 39756 225 99378
BMP 26265 39759 225 99390
BMP 26263 39758 225 99384
BMP 26261 39757 225 99378

Next step will be adding code for the XBee and sleeping. To bad, time’s up for now… hopefully, later this evening i have some time left to finish this sensor.

JeeNodev4 with BMP085 Sensor

JeeNodev4 with BMP085 Sensor

Tagged with:
Dec 27

Today i had some spare time to combine a few of the things i’ve been working on lately:

  • My Zigbee API;
  • Arduino;
  • Pan & Tilt mechanism

I wanted to create a small executable that would enable me to control the position of the 2 servo’s.

XBee module

I started with programming the XBee: Zigbee End Device AT firmware, the right PAN, Node Identifier ED5 (as in End Device 5), Sleep Mode=1 (Pin Hibernate). I put the module on a breadboard by use of a Breakout Board. Grounded pin 9 and used the 3.3V output of the Arduino to power the module.

Arduino

I strapped the Arduino Duemilanove to the same breadboard and wired the 2 servo’s. Pins 9 and 10 of the Arduino are used as PWM output for the 2 servo’s. Arduino pins 2 & 3 were connected to the DIN and DOUT pins of the XBee module.

Sketch

Now it was time to write a sketch that would receive commands from the XBee and move the servo’s accordingly. The sketch is a real quick and dirty one, low on error handling and validation. I made up a small ‘protocol’: commands have to end with the exclamation mark (”!”) and can be either 1 or 2 characters long.

P+! would Pan right 3 degrees, P-! would Pan left 3 degrees, T+! would Tilt up 3 degrees and so on. H! is the command to go back to the Home position. Of course you can extend this as much as you like, e.g. add absolute positioning, presets, you name it.

This is the sketch:

#include <NewSoftSerial.h>
#include <ServoTimer1.h>
#include <PString.h>

ServoTimer1 PanServo;
ServoTimer1 TiltServo;

int PanAngle = 90;
int TiltAngle = 90;
byte DeltaPan = 3;         // move 3 degrees
byte DeltaTilt = 3;        // move 3 degrees
char cbuffer[40] = "";     // receive buffer
NewSoftSerial XBSerial = NewSoftSerial(2, 3);
PString buffer(cbuffer, sizeof(cbuffer));

void setup() {

  XBSerial.begin(9600);         // set up XBee at 9600 bps
  delay(10000);                 // wait 10 sec. for possible joining

  PanServo.attach(9);
  TiltServo.attach(10);

  PanServo.write(PanAngle);
  TiltServo.write(TiltAngle);
}

void waitforcommand()
{
  while (true)
  {
    if (XBSerial.available())
    {
      int c = XBSerial.read();
      if (c == 0x21)     // command terminator = "!"
      {
        break;
      }
      else
      {
        // add to buffer
        buffer.print(c,BYTE);
      };
    };
  };
}

void loop() {

  buffer="";
  waitforcommand();

  // what's the first character?
  switch (buffer[0])
  {
    case 0x50:             // P for Pan
      {
        // what's the next character?
        switch (buffer[1])
        {
          case 0x2B:       // +
            PanAngle += DeltaPan;
            break;

          case 0x2D:       // -
            PanAngle -= DeltaPan;
            break;
          };
          break;
      };
    case 0x54:            // T for Tilt
      {
        // what's the next character?
        switch (buffer[1])
        {
          case 0x2B:       // +
            TiltAngle += DeltaTilt;
            break;

          case 0x2D:       // -
            TiltAngle -= DeltaTilt;
            break;
          };
          break;
      };
    case 0x48:            // H for Home
      {
        PanAngle=90;
        TiltAngle=90;
        break;
      };  

  };

  // check boundaries for Pan
  PanAngle=(PanAngle < 0)?0:PanAngle;
  PanAngle=(PanAngle > 180)?180:PanAngle;

  // check boundaries for Tilt
  TiltAngle=(TiltAngle < 90)?90:TiltAngle;
  TiltAngle=(TiltAngle > 180)?180:TiltAngle;

  // Set dervo's accordingly
  PanServo.write(PanAngle);
  TiltServo.write(TiltAngle);

}

PC software

Next item was a small program that would use the API to address the XBee module.

XBee servo control

XBee servo control

4  buttons for Left, Rigth, Up and Down, a Home button and a button to connect to the Zigbee network. Not very spectacular, I’d say.

There are 2 important API functions that are used to communicate with the Zigbee module:

  • Node Discovery
  • XBee Transmit Request.

The code that is executed when the “Connect” button is pressed, sends out a Node Discovery command. This will trigger all joined Zigbee modules to respond with information about themselves, like 16- and 64-bit address, node identifier and some more interesting stuff. The code goes something like this:

  XB:=TXBEE.Create(14,9600);
  XB.Open;
  gXBeeModules.Clear;
  cmd:=TXBee_NodeDiscover.Create('');
  XB.SendPacket(cmd.GetPacket);

The Node Identifier is used to see if the Zigbee module that is connected to the Arduino, is “in the air”. Cause it doesn’t have to be, it could be disconnected from power or whatever…

When the Zigbee module with Node Identifier “”ED5″ has responded, the 5 buttons are enabled and clicking them will move the servo’s. This is done with the XBee Transmit Request function; a string is being sent to the XBee and the XBee will take care of transferring it out on the UART.  Below the code for the “Home” button:

i:=gXBeeModules.Indexof('ED5');
if i >=0
then begin
Module := TXBeeModule(gXBeeModules.Objects[i]);
Addr16:= Module.Addr16 ;
Addr64:= Module.Addr64 ;
TR:=TXBeeTransmitRequest.Create(1,Addr16,Addr64,"H!");
X.SendPacket(TR.GetPacket);
end;

Et voila, the servo’s start moving!

To see how (good or bad) it works, i’ve made a small video.
The power of Arduino and Zigbee!!!

Tagged with:
Dec 25

Now that i managed to put an XBee ZB module to sleep, all i had left to do was being able to put the RBBB to sleep for a certain amount of time (and have it wake up again!).  It would be very nice if i could use 2 triggers for waking up the controller: based on a predefined interval and by some external source (for example an attached motion detector that detects motion).

Zigbee module

Low-power Zigbee & Arduino

Both are actually equally important, so i tossed a coin with the outcome that i started with trying to accomplish to wake up the RBBB on a predefined interval. I found an article that pretty much did what i wanted. The maximum time that the Watchdog Timer can power down the microcontroller is 8 seconds, after which it will wake up again and carry on with it’s job. I modified some things so that the power down routine is called multiple times, which results in a power down mode in multples of 8 seconds. Currently the wake up interval is set at 32 (4*8) seconds and it has run flawlessly for 16 hours now. I still have to dig in deeper to the Watchdog code see if my ‘modifications’ can be made more efficient, but for now this will be OK.

Now i wonder what the power consumption of this combination of RBBB and Zigbee module is… should i let it run on a battery and wait till it stops? How long will that be…. no; i think it’s better to find a way to estimate battery life by actually measuring the power consumption. That will probably mean i will need extra hardware and tools.

Tagged with:
Dec 24

While working on the experiments I’ve done in the past months with the Arduino Duemilanove, RBBB, XBee Series 1 and 2 modules the thought of a wireless, battery powered, ‘intelligent’ sensor kept me busy.

RBBB controlling a XBee ZB module

RBBB controlling a XBee ZB module

Finally the time had come  to do some experiments  in that direction. I’ve found several very well written articles, all by Jean-Claude Wippler regarding Low-power techniques. This was a very good starting point; one of the things that i concluded is that running on 3.3V is the best choice: it seems it’s much easier to interface with sensors at 3.3V then 5V. So i really gotta have me some JeeNodes soon now! :-)

But it wouldn’t hurt to already start searching the net for code that would support bringing the ATMega to a state in which it would consume much less power.  I had already found a way to bring an XBee module to deep sleep by setting Sleep Mode (SM) to 1 and grounding pin 9, so now it was time to start sketching and produce something that could put both the RBBB and the attached XBee to sleep for a fixed period, wake them up, take samples of whatever sensor is attached, send the data to the Zigbee Coordinator and go back to sleep again. I didn’t want to use any external trigger, so the solution had to be found inside the MCU itself.

Putting XBee to sleep

First i wrote a sketch that periodically woke up the XBee, send some data and put the XBee back to sleep. That shouldn’t be that hard.  How wrong could i be….

The job to do comes down to the following sequence:

  • wake up the XBee (use a Digital Output from the RBBB to set XBee pin 9 low);
  • wait for the XBee to be ready (CTS pin to go low);
  • send some dummy data;
  • wait a little more and put the XBee back to sleep (set XBee pin 9 back to high);
  • delay the loop for a number of seconds.

At first run all worked fine. However, after increasing the interval at which the job listed above were to be executed, i started losing packets. Because i enclosed a counter value into the sent data, i could see a very strange behavior: depending on the interval i saw packets coming only once every 2 or 3 times a packet was sent… What’s that?? By playing around with the interval i could determine that something strange was happening when the interval was set above 5 seconds. Why ? It took me some time to figure this out.

Sleeping XBee

Sleeping XBee

I  remembered the 5 seconds to be the default value for the “Time Before Sleep” (ST) Command. But this Command and the value set, are only applicable for Cyclic Sleep End Devices. And indeed, changing the Time Before Sleep didn’t make things better. OK, so now it was time to start reading the manual really well :-)

And there it was: the “Child Poll Timeout” must be what is bugging me. This is what the manual has to say about Child Poll Timeout:

“Router and coordinator devices maintain a timestamp for each end device child indicating when the end device sent its last poll request to check for buffered data packets. If an end device does not send a poll request to its parent for a certain period of time, the parent will assume the end device has moved out of range and will remove the end device from its child table. This allows routers and coordinators to be responsive to changing network conditions.”

So, if an End Device doesn’t let it’s parent (= Router, Coordinator) know that it’s still there from time to time, the End Device will be thrown out of the PAN, and has to start joining all over again; which takes a relatively long time, which it doesn’t really have being powered down all the time..

Increasing the value for the Child Poll Timeout on the Coordinator (to a higher value then the minimum of 5 seconds) resolved everything.

On to the next ‘easy’ job; using the ATMega328 Watchdog Timer to put the RBBB to sleep :-)

Tagged with:
Dec 21

This weekend i’ve been working on a setup to be able to test various things with the exciting Digi XBee modules that i’ve purchased some time ago.

XBee ZB modules and a RBBB

XBee ZB modules and a RBBB

As you can see there are 2 different types of XBee modules placed on the breadboard; there are 3 (a bit smaller) XBee Series 2 modules and 3 (larger) XBee-PRO modules. I also included an RBBB, a very small Arduino compatible device, that is located on the lower half of the board and is connected to the 6th XBee module. On the lower right side of the board there’s a 3.3V regulator to power the XBee modules.

First thing that had to be done was programming the upper row of 5 Digi XBee modules with the right firmware to let them all act as a End Device in AT/Transparent mode, and do some wiring. The XBee breakout board had already been soldered some time ago. I also added some LEDs for visualizing the status of the modules. After that, it was time do do some testing of my Domotica software to interface with these modules. Commands like “IS” for sampling the Digital/Analog IO ports on the modules. Here the first problem came up; the command did execute correctly cause i got a response back, but the payload of the frame was empty.. of course, after some time i realized i forgot to enable any of the I/O on the modules… :-(

Next command on the list was the ZigBee Transmit Request Command. This command is used for sending data to a module where it will be sent to the UART. This way it will arrive at the device that is attached to the XBee, in my case the RBBB. This allows me to communicate with the Arduino wirelessly. All worked well, i got the right responses back and i saw data arriving on the RBBB.

Now it was time to start sending data from the RBBB to my Domotica system. Here the default sleep mode of the Zigbee took some time to resolve. The first sketch for the RBBB sent some text to the XBee every 15 seconds. But this only arrived on my PC once every 2 minutes or so… and i didn’t know why. Changing the sketch and now sending the same text every second, made the problem go away… Suddenly i realized is was the default sleep mode that was bugging me! The default sleep mode for an XBee with this firmware is “Cyclic Sleep”, which means the module is only awake periodically. Ofcourse, sending data to the UART of a sleeping XBee doesn’t work… I tried to change Sleep mode to 0 (”always awake”) but that’s not even supported! Hmm, fortunately there’s a workaround for this: set sleep mode to 1 (”Pin Hibernate”), ground Pin 9 (the yellow wire in the picture does that) and you’re done. While trying to change the sleep mode on a specific module the use of the LED really payed off, cause suddenly the LED for the wrong module went off.. it seemed i had addressed the wrong module with the Sleep mode set to Pin Hibernate command. Typically a case of where you can keep on searching for hours and hours why it’s not working as expected, and all you did wrong was addressing the wrong module…

Now i have a sketch running on the RBBB that transmits a small text every 10 seconds and it will echo anything that is received. This way i can start testing how reliable the combination of XBee and Arduino really is.

Tagged with:
Dec 18

Since 4 weeks i have a Digi XStick. This is a USB module that provides connectivity to a XBee network:

XStick

XStick

This XStick ZB is configured to behave as a coordinator within a mesh topology. The XStick can be plugged directly into the USB port of a PC and doesn’t require batteries or power adapter since it’s USB powered. Last 2 weeks i’ve been working on a Zigbee interface for my domotica system, using ths XStick.

First some things you need to know..

An Xbee module has three communication modes:

  • Transparent mode,
  • Command mode
  • API mode.

At startup, an Xbee module is in transparent mode. In this mode, the module acts as a serial line replacement. All data received from the DIN pin is transmitted, and when RF data is being received, it is sent out on the DOUT pin. A pair of XBee modules can act as invisible cables in this mode.

Command mode is where you can change a large amount of settings of the XBee module. To enter Command mode you must send the characters “+++” and wait a second. Once the XBee enters command mode, it will answer with OK. Most of us will remember this behavior from modems. While in command mode you can change baud rate, destination address, etc etc. Leaving command mode can be accomplished by executing the ATCN command.

Sending messages to constantly changing targets (=other XBee modules), API mode is the best mode to choose. It is the most powerfull but also the most complicated mode to use. API (Application Programming Interface) mode is a frame-based method for sending and receiving data to and from an XBee.

API mode has some special abilities:

  • Changing parameters without entering command mode;
  • RSSI and source address information;
  • Receive packet delivery confirmation on every transmitted packet

Since API mode seems to be the most flexible, i decided to create an API-mode interface. With more then 140 pages of  information of how to interface with XBee/XBee-PRO ZB RF modules i knew this was a job that could take a while, but today i managed to get a sequence of API mode commands working.

The first command i started with  was the Node Discovery command, which will let every device on the network respond with basic information about that device. These reponses are received by the XStick, the address information of the responding XBee devices is stored and the next step is to send a request to all of the responding devices to request information about their hardware version. Today i succeeded in doing this first excercise, as you can see here:

Execute Node Discovery
Sending frame:7E 00 04 08 01 4E 44 64
Serialport.RxCount:33
RxBuffer:7E 00 1D 88 01 4E 44 00 86 23 00 13 A2 00 40 31 B9 04 45 44 41 54 32 00 00 00 02 00 C1 05 10 1E 12

*** Processing frame ***
ApiID = 88
Checksum Ok=True

ATCommandResponse, 29 bytes:
FrameID=1
Command=ND
Status=0
MY 8623
SH,SL 5526146518202628 (0013A2004031B904)
NI [EDAT2]
PARENT 00 00
DEVICE_TYPE 02
STATUS 00
PROFILE_ID C1 05
MANUFACTURER_ID 10 1E

Request Hardware Version for Node 8623
Sending frame:7E 00 0F 17 01 00 13 A2 00 40 31 B9 04 86 23 00 48 56 BD
Serialport.RxCount:21
RxBuffer:7E 00 11 97 01 00 13 A2 00 40 31 B9 04 86 23 48 56 00 19 44 E0

*** Processing frame ***
ApiID = 97
Checksum Ok=True

RemoteATCommandResponse, 17 bytes:
FrameID=1
Command=HV
Status=0
Response=19 44

So the XBee module that responded has a Hardware Version of 1944 :-)

Tagged with: