Arduino Uno + Zigbee S2

Hi!

I'm working on a project using Uno and Xbee S2s. So far, I've been trying to use the python-api library to send and receive api packets.

The problem I encounter is:

  1. I can't receive right data from PC to arduino through Xbees.
  2. I can't send data from arduino to PC through Xbees.

Not getting the right data
I tried to send a list of 'a','b','c','d'. But I got many weird things instead such as what I attached.
What is even more surprising is this... I programmed it such that if there's a 'a' or a 'b' it will change my LEDpin 13. And it really DID change even though I print out garbage on Serialport.

Not sending data
I tried to send back the data to no avail.

Things I have tried
Even though my xbee adapter itself has a 5V level conversion already,
I tried the following website to do a level conversion.
http://bildr.org/2011/04/arduino-xbee-wireless/
It didn't work at all...

I've attached the screenshot and the sketch that I used. I apologise as I'm really new to arduino and xbee...

XbeeABpin13_test.ino (783 Bytes)

I'm working on a project using Uno and Xbee S2s.

How are the XBees configured? How are they connected to the Arduinos?

Thanks for the reply.

How are they connected?
I have tried 2 ways of connecting them.

  1. I connect the 5V and ground from Xbee to Arduino. I connect the DOUT of Xbee to RX of Arduino. Similarly, DIN/Config to TX of Arduino.

  2. I connect the 3.3V and ground from Xbee to Arduino. I use the level convertor shown in the link below to connect the rest accordingly.
    http://bildr.org/2011/04/arduino-xbee-wireless/

Why are you not using a shield?

Okie... I'm trying to make a prototype of atmega328 with a Xbee to reduce the power consumption using a custom voltage regulator. Using a shield defeats the purpose since later I need to remove it from the setup too so that it'll be as small sized as possible (another requirement). I start off with the arduino uno first since it's quite close to what I need other than it's inefficient 7805 regulator. I'll replace it with a low q current regulator later which will help keep the project within reasonable power consumption.

Hmm. is it like no way to connect without a shield?

Using a shield defeats the purpose

Of understand that the XBee is configured correctly, and that the code is functioning? I don't think so.

is it like no way to connect without a shield?

There is. But building a prototype using an Arduino, a XBee shield and an XBee is not the same thing as building a finished product containing an ATMega328, a crystal, a few caps, and an XBee.

Get the prototype working first. Then, understand why the device works with the shield, but not without it, if indeed that is the case. If it doesn't work with the shield, either, then the problem is one of configuration of the XBees.

I'm just outlining how I'd approach solving the problem. Your mileage might vary.

I regularly use an XBee S2 connected directly to an arduino without special circuitry to try out ideas. The pins are 5V tolerant except for power, which you are getting from the 3.3V so that should be fine. I don't run them long term this way (weeks), but I have one device that has been set up this way for months. Net, I don't think the additional circuitry to do level conversions is necessary at the beginning stages, but will be over time.

What you seem to be getting is a baud rate difference. Double check the XBee on the arduino to be sure the baud rate is set to 9600 just to be sure something didn't sneak in and change it while you weren't looking. Note that the XBee on the Arduino and the XBee on the PC don't have to be the same baud rate, they have to match the device they're attached to. So, if the terminal emulator or XCTU or whatever on the PC is using a different baud rate, check that XBee to be sure it is correct.

Next, you mentioned that you were trying to do a project using API mode. The code you're using on the arduino will only show good stuff if you're using transparent mode. API mode will be wrapped up in headers, checksums, addresses and such and will appear to printing garbage out the serial port. So, make sure (for now at least) that you are not using API mode. As for the fact that you see the led change, a bunch of seemingly garbage characters may well have an a or b in there somewhere; this may just be an accident.

When you get it talking such that you recognize the characters, take a look at the XBee library to help you decode the API packets; this will save you some trouble and headaches when you get further into the project.

@Paul
Thanks. I kind of understand your approach. Solve the most workable setup before moving down to harder circuits slowly to ease debugging. I would like to but currently I don't own a shield partly because I'm not too sure of project budget (my supervisor is not telling me for some odd reason). And thus, I didn't buy it because I thought it won't be in the final setup. I'll consider getting one though...

