Re: Reading RSSI of XBee Series 2 Problem

Greetings all,

I encountered a problem and have been searching for solutions in the web. Basically, this topic is a follow up from another thread that encountered the same problem as me. One of the tutorials I went to is http://letsmakerobots.com/node/37243

So basically, after following the instructions from that tutorial, I am only getting readings of “0” for my RSSI in my Serial Log while the tutorial is able to get a range of numbers.

I have a very simple setup,

1x XBee Series 2 (Coordinator API)

1x XBee Series 2 (Router AT)

2x XBee Shields

1x XBee Arduino MEGA

1x XBee Arduino UNO

So, the Coordinator XBee is mounted onto the MEGA with the Shield and the Router XBee onto the UNO.

On both Arduino MEGA and UNO, two jumper wires criss cross the TX and RX so that the TX is connected to the RX on the Shield and vice versa RX to TX.

On the Arduino MEGA, I connected the XBee Series 2 (Coordinator) pin 6 to pin 10 of the Shield (RSSI in PWM).

The x-CTU settings are shown on the tutorial videos itself and the codes as well. I am wondering why dosent it shows the RSSI? I have tried reading it in HEX but to no avail. Is there something wrong with my setup or is there a better way to go about getting RSSI readings from AT to API?

*Reason why I am using API is because I may need it to do mesh topology with many other router ATs

Thank you very much for taking your time in reading this.

I will appreciate any kind of help as I have been trying to solve this for a month now.

In order for the RSSI pwm signal to be updated it needs to have received an API packet. Also, for the series 2 Xbee this applies only for the last hop of the packet, so from last router to destination (your coordinator I presume). So make sure you receive something from the other Xbee first.

As for the code, it works only on the Mega. It can’t work on the Uno because of lack of additional serialports. Also that code makes very crude attempts (bad really) to sync to a received API packet. As it does not check what sort of API packet it is, or what it means. Not all API packets coming out of the serial port are because of a received transmissions. Basically it waits until a bunch of data is put into the serial buffer. Flushes some of it if it encounters the API packet header, and only then measures the pulse length of the RSSI PWM with pulseIn, on the assumption that it happens.

Hi Valen! I have tried experimenting with a Coordinator AT and Router AT and a code to send “Hello World!” from the Router to the Coordinator and this works.

After that, I tried a Coordinator API and Router AT and again to send “Hello World!” from Router to Coordinator. The message relayed was in API packet forms and I received the start byte all the way to the checksum without problems.

Now for the RSSI PWM Signal, I only used Uno to power up my XBee Series 2 (Router AT), is there a code for the Router AT to force it to send only the RSSI?

