Part 1 <link>, Part 2 <link>.
As part of my porting of my devices to the latest version of the Arduino IDE, I decided to move the devices to using the XBee library. Back in part 1 I described why I suddenly took an interest to it, and since I was going into the code, I might as well start using it for real at the same time. The changes to make my XBees receive packets using the library went without a hitch. It just worked fine and reduced the code I had to write by a lot. However, when I looked at transmitting data, I was appalled. All the examples show somthing like:
I mean REALLY?? Setting the bytes into an array one at a time? Well, I went searching the web to see what else could be done and found dozens of examples of this kind of thing. Here's one from the New SoftSerial example:
void loop() {
payload[0] = 'H';
payload[1] = 0x7E;
payload[2] = 0x11;
payload[3] = 0x13;
payload[4] = 0x7D;
xbee.send(zbTx);
I even saw examples that had many bytes filled in one at a time to compose the data that needed to be sent. Clearly, the examples need to be updated. That's not something that is easy to do, but I can put an example here to show how a simple string, "Hello World" can be transmitted to another XBee without all the hassle. Here is an extremely easy way to do it:
Yes, that's all there is to it; this example will compile and run using IDE 1.0.3 on a Mega2560. Andrew made the library quite capable, but most people don't seem to want to look deeply enough into it to use it to advantage. Notice that you fill in the Tx request with an address and then send the string pointer and its length to the XBee. It's just that simple. You can use a buffer and format it to be exactly what you want, then hand it off to the xbee.send() for transmission. Really, really nice.
Remember though this example is for a mega2560 with four serial ports. To do exactly the same thing on a UNO, just use SoftwareSerial as I described in part 1. It will work equally well and you still have the Serial to output status and debugging information so you can see what is going on.
Suppose you want to send the packet to a specific XBee on your network, avoiding the problems that can happen with broadcast <link> it's actually really easy. Just create another address like the one for Broadcast in the example above and use it instead.
Using this technique, I reduced a fifty or so line transmit routine down to:
Yes, I can compose the commands for my various devices and then just call sendXbee() with the string. Simple, easy to read, and it works.
I like my little XBees more and more each day.
As part of my porting of my devices to the latest version of the Arduino IDE, I decided to move the devices to using the XBee library. Back in part 1 I described why I suddenly took an interest to it, and since I was going into the code, I might as well start using it for real at the same time. The changes to make my XBees receive packets using the library went without a hitch. It just worked fine and reduced the code I had to write by a lot. However, when I looked at transmitting data, I was appalled. All the examples show somthing like:
XBee Tx Example
void loop() {
// break down 10-bit reading into two bytes and place in payload
pin5 = analogRead(5);
payload[0] = pin5 >> 8 & 0xff;
payload[1] = pin5 & 0xff;
xbee.send(zbTx);
// flash TX indicator
flashLed(statusLed, 1, 100);
// break down 10-bit reading into two bytes and place in payload
pin5 = analogRead(5);
payload[0] = pin5 >> 8 & 0xff;
payload[1] = pin5 & 0xff;
xbee.send(zbTx);
// flash TX indicator
flashLed(statusLed, 1, 100);
I mean REALLY?? Setting the bytes into an array one at a time? Well, I went searching the web to see what else could be done and found dozens of examples of this kind of thing. Here's one from the New SoftSerial example:
Another Example
void loop() {
payload[0] = 'H';
payload[1] = 0x7E;
payload[2] = 0x11;
payload[3] = 0x13;
payload[4] = 0x7D;
xbee.send(zbTx);
My Tx Example
/*
XBee RX test for a Arduino Mega2560 using Serial3 as the XBee serial
input for a Series 2 XBee. This is NOT based on the examples that come with
the Arduino XBee library.
See, the examples there and most other places on the web SUCK. Andrew's
library is much easier to use than the illustrations would lead you to believe.
This is a HEAVILY commented example of how send a text packet using series 2
XBees. Series 1 XBees are left as an exercise for the student.
*/
#include <XBee.h>
XBee xbee = XBee();
// This is the XBee broadcast address. You can use the address
// of any device you have also.
XBeeAddress64 Broadcast = XBeeAddress64(0x00000000, 0x0000ffff);
char Hello[] = "Hello World\r";
char Buffer[128]; // this needs to be longer than your longest packet.
void setup() {
// start serial
Serial.begin(9600);
// and the software serial port
Serial3.begin(9600);
// now that they are started, hook the XBee into
// Software Serial
xbee.setSerial(Serial3);
Serial.println("Initialization all done!");
}
void loop() {
ZBTxRequest zbtx = ZBTxRequest(Broadcast, (uint8_t *)Hello, strlen(Hello));
xbee.send(zbtx);
delay(30000);
strcpy(Buffer,"I saw what you did last night.\r");
zbtx = ZBTxRequest(Broadcast, (uint8_t *)Buffer, strlen(Buffer));
xbee.send(zbtx);
delay(30000);
}
XBee RX test for a Arduino Mega2560 using Serial3 as the XBee serial
input for a Series 2 XBee. This is NOT based on the examples that come with
the Arduino XBee library.
See, the examples there and most other places on the web SUCK. Andrew's
library is much easier to use than the illustrations would lead you to believe.
This is a HEAVILY commented example of how send a text packet using series 2
XBees. Series 1 XBees are left as an exercise for the student.
*/
#include <XBee.h>
XBee xbee = XBee();
// This is the XBee broadcast address. You can use the address
// of any device you have also.
XBeeAddress64 Broadcast = XBeeAddress64(0x00000000, 0x0000ffff);
char Hello[] = "Hello World\r";
char Buffer[128]; // this needs to be longer than your longest packet.
void setup() {
// start serial
Serial.begin(9600);
// and the software serial port
Serial3.begin(9600);
// now that they are started, hook the XBee into
// Software Serial
xbee.setSerial(Serial3);
Serial.println("Initialization all done!");
}
void loop() {
ZBTxRequest zbtx = ZBTxRequest(Broadcast, (uint8_t *)Hello, strlen(Hello));
xbee.send(zbtx);
delay(30000);
strcpy(Buffer,"I saw what you did last night.\r");
zbtx = ZBTxRequest(Broadcast, (uint8_t *)Buffer, strlen(Buffer));
xbee.send(zbtx);
delay(30000);
}
Yes, that's all there is to it; this example will compile and run using IDE 1.0.3 on a Mega2560. Andrew made the library quite capable, but most people don't seem to want to look deeply enough into it to use it to advantage. Notice that you fill in the Tx request with an address and then send the string pointer and its length to the XBee. It's just that simple. You can use a buffer and format it to be exactly what you want, then hand it off to the xbee.send() for transmission. Really, really nice.
Remember though this example is for a mega2560 with four serial ports. To do exactly the same thing on a UNO, just use SoftwareSerial as I described in part 1. It will work equally well and you still have the Serial to output status and debugging information so you can see what is going on.
Suppose you want to send the packet to a specific XBee on your network, avoiding the problems that can happen with broadcast <link> it's actually really easy. Just create another address like the one for Broadcast in the example above and use it instead.
Using this technique, I reduced a fifty or so line transmit routine down to:
How Simple It Can Be
XBeeAddress64 Broadcast = XBeeAddress64(0x00000000, 0x0000ffff);
void sendXbee(const char* command){
ZBTxRequest zbtx = ZBTxRequest(Broadcast, (uint8_t *)command, strlen(command));
xbee.send(zbtx);
}
void sendXbee(const char* command){
ZBTxRequest zbtx = ZBTxRequest(Broadcast, (uint8_t *)command, strlen(command));
xbee.send(zbtx);
}
Yes, I can compose the commands for my various devices and then just call sendXbee() with the string. Simple, easy to read, and it works.
I like my little XBees more and more each day.