@dray
Thanks. I think you kind of hit where the bug is. I've checked the BAUD rate and they matched alright. But indeed, the issue is with the API mode. I've reverted back the xbee on the arduino side to AT mode while keeping the coordinator API. Now, the xbee on the arduino side is able to send data perfectly fine. The odd thing is the coordinator xbee can't send data to the arduino xbee(AT). Btw, I'm currently using SoftwareSerial to do this. Below is my code

#include <SoftwareSerial.h>

SoftwareSerial xbee(2,3);

char data = 'B';

void setup() {
  Serial.begin(9600);    	//initialize serial
  xbee.begin(9600);
  pinMode(13, OUTPUT);   	//set pin 13 as output
}

void loop() {
  xbee.print(data);
  while(xbee.available()){  //is there anything to read?
	char getData = xbee.read();  //if yes, read it
        Serial.print(getData);

	if(getData == 'a'){
  	  digitalWrite(13, HIGH);
          xbee.print('x');
	}else if(getData == 'b'){
  	  digitalWrite(13, LOW);
          xbee.print('z');
	}else if(getData == 'c'){
          xbee.print(getData);
        } 
  }
}

Btw, are you referring to this site when you say that I should look into for API transfer?

I did try to use one of the Zigbee S2 RX example but I seem to find no head way.

Glad I could help. Now, I think you've got the exact same problem in reverse. What I mean is that your talking from the PC to the XBee and the XBee is in API mode. It's most likely rejecting everything you send because you haven't constructed an API frame to send to it. Now, if you already know all this, just tell me to shut up.

See, when you use API mode, you have to construct the packet according to the XBee's requirements. Start sentinel, addresses, etc., all the way to and including the checksum to get the XBee to accept and forward it. The XBee wraps all this up in another packet and finally sends it to the destination. So, if you aren't doing everything right, the XBee will drop it on the floor and ignore it. You can test this by simply switching the XBee hooked to the PC to AT mode and type a few characters into the terminal window. They should show up on the arduino.

Then, you get the wonderful chore of constructing the packets on the PC and taking them back apart on the arduino. That's why I recommend using the library on the arduino to simplify that task. There's another library out there for the PC. You'll have to scout around for it, I have never used it, but it's got to be easier than building one yourself. If you can get your boss to spring for it, get Faludi's book on the XBee and take a look at it. There's a ton of examples in there that will help you get past this little hump and into the real code that actually does stuff.

Thanks. I've tried to do it in Transparent mode and it is able to receive and transmit. (I did a loopback to make sure it worked)

Anyway, I've tried to use the Xbee and API mode testing. So far I only tested the receiving part. I think it works but the payload gives me hexidecimal instead of ascii. I send a 'a' and got a payload of 61 on my arduino. I checked and it matched the hex of 'a' on ascii.

I'll continue to check out the transmitting to post again. I'll post my final testing codes here once I got both tx and rx to work. =) Thanks!

Hi,

Just gonna round up the last bit and thank everyone for helping out!

This is my transmitter/router code to send data. I've made it such that it's easy to do debugging on Serial by changing some of the codes.
It basically send 'aa' over. Thanks to Paul's SoftwareSerial codes, I can line the Xbee on pin8 and 9. =)

#include <XBee.h>
#include <SoftwareSerial.h>

/*
This example is for Series 2 XBee
 Sends a ZB TX request with the value of analogRead(pin5) and checks the status response for success
*/
char data = 'a';

// Connect Arduino pin 8 to TX of usb-serial device
uint8_t ssRX = 8;
// Connect Arduino pin 9 to RX of usb-serial device
uint8_t ssTX = 9;
// Remember to connect all devices to a common Ground: XBee, Arduino and USB-Serial device
SoftwareSerial nss(ssRX, ssTX);

// create the XBee object
XBee xbee = XBee();

uint8_t payload[] = { 0, 0 };

// SH + SL Address of receiving XBee
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x4079a7f9);
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

int pin5 = 0;