For the tutorial codes I am using for MEGA, and it seems mine is not working as well as the guy in the tutorial video :(. You have discussed this issue with donaldhwong on another post before but it seemed that he can get it working too at the end.

For reference, some information about his issues is found at the end of this thread. (contains code)

https://forum.sparkfun.com/viewtopic.php?f=13&t=40119

jysgymg:
… Now for the RSSI PWM Signal, I only used Uno to power up my XBee Series 2 (Router AT), is there a code for the Router AT to force it to send only the RSSI?

I have not read the Series 2 manual from back to front intensively. (I don’t have one, so have no need for it either. Trying to help here I am sometimes tempted to do quick searches in the hope of finding the solution. But ultimately you should read it entirely) So I do not know if there is a way. A RSSI can only be measured by the receiving module, as it is the strength of the received RF signal. It is not part of the transmitted data. You can request the last value from the receiving Xbee with an API packet or AT command.

For the tutorial codes I am using for MEGA, and it seems mine is not working as well as the guy in the tutorial video :(. You have discussed this issue with donaldhwong on another post before but it seemed that he can get it working too at the end.

You have as much information available as I do how he fixed his issue. I do not engage in private email conversations to help people fix something because that prevents others from learning from it. I want it to be public. Read his last replies in that thread. It was a wrong value in the RP register. Other than that I don’t know what could be your cause. Make sure you check if that RSSI pin of the Xbee actually sends out pulses. And if not, then you know why the program does not work. If there is a led connected to it you might see a blink, or intensity changes. Otherwise you might have luck seeing a voltage change with a voltage meter (not a big change since it is of short duration and the meter averages slowly). Or try to get some sort of oscilloscope reading from it.

Yes, I did followed donaldhwong’s steps regarding the RP hops register (mine was already set to 28 as a default value). I will stop posting on the other thread as well as it may cause confusion (my bad). I will use an oscilloscope to see if there are any PWM pulse but assuming it has PWM wave, what part of my codes I should change to include the RSSI value? What will happen to the Serial.println? I will post the codes below for everyone else ease.

So I will try to screenshot an output of the Serial Log and paste it here as well. It seems that I get a reading of 0 (RSSI) about 99% of the times. The other 1% however, I may get a “Zone 1” with a number (ranges from 5-12?). Does this means I am actually able to read the RSSI but maybe the bytes are too short?


Arduino Codes (Mostly from the tutorial Video, just a few minor tweaks):

/*

XbeeRSSI.pde

This is a sketch for RSSI-Measurements. The sketch reads the incoming RSSI Value and turns on a LED if the Signal is strong enough.

Please note that the used Value (40) depends on your project environement.

ATTENTION!!!


YOU HAVE TO USE AN ARDUINO WITH AT LEAST TWO SERIAL PORTS!

I am using an Arduino MEGA!

Connect your Xbee RX to Arduino RX!

Connect your Xbee TX to Arduino TX!

And don’t forget the power supply!

RSSI Pin on Xbee → 6


Author: Cédric Portmann (cedric.portmann@gmail.com.)

Copyright (C) 2013 Cédric Portmann

*/

int digitalPin = 10; // the RSSI pin 6 of Xbee is connected to this PWM Pin. (Digital Pin 10)

int rssiDur; // Variable for RSSI

int led = 13; // LED connected to Pin 13

void setup()

{

pinMode(led, OUTPUT);

pinMode(digitalPin, INPUT);

Serial.begin(9600); // this is the connection for your Arduino to your PC/MAC

Serial3.begin(9600); // this is the connection of your Xbee to your Arduino MEGA!!

}

void loop()

{

if(Serial3.available() >= 21) { // This isn’t important. You can do here whatever you want.

if(Serial3.read() == 0x7E) { // Reads the start byte

for(int i = 1; i < 50; i++) {

byte discardByte = Serial3.read();

rssiDur = pulseIn(digitalPin, LOW, 200); // get’s the RSSI Value

Serial.println(rssiDur); //for debbuging and first setup.

if(rssiDur < 40 && rssiDur != 0){ //turns Led on if RSSI is less then 40

digitalWrite(led, HIGH);

Serial.println(Zone 1);

}

if(rssiDur > 40 && rssiDur != 0){ //turns Led off if RSSI is bigger then 40

digitalWrite(led, LOW);

Serial.println(Zone 2);

}

}

delay(1000);

Serial.println();

}

}

}

jysgymg:
…What will happen to the Serial.println? I will post the codes below for everyone else ease.

I presume you mean these ones?
Serial.println(Zone 1);

Serial.println(Zone 2);

The compiler will not understand what Zone means, and why there is a space with a number behind it. It will print one or more compiler error or warning in the compiler log and will get stuck and fail trying to write the machinecode for the Arduino. So whatever is running inside your Arduino now is from a succesfull compile at an earlier moment. If you just intend to print the text “Zone 1” or “Zone 2” then you forgot to encase them in double quotes " ".

Please fix that first so we can be sure the behavior that the arduino exhibits matches with the code you wrote for it now. Once you have a successful compile and upload post the code and a description of how it behaves and a log of the serial monitor messages.

See the attached image what happens when I try to compile your code. It does not succeed.

Oddly enough the compiler complains about Zone 2 first, even though it comes a few lines later in the code. Once I encase it as “Zone 2” and recompile it complains about the line with Zone 1 also. This prevents your code from being compiled and uploaded to the Arduino.

Ahh,

I may have misplaced the 2 " " for the println.

if(rssiDur < 40 && rssiDur != 0){ //turns Led on if RSSI is less then 40

digitalWrite(led, HIGH);

Serial.println(“Zone 1”);

}

if(rssiDur > 40 && rssiDur != 0){ //turns Led off if RSSI is bigger then 40

digitalWrite(led, LOW);

Serial.println(“Zone 2”);

}

So it is supposed to print Zone 1 and Zone 2 literally if the RSSI values are below 40 or above 40 respectively. Sorry for the small issue as I was playing around with the codes and may have copied the wrong one.

I am about to screenshot some of my results over and see if my setup makes sense.

Once again, thank you very much for being with me!

I have attached a Screenshot of the result I get in Arduino.

I was wondering why my frame bytes do not start with 0x7E.

The RSSI values still prints 0, I will update the newer version of the codes below.

I have change nothing vital except for adding a new for loop to print out the API frames in HEX.

Is there something wrong with the codes? Or maybe X-CTU settings?

Oh, and a happy valentine’s day everyone!

Codes:

/*

XbeeRSSI.pde

This is a sketch for RSSI-Measurements. The sketch reads the incoming RSSI Value and turns on a LED if the Signal is strong enough.

Please note that the used Value (40) depends on your project environement.

ATTENTION!!!


YOU HAVE TO USE AN ARDUINO WITH AT LEAST TWO SERIAL PORTS!

I am using an Arduino MEGA!

Connect your Xbee RX to Arduino RX!

Connect your Xbee TX to Arduino TX!

And don’t forget the power supply!

RSSI Pin on Xbee → 6


Author: Cédric Portmann (cedric.portmann@gmail.com.)

Copyright (C) 2013 Cédric Portmann

*/

int digitalPin = 10; // the RSSI pin 6 of Xbee is connected to this PWM Pin. (Digital Pin 10)

int rssiDur; // Variable for RSSI

int led = 13; // LED connected to Pin 13

void setup()

{

pinMode(led, OUTPUT);

pinMode(digitalPin, INPUT);

Serial.begin(9600); // this is the connection for your Arduino to your PC/MAC

Serial3.begin(9600); // this is the connection of your Xbee to your Arduino MEGA!!

}

void loop()

{

if(Serial3.available() >= 21) { // This isn’t important. You can do here whatever you want.

if(Serial3.read() == 0x7E) { // Reads the start byte

for(int i = 1; i < 23; i++) {

// byte discardByte = Serial3.read();

Serial.print(Serial3.read(), HEX);

Serial.print(“,”);

}

Serial.println();

for(int j = 1; j < 23; j++) {

rssiDur = pulseIn(digitalPin, LOW, 200); // get’s the RSSI Value

Serial.println(rssiDur); //for debbuging and first setup.

}

if(rssiDur < 40 && rssiDur != 0){ //turns Led on if RSSI is less then 40

digitalWrite(led, HIGH);

Serial.print(“Zone 1”);

}

if(rssiDur > 40 && rssiDur != 0){ //turns Led off if RSSI is bigger then 40

digitalWrite(led, LOW);

Serial.print(“Other Zones”);

}

}

delay(1000);

//Serial.println();

}

}

//}

Hey everyone!

First off, I would like to thank Valen for his constant replies in trying to solve my question.

I may have found a solution to my problem but I have encountered more questions.

I have found out that my codes and hardware actually works to get RSSI values from 2 XBee Series 2. The only problem was that when I was working with them, both of the XBees were connected to my laptop so they were approx <2m away from one another. This is the reason that it always spark the 0 readings for the RSSI.

Accidentally, I moved 1 of the XBee away when I was using an oscilloscope to try and see if I can get the PWM pulse and VOILA! I actually saw readings of the RSSI! BUT!!!

Here, it spark a few question:

  1. Why is it that when the XBees are closed to one another, the RSSI values produced are always 0? I read on so many articles and tutorials where RSSI values are never 0 even at close range.

  2. There is a fluctuation of the range of RSSI values (like from 4 to 28) even when both XBees are rooted at one location (no change in distance, height or orientation), why is this so?

  3. Even at the same distance, there will be readings of 0, and from 4 to 28. Sometimes there may occur a period of long readings of 0s and I may touch the Arduino boards (moving it a little up and down, left and right or turning it around orientation wise) and it spark a little reading of RSSI values (also from 4 to 28).

  4. And lastly, I am still unsure of what the HEX numbers are telling me. It dosent start with 0x7E (start byte) and I read from this link: http://www.digi.com/support/forum/35318 … ignal-rssi

that the RSSI values can be read from the HEX bytes frame. Could someone also tell me how to get the correct byte frame?


I will attach some pictures of my results. Basically I have only tested from 1m(readings of 0) to <4m (readings of 0 - 28).

I will also copy and paste the current codes that I am playing with. I will update regularly on the RSSI readings and experiments.

Cheers!

Codes:

/*

XbeeRSSI.pde

This is a sketch for RSSI-Measurements. The sketch reads the incoming RSSI Value and turns on a LED if the Signal is strong enough.

Please note that the used Value (40) depends on your project environement.

ATTENTION!!!


YOU HAVE TO USE AN ARDUINO WITH AT LEAST TWO SERIAL PORTS!

I am using an Arduino MEGA!

Connect your Xbee RX to Arduino RX!

Connect your Xbee TX to Arduino TX!

And don’t forget the power supply!

RSSI Pin on Xbee → 6


Author: Cédric Portmann (cedric.portmann@gmail.com.)

Copyright (C) 2013 Cédric Portmann

*/

int digitalPin = 10; // the RSSI pin 6 of Xbee is connected to this PWM Pin. (Digital Pin 10)

int rssiDur; // Variable for RSSI

int led = 13; // LED connected to Pin 13

void setup()

{

pinMode(led, OUTPUT);

pinMode(digitalPin, INPUT);

Serial.begin(9600); // this is the connection for your Arduino to your PC/MAC

Serial3.begin(9600); // this is the connection of your Xbee to your Arduino MEGA!!

}

void loop()

{

if(Serial3.available() >= 21) { // This isn’t important. You can do here whatever you want.

if(Serial3.read() == 0x7E) { // Reads the start byte

for(int i = 1; i < 22; i++) {

// byte discardByte = Serial3.read();

Serial.print(Serial3.read(), HEX);

Serial.print(“,”);

}

Serial.println();

for(int j = 1; j < 19; j++) {

byte discardByte = Serial3.read();

rssiDur = pulseIn(digitalPin, LOW, 200); // get’s the RSSI Value

Serial.println(rssiDur); //for debbuging and first setup.

}

// if(Serial3.available() > 21) {

// if(Serial3.read() == 0x7E){

// for(int i=0; i<21; i++) {

// Serial.print(Serial3.read(),HEX);

// Serial.print(“,”);

// }

// delay(1000);

// Serial.println();

// }

if(rssiDur < 40 && rssiDur != 0){ //turns Led on if RSSI is less then 40

// digitalWrite(led, HIGH);

Serial.print(“Zone 1”);

Serial.println();

}

if(rssiDur > 40 && rssiDur != 0){ //turns Led off if RSSI is bigger then 40

// digitalWrite(led, LOW);

Serial.print(“Other Zones”);

Serial.println();

}

}

}

}

//}

4: It doesn’t print the hex 7E because it doesn’t print it. Once the Serial3.read() == 0x7E statement is true it is ignored. Serial.read consumes the byte, it takes it from the buffer. If you don’t do anything with it, like store it in a variable or something, then it is lost.

In the link, the top answer says how you get a RSSI return in an API packet. It says if you first use a certain API packet sequence you get an answer back. But to know why you first need to understand what sort of API packet the first one is. You can decode the api packet with the modern XCTU application. Not the old one. Or just dive into the manual and interpret those hex numbers by yourself. RTFM

Oh, I will try removing the 7E statement and see what happens.

Anyways, for the distances, I send the same packet from my coordinator API to my router AT in X-CTU console log. The router sends back a frame that does include the RSSI values (from the link it says the data will be the last 2 HEX digits before checksum). However, my arduino serial log only shows 0 RSSI when it should be a range of numbers at close distance. Is there a problem with the codes?

I don’t think that will improve anything. If you want to see the 7E in the serial monitor then I suggest you insert a Serial.print statement that does print it when it is encountered. Removing the part ```
Serial3.read() == 0x7E


The major problem I have with that code is that it assumes the packets are of a fixed length. It doesn't look at the actual size of the packets and dumps it in it's entirety, or figure out how far away the RSSI value is after the 7E. It never takes the 2 bytes following the 7E and turns that into a packet-length. Which the for-loop could use to show all the bytes of the packet that come behind. If an unexpected packet comes along that does not fit the hardcoded length then you'll get corrupted data. Or you'll skip a packet.

Hi Valen,

Sorry, had been busy with an event over the weekends and I am back to this project haha.

What do I do to read the entire “correct” packet sent by my Router AT? Do I increase the For Loop count?

So if I take away the line Serial3.read() == 0x7E, will other “unknown” datas be printed instead of the 0x7E?

And yes, when I change my for loop to the normal 19,20,21,22, it gives FFFFFFFF, FFFFFFFF

It is like it deleted the bytes at the end which is absurd.

When I program the XBees Series 2 to this:

void setup()

{

Serial.begin(9600);

Serial3.begin(9600);

}

void loop()

{

if (Serial3.available()>=21){

for(int i=0;i<22;i++){

Serial.print(Serial3.read(),HEX);

Serial.print(“,”);

}

Serial.println();

}

}

It reads all 22 api frames from start delimiter to checksum.

Its like the code discarded half of the frames. Like the even half of the frames leaving only the odd half behide.

22-byte frames:

7E,0,12,92,0,13,A2,0,40,E7,79,DB,70,9E,1,1,0,0,8,2,9,1A

My byte frames:

7E,12,0,A2,40,79,70,1,0,8,9,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,

See how the “even” bytes are taken out?

I dont know if its the cause of the weird RSSI readings, but I am not going to do a distance test with what I have. I am doubting alot on the values though. Will screenshot and update ASAP.

Hi just to update,

it seems that the distance may or may not affect the “RSSI” values that are printed onto the Serial Log. (yup, the open inverted commas as I am still unsure if its really the RSSI values).

Another experiment I did is that when I actually blocked the Line of Sight(LOS) of the 2 XBees, there were actually values. I also did hook it up to an oscilloscope and it showed a PWM signal. So, I did many funny things like using my body to block LOS, used my hand to block the antenna at touching distance, using my hands to block the LOS etc… and all of these actually resulted in values shown onto the Serial Log.

And its always random, it ranges from 8 to 110! But mostly the numbers are between 8 to 21.

I am certain this is not the RSSI signal? Or I am reading something wrong or coding something wrong.

Going to continue researching and experimenting now. Wish me luck.

Have you read the Xbee manual? It explains how the API packets are structured. I already said what needs to be done with the bytes following ‘7E’. They make up the length. That tells you how long the for loop should read bytes of the packet. But it should not dumb read the data. It should look what those bytes are and check if they are the specific values that are important for it.

There are a few libraries for Arduino that interpret Xbee API packets. I suggest you use them. If you are serious in wanting to learn how to program you also try to learn the basics about if-statements and for- or while-loops. Without them you’ll not get very far. Learn what the code does by taking each line step-by-step and do in your mind (or better on paper) what the arduino is doing. That is how I started and what I am still doing when I am trying to help people here.

Hi Valen and all,

First of all, I have gotten the RSSI values with range experiments. They seem to fluctuate a lot.

Valen:
Have you read the Xbee manual? It explains how the API packets are structured. I already said what needs to be done with the bytes following ‘7E’. They make up the length. That tells you how long the for loop should read bytes of the packet. But it should not dumb read the data. It should look what those bytes are and check if they are the specific values that are important for it.

There are a few libraries for Arduino that interpret Xbee API packets. I suggest you use them. If you are serious in wanting to learn how to program you also try to learn the basics about if-statements and for- or while-loops. Without them you’ll not get very far. Learn what the code does by taking each line step-by-step and do in your mind (or better on paper) what the arduino is doing. That is how I started and what I am still doing when I am trying to help people here.

I think after reading other forums as well as more thesis and tutorials, after doing some experiments with RSSI values, the RSSI is either:

  1. Not very accurate, as the results fluctuates in that specific distance. For example, for 5m, it fluctuates from 4 to 28. 10m would be around 8 to 36 and so on. There are overlaps of the RSSI values.

  2. I could be reading something else entirely! For now I am only using the pulseIn() function so I am not sure if this is really RSSI. There are formulas to calculate the RSSI but I just got the experimental results so I have not conclude this part yet. For now, what the results show is that these RSSI values do increase when distance increase and if the XBee (Router AT) is blocked by a wall or anything.

  3. Wrongly read. In this case, maybe I have made some wrong connections here and there. The manual do states that there will be RSSI value in the API frame but I cant seem to get that specific frame. Also the XBee library is not helping me as I am stuck at calling the functions out (no idea why, maybe someone can enlighten me on this), like for example if I were to type

//

if(xbee.getResponse().isAvailable()){

Serial.print(“I am here”);

}

//

This dosent work but if i type

//

if(Serial3.available() > 21) {

if(Serial3.read() == 0x7E){

Serial.print(“I am here”);

}}

//

and it does work.

Just an update for everyone and also if anyone has any recommendations or comments, do feel free to post them. I may be coming to the end of my Project soon.

Cheers!

Other things being equal, the RSSI value depends much more strongly on relative antenna orientation and absorption or interference effects than it does on distance, so it is nearly useless as a distance measure.

There are exceptions under very carefully controlled circumstances, of course.