Go Down

Topic: xbee serial.write question (Read 7200 times) previous topic - next topic


Oct 25, 2011, 06:03 am Last Edit: Oct 25, 2011, 06:27 am by draythomp Reason: 1
Ah crap, I think I know what it is.  There's nulls in there and I'll bet serial.write is messing up.  Try putting it in a loop like:

for(int i = 0; i<sizeof(array);i++){

I bet you get different results.  (not much though)


I'm still following this thread and haven't gotten any iteration of these to be successful.

I was using AP=1. However x-ctu seemed to be able to send my packet over unescaped (according to the log), which is puzzling.
I'm trying A=2 and escaping without much luck, but I'm continuing to tinker.

To answer some other questions, yes I'm just trying to turn D2 on/off remotely. It's harder than it looks!

Someone said, "It was pretty easy, it just took a while to find out how easy it was."  ;-)

Anyway, I stopped parsing when I saw the 0x13. But there is also a 0x7E in the XBee's 64-bit address, this must be your lucky day! Make sure AP=2 and then try:

Code: [Select]
byte turnondata[] = {0x7e, 0x00, 0x10, 0x17, 0x01, 0x00, 0x7d, 0x33, 0xa2, 0x00, 0x40, 0x7d, 0x5e, 0x71, 0x53, 0xff, 0xfe, 0x02, 0x44, 0x32, 0x05, 0x36}
byte turnoffdata[] = {0x7e, 0x00, 0x10, 0x17, 0x01, 0x00, 0x7d, 0x33, 0xa2, 0x00, 0x40, 0x7d, 0x5e, 0x71, 0x53, 0xff, 0xfe, 0x02, 0x44, 0x32, 0x04, 0x37}


Oct 25, 2011, 07:48 pm Last Edit: Oct 25, 2011, 08:31 pm by draythomp Reason: 1
Ok, it's time to look at a working example.  I cut this out of my code that is running right now and doing this every single day.  Strangely, I didn't have any trouble getting it to work.  So...