int statusLed = 13;
int errorLed = 13;

void flashLed(int pin, int times, int wait) {

  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);

    if (i + 1 < times) {
      delay(wait);
    }
  }
}

void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
  
  nss.begin(9600);
  Serial.begin(9600);
  xbee.setSerial(nss);
}

void loop() {   
  // break down 10-bit reading into two bytes and place in payload
  payload[0] = data & 0xff;
  payload[1] = data & 0xff;
  //pin5 = analogRead(5);
  //payload[0] = pin5 >> 8 & 0xff;
  //payload[1] = pin5 & 0xff;

  xbee.send(zbTx);

  // flash TX indicator
  flashLed(statusLed, 1, 100);

  // after sending a tx request, we expect a status response
  // wait up to half second for the status response
  if (xbee.readPacket(500)) {
    // got a response!

    // should be a znet tx status            	
    if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
      xbee.getResponse().getZBTxStatusResponse(txStatus);

      // get the delivery status, the fifth byte
      if (txStatus.getDeliveryStatus() == SUCCESS) {
        // success.  time to celebrate
        flashLed(statusLed, 5, 50);
      } else {
        // the remote XBee did not receive our packet. is it powered on?
        flashLed(errorLed, 3, 500);
      }
    }
  } else if (xbee.getResponse().isError()) {
    Serial.print("Error reading packet.  Error code: ");  
    Serial.println(xbee.getResponse().getErrorCode());
  } else {
    // local XBee did not provide a timely TX Status Response -- should not happen
    flashLed(errorLed, 2, 50);
  }

  delay(1000);
}

And this is for the receiver. I notice Dray did something similar in the past when I was surfing the web. Great minds think alike!

#include <XBee.h>
#include <SoftwareSerial.h>

/*
This example is for Series 2 XBee
Receives a ZB RX packet and sets a PWM value based on packet data.
Error led is flashed if an unexpected packet is received
*/

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle 
ZBRxResponse rx = ZBRxResponse();
ModemStatusResponse msr = ModemStatusResponse();

// Define NewSoftSerial TX/RX pins
// Connect Arduino pin 8 to TX of usb-serial device
uint8_t ssRX = 8;
// Connect Arduino pin 9 to RX of usb-serial device
uint8_t ssTX = 9;
// Remember to connect all devices to a common Ground: XBee, Arduino and USB-Serial device
SoftwareSerial nss(ssRX, ssTX);


void setup() {  
  // start serial
  Serial.begin(9600);
  nss.begin(9600);
  xbee.setSerial(nss);
  Serial.println("starting up here!");
}

// continuously reads packets, looking for ZB Receive or Modem Status
void loop() {
    
    xbee.readPacket();
    
    if (xbee.getResponse().isAvailable()) {
      // got something
           
      if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        // got a zb rx packet
        
        // now fill our zb rx class
        xbee.getResponse().getZBRxResponse(rx);
      
        Serial.println("Got an rx packet!");
            
        if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
            // the sender got an ACK
            Serial.println("packet acknowledged");
        } else {
          Serial.println("packet not acknowledged");
        }
        
        Serial.print("checksum is ");
        Serial.println(rx.getChecksum(), HEX);

        Serial.print("packet length is ");
        Serial.println(rx.getPacketLength(), DEC);
        
         for (int i = 0; i < rx.getDataLength(); i++) {
          Serial.print("payload [");
          Serial.print(i, DEC);
          Serial.print("] is ");
          Serial.println(rx.getData()[i], HEX);
        }
        
       for (int i = 0; i < xbee.getResponse().getFrameDataLength(); i++) {
        Serial.print("frame data [");
        Serial.print(i, DEC);
        Serial.print("] is ");
        Serial.println(xbee.getResponse().getFrameData()[i], HEX);
      }
      }
    } else if (xbee.getResponse().isError()) {
      Serial.print("oh no!!! error code:");
      Serial.println(xbee.getResponse().getErrorCode());
    }
}

And I will add that I use xbee-python library to solve the api problem on PC. It was really good and easy to use and I love PYTHON! =)

Very glad you got over this hump. Now, have fun with it.