Code: [Select]
const char acidPumpOnCommand[] PROGMEM = {0x10,0x01,0x00,0x00,0x00,0x00,

void sendXbee_P(const char* command, int length){
 byte checksum = 0;
 int i;
 Dbuf[0] = 0x7e;  // begin frame
 Dbuf[1] = length >>8;
 Dbuf[2] = length & 0xff;
 // copy command into buffer calculating checksum at the same time
 for(i = 0; i<length; i++){
   char c = pgm_read_byte(command + i); // can't use command[i]
   Dbuf[i+3] = c;
   checksum += c;
   Serial.print(" ");
 Dbuf[i+3] = 0xff - checksum;
 for(i = 0; i<length + 4; i++){
   Serial.print(" ");

void printByteData(uint8_t Byte){
 Serial.print((uint8_t)Byte >> 4, HEX);
 Serial.print((uint8_t)Byte & 0x0f, HEX);

//and then somewhere in the code somewhere I put

void acidPumpOn(){
 sendXbee_P(acidPumpOnCommand, sizeof(acidPumpOnCommand));

I run in API mode 1 and send in broadcast so I can watch my XBee network with an XBee plugged into the side of my laptop.  That way I can see how bad a problem I have with collisions and also inject commands from time to time to see if things are working right.  My coordinator is a separate device that is up in the attic so most of the devices can see it easily and does almost nothing except coordinate and send the current time over the network to sync the various devices.  I use progmem because I got tired of running out of memory on the smaller devices, hence the way the array is defined.  I calculate the checksum in the code because I got pretty tired of putting together commands and having the checksum wrong.  The debug is in there because I (naturally) want to be able to see the hex data that is being sent.  My network protocol is totally readable ascii; I want to be able to tell what the heck is going on without checking bytes.

This should give you a clue on what to do next.

edit:  Oh, and I took this from a mega2560 board, that's why I use Serial1 as the XBee output and Serial as the debug.  I do the same thing on a regular arduino but the XBee is on a SoftwareSerial port there.


Ok, it's time to look at a working example.  ...

Well that is one example with no bytes that need to be escaped, so AP=1 or AP=2 would be equivalent I suppose. Good idea, though, I was going to suggest to the OP that he could write a function to add the start delimiter, length, checksum, do the escapes, and still have a pretty thin solution.

draythomp, are you using S1 or S2? Not sure if all this API/escape business is the same between the two, I'm only familiar with S2.

And how's broadcast working for you? There were some pretty dire-sounding warnings about broadcast causing a lot of network discovery overhead. But I guess it depends on network size too. Haven't tried broadcast, myself. BTW, checked out your web site some time back, very impressive project!


I only have S2.  I never even looked at the S1 because I wanted to have all the stuff you get from Zigbee.  And, as you know, it works.  I can put a device 100 yards away, and if it doesn't reach, just put one in the middle to relay the data.  That is so cool.

Regarding broadcast.  Yes, there are some problems related to collisions and some others that I really don't understand, but all in all, it works darn nicely.  I could eliminate all the problems by just going to a query, response protocol, but then the devices wouldn't be nearly as autonomous and it's nice to be able to put a monitor XBee anywhere and have it pick up the various devices talking.  One device though is fully API.  I have a thermometer that sends its temperature to a specific device and I can't see it on the network by just monitoring.  I don't really like that and will eventually change it to use an ardweeny and broadcast.  But, it was an experiment to see if I could do it that worked and worked itself into being a 'necessary' part of the project.  Funny how that happens.

It's funny though Jack, I had some initial problems with getting the XBees to talk, but after a little messing around, I add XBees at a whim.  I can set one up to tell me the coffee pot turned on in about 20 minutes and have it work first try.  I'm not the sharpest tool in the shed and make stupid mistakes all the time, but I don't seem to have anywhere near the problems with these little devices that other people do.  Has that been your experience, or am I just lucky?


Yeah, I get along with 'em pretty well too, not a rocket scientist here either, I read Faludi's book, which helped a lot, and I'm sure my background helps as well. But I'm just amazed at how well they work, how easy they are to use, and like you say, all the cool stuff they just do for you. (No, I don't work for Digi Intl. Maybe I should?  XD)

I like the idea of being able to plug one into the laptop and basically sniff the whole network. I haven't built a network larger than probably 4 or 5 nodes. I use all AP=2. I will use Serial.print, LCDs, etc., to monitor and debug, but basically, once they're working, they just keep on truckin.

So I don't know. Conceptually they can be simple: Send data from "A" to "B" ... but there's a lot of complexity in that little package too, and even though it's not all (or even mostly) visible to the casual user, having some appreciation certainly does help understand what's going on.

I don't use a polling approach. My data rates are low, 1/minute usually, and the fastest is 6/minute, so I just go with a send-it-when-you've-got-it approach. Most nodes send to the coordinator, so I implemented a timed staggering based on the node identifier (NI), basically it's a number which determines when each node transmits. Not sure how necessary that really is, since I'm sure the network will handle some amount of collisions without issue. While I process the acknowledgements, I don't worry about retransmitting any failed packets, as any one is of no consequence, there's another sample coming in a minute. While I have no reason to believe any packets are getting dropped, at the same time I've never instrumented it, I should try that sometime!

Good Stuff!


I stole your idea of putting an identifier in the NI parameter and reading it back into the arduino at start up to identify the device.  It worked really well.  Using that little clue helped me with identical devices that are just in different spots.  The way I'm using broadcast, it allows me to rename a device and even change it's behavior based on a name I plug in.  Things like coyote motion detector north end are possible..heh.  Although it's actually CMDN in the NI parameter, but I know what that means.  Thanks for posting that a while back.

So, OP, where are you?


OP is tied to a desk at work. :smiley-eek: I should be able to figure this out based on all of the information provided here, which is great. Thank you!

The code I posted was also just a distilled sample--I have much more I will be doing in this project.

I'll write back with final success, which should be imminent.  


Coyotes! Sweet! Used to travel to AZ a bit in my younger days, Phoenix area. Liked it a lot, once I got sweated out! Has grown up an awful lot since then. Had to drive through miles of open range back then to get to the Pinnacle Peak restaurant. Almost ran out of gas out there once, kind of a scary prospect. I see you're not too far from Cave Creek, been there too.

Yeah the OP has a couple suggestions back up there a ways I'd like to see him try, if we haven't either bored him or frightened him off  :D


Ok, it's working using the arrays Jack provided and AP=2. Awesome!

I can continue writing with my adventures now...

As a sidenote, I dug around your project pages a bit. The Arizona house project is great and similar to what I'm doing, though I'm not quite at the same scale. I have a cabin in northern VT. I can turn the stoves on remotely, monitor temperatures inside and out throughout the year and, most importantly, turn the heat on before I get there. The place is built to freeze solid and indoor temperatures routinely reach < zero Fahrenheit in the winter. It used to take 24 hours to get the place up to a reasonable temperature in the winter. It still does, but I can get a remote head start these days.

The control for the whole thing is my own domain/host, Google graph APIs, jpgraph, and a whole ton of PHP.

Thanks again!


Hey that's great news! Your place sounds great, although 180° from Arizona, ha! We get winter here, but not like Vermont. Starting to lay in next year's firewood, but haven't fired the wood stove up this season yet. Might have to give you a shout sometime on the Google Graph stuff. I've just felt my way along the wall in the dark with it once or twice.


Definitely look me up for Google Graphs API help. The API is surprisingly difficult since it's so JavaScript dependent, but in the end of the day the graphs are just too pretty.

Go Up