How to measure XBee signal strength?

I have looked for about a week now and can't figure out how to get any form of signal strength indication. I basically need to press a button from one Arduino and return the signal strength in any useable fashion so that I can map it to 3 LEDs. Good, average, and poor. I have tried the pulseIn function along with sending AT commands. I can't find a straight forward guide on how to get API mode working to pull the RSSI value from that packet strand. I am using two XBee Pro S2B. Any help on how to do this would be greatly appreciated.

Did you see this section in the datasheet?

RSSI Indicators
It is possible to measure the received signal strength on a device using the DB command.
DB returns the RSSI value (measured in –dBm) of the last received packet. However, this
number can be misleading. The DB value only indicates the received signal strength of the
last hop. If a transmission spans multiple hops, the DB value provides no indication of the
overall transmission path, or the quality of the worst link – it only indicates the quality of
the last link and should be used sparingly.

On the S1 modules, you just send

+++
ATDB

and it sends back the RSSI value.

oric_dan:
On the S1 modules, you just send

+++

ATDB



and it sends back the RSSI value.

Ditto for the S2 modules. Also works in API mode of course.

How does this work? I can do this easily in the X-CTU terminal. I type +++ and it replies OK then I type ATDB, hit enter, and it replies with a hex number. This is not happening in the Arduino terminal. Am I allowed to put this in the loop section of the the code? I don't mind doing it this way, but I can't get any code to work trying to enter the +++ mode.

Edit: To be clear, I open the serial monitor of the Arduino and in the top line type +++ and hit send and I get no response no matter what I do. In fact it sends over to the other terminal on XCTU.

Khamey:
How does this work? I can do this easily in the X-CTU terminal. I type +++ and it replies OK then I type ATDB, hit enter, and it replies with a hex number. This is not happening in the Arduino terminal. Am I allowed to put this in the loop section of the the code? I don't mind doing it this way, but I can't get any code to work trying to enter the +++ mode.

Edit: To be clear, I open the serial monitor of the Arduino and in the top line type +++ and hit send and I get no response no matter what I do. In fact it sends over to the other terminal on XCTU.

How are things connected? Are the XBee and Arduino both connected? If so, there's an issue. Serial comm is a two-device arrangement, not three (PC, Arduino, XBee). Probably the TX signals from both the PC and the XBee are connected to the Arduino's RX pin, and the Arduino's TX pin is connected to both the PC's RX and the XBee's RX. So typing on the serial monitor will go to the XBee's TX pin, where it will not see it.

That made a lot of sense what you pointed out. Basically at some button press I want to be able to send a packet, get a ping back, and then display the signal strength of that ping. I have the XBee connected to pins 2 and 3 of the Arduino through software serial. What you're saying is that when I type +++ into the serial monitor of the arduino that goes into my char variable straight to the Tx pin and the Rx pin is the on that needs to see it?

Khamey:
That made a lot of sense what you pointed out. Basically at some button press I want to be able to send a packet, get a ping back, and then display the signal strength of that ping. I have the XBee connected to pins 2 and 3 of the Arduino through software serial. What you're saying is that when I type +++ into the serial monitor of the arduino that goes into my char variable straight to the Tx pin and the Rx pin is the on that needs to see it?

Well if the XBee is on 2 and 3, the hardware serial interface is pins 0 and 1, this is what the serial monitor connects to. So with that arrangement, the XBee isn't even in the picture. Characters entered via the serial monitor are presented on the Arduino's pin 0. When the Arduino transmits to the serial monitor, it does so on pin 1.

Here is an API-mode function I use to get the RSS. The XBee is connected to the hardware serial interface. I've truncated the two switch statements in loop() to the bare minimum, it compiles but will need to be fleshed out for your particular application. I know that the latest version of the XBee library allows use of software serial, but I have not tried this, I've always used the hardware serial interface.

#include <XBee.h>                  //http://code.google.com/p/xbee-arduino/
#include <Streaming.h>             //http://arduiniana.org/libraries/streaming/

//XBee variables
XBee xbee = XBee();                //XBee object
ZBRxResponse rx = ZBRxResponse();  //XBee receive response

void setup(void)
{
    Serial.begin(115200);
}

void loop(void)
{
    xbee.readPacket();

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

        switch (xbee.getResponse().getApiId()) {           //what kind of packet did we get?
    
        case ZB_RX_RESPONSE:                               //rx data packet
            xbee.getResponse().getZBRxResponse(rx);        //get the received data
            switch (rx.getOption()) {
            case ZB_PACKET_ACKNOWLEDGED:
                Serial << "Packet received, RSS = -" << _DEC(rss()) << " DB" << endl;
                break;
            }
        }
    }
}

/*-----------------------------------------------------------------------*
 * returns received signal strength value for the last RF data packet.   *
 *-----------------------------------------------------------------------*/
uint8_t rss() {

    uint8_t atCmd[] = {'D', 'B'}, respLen, *resp, dBm;
    AtCommandRequest atCmdReq;
    AtCommandResponse atResp;

    atCmdReq = AtCommandRequest(atCmd);

    xbee.send(atCmdReq);
    if (xbee.readPacket(10)) {
        if (xbee.getResponse().getApiId() == AT_COMMAND_RESPONSE) {
            xbee.getResponse().getAtCommandResponse(atResp);
            if (atResp.isOk()) {
                respLen = atResp.getValueLength();
                if (respLen == 1) {
                    resp = atResp.getValue();
                    dBm = resp[0];
                    return dBm;
                }
                else {
                    Serial << "RSS LEN ERR" << endl;    //unexpected length
                }
            }
            else {
                Serial << "RSS ERR" << endl;            //status not ok
            }
        }
        else {
            Serial << "RSS UNEXP RESP" << endl;         //expecting AT_COMMAND_RESPONSE, got something else
        }
    }
    else {
        Serial << "RSS NO RESP" << endl;                //timed out
    }
}

I appreciate the thoughtful response, but I am not in API mode currently. This is something I will look into eventually but AT has been the easiest for me to set up and get a functioning program. The way I see it, is getting API to a working state is at least another 20 hours of work on my end to get to the same point I am at now. Really all I want to do is press a button, notice the button is pressed, send the XBee into command mode, send ATDB through the Arduino and then get that hex number. I will look into your API comments when I have more time. Is there anyone who has experience reading the RSSI value as a PWM?

Edit: Jack if you have some or know of easy to follow API mode tutorials for XBee Pro S2B I would gladly take a look at them. It seems that the information is just really hard to find and took me about 20 hours to get the two connected basically by tinkering and finding bits and pieces around the internet.

There are good API examples that come with the XBee library. I won't kid you, there is a learning curve, but it looks the worst from the foot of the hill and it pays off big time once you're up and through it. Start simple and slow. Seriously the examples are good. Just send "Hello world" or whatever. Be sure to get the doc files for the library. The library is extensive, there is an object model to learn. That's how I learned though, mostly from the examples that come with the library and a fair amount of time in the doc files, which I continue to refer to. Oh and don't forget the XBee product manual, I always have that near.

I'm the first to admit that I am a huge API-mode bigot, but once you're there, AT mode just seems super clunky. Having to send +++ then wait etc. etc. seems sooo inefficient. Being able to just code the destination address into a packet and send it is indispensable for multi-node networks. With AT mode, it would again require getting into command mode, changing the DH and DL parameters, etc. etc. Ugh!

I've used pulseIn() to measure the PWM signal, and it works, but again it seems like the hard way to do it. Have to dedicate an MCU pin and so forth. Seems much more straightforward to just ask the XBee and have it respond with the number!

OK I'm on a roll now. Sorry about that. Have fun, good luck!

Khamey:
How does this work? I can do this easily in the X-CTU terminal. I type +++ and it replies OK then I type ATDB, hit enter, and it replies with a hex number. This is not happening in the Arduino terminal. Am I allowed to put this in the loop section of the the code? I don't mind doing it this way, but I can't get any code to work trying to enter the +++ mode.

Edit: To be clear, I open the serial monitor of the Arduino and in the top line type +++ and hit send and I get no response no matter what I do. In fact it sends over to the other terminal on XCTU.

I never use the Arduino IDE Serial Monitor for most RS232 tasks, because you have to
press Enter before it sends the data from the keyboard. However, every other Terminal
Emulator should work with direct comms to the XBee modules. Certainly XCTU will.

Khamey:
That made a lot of sense what you pointed out. Basically at some button press I want to be able to send a packet, get a ping back, and then display the signal strength of that ping. I have the XBee connected to pins 2 and 3 of the Arduino through software serial. What you're saying is that when I type +++ into the serial monitor of the arduino that goes into my char variable straight to the Tx pin and the Rx pin is the on that needs to see it?

This is another problem that I've mentioned on 4 or 5 threads in the just the past week or so.
Basically trying to use an XBee shield on a UNO or other board with only 1 h.w. UART and
SoftSerial is about as easy as eating worms. I've never had any luck at all using SoftSerial, and
almost all of the avialable XBee shields have major issues with very poor design. Maybe Jack's
suggestions will work, but just getting past the h.w. setup issue is a big PITN.

I have a working program and hardware for my XBee Pro S2Bs using one connected through USB explorer operating the X-CTU terminal and one connected to an Arduino UNO running a loop. I can send and receive data fine from both the laptop and the Arduino. Basically the last goal I have is to get some sort of RSS. It is literally the last thing I need to do. I don't disagree API is better and much more elegant, but it seems much more difficult and I am in a little bit of a time constraint. I really wish I had series 1 seeing as all I wanted to do was point to point. Setting up point to point with the supplies available was hard enough and I'm just trying to put the last piece of the puzzle in. It doesn't have to be elegant and it doesn't need to be flawless this is just a proof of concept that I will have time later to refine where I will learn API mode and change all the code to that.

Jack do you remember how you did the pusleIn to get the pulse from the RSSI pin? It seems like its only on or off for me and it only returns 0's in the serial monitor. There is one line of code on log.linmena something like that that has zero details. I need to know which pin to hook into what variables to declare. Seriously tried everything I know and I don't get anything other than zeroes. Maybe I could be implementing my code wrong?

one connected to an Arduino UNO running a loop.

This makes it a lot easier, if you're not trying to do s.w. dev and XBee comms
simultaneously. Hopefully, your shield has 5V-to-3.3V level-shifters.

I've worked with XBees for 8 or 9 years now, and never needed to use the API,
and only ever used the AT commands.

All you have to do is, inside your loop, once a message is received from the host
node, rather than replying immediately, simply send +++ and ATDB out the serial
port and the XBee will interpret this as a command and reply with the RSSI signal.
Then read it using Serial.available() and Serial.read(), and transmit the data to the
host. Simple. Make sure the host delays a bit to give the remote time to do the op.

Khamey:
Jack do you remember how you did the pusleIn to get the pulse from the RSSI pin?

It was this simple. Note this was a S1 XBee, check the S2 product manual, the PWM period is different IIRC:

#define RSSI_PIN 2					//connect to the XBee RSSI pin
#define PWM_PERIOD 64					//XBee RSSI PWM period in µs per the XBee 802.15.4 Product Manual
unsigned long pulseWidth;					//the XBee RSSI pulse width reading from pulseIn
pulseWidth = pulseIn(RSSI_PIN, LOW, PWM_PERIOD);	//read the rssi pulse width, give up after 64ms

oric_dan:
This is another problem that I've mentioned on 4 or 5 threads in the just the past week or so.
Basically trying to use an XBee shield on a UNO or other board with only 1 h.w. UART and
SoftSerial is about as easy as eating worms. I've never had any luck at all using SoftSerial, and
almost all of the avialable XBee shields have major issues with very poor design. Maybe Jack's
suggestions will work, but just getting past the h.w. setup issue is a big PITN.

I haven't tried an XBee shield, but we do seem to see our share of issues with them here on the forum.

For prototyping, AFI's adapter boards work great for me, just plugged into a breadboard. Hook up power, ground, RX and TX and it's good. To upload a new sketch, I pull the jumper from the XBee to the Arduino RX pin. On custom boards, I implement the same concept with a three-pin header and a shorting block. Like I said, this is all just using HW serial.

For prototyping, AFI's adapter boards work great for me,

Of all the adaptors and shields, those are probably the safest design around,
and the least likely to blow up your 3.3V XBee modules.

However, they could be improved significantly by adding series-Rs [470-1000 ohm]
in the Dout and CTS lines. This way, if you accidentally connect TX from the Arduino
to Dout, you won't blow the Dout pin. Also, some XBee-plug-alike modules use the CTS
pin as an input, and RTS as output nowadays.

I am using the adafruit adapter kits XBee Adapter kit [v1.1] : ID 126 : $10.00 : Adafruit Industries, Unique & fun DIY electronics and kits. Like I said I have Tx and Rx connected to the Arduino pins 2 and 3 using the software serial library and 5V to 5V and GND to GND. Should I be using the Tx and Rx pins to pins 0 and 1 of the arduino and forgetting the software serial library all together? Can i still program and troubleshoot with the xbee plugged into these two pins. I remember vaguely a friend having trouble programming while those pins were occupied. Oric what you are saying is what I want to do. I'm not too concerned about the time lost checking this, but what you have responded is mostly what I have found on the internet. Very vague and I can't figure out why it isn't applying to my solution.

Thanks for all your responses. I really feel helped =)

As I mentioned, I've never had any luck whatsoever using SoftSerial. Maybe Jack is luckier.

What I would try doing, at least to get things to work, is connecting the XBee to pins 0,1
[Rx,Tx] and using the Serial.read()/etc commands, and not SoftSerial. You will have
to disconnect the XBee, connect USB, upload the sketch, and then disconnect USB, and
reconnect XBee. It's a PITN, however this will "definitely" work with a UNO board.

Once you have that, then you can try SoftSerial, or whatever else. Better than wasting
another week on this.

Thanks so much. Any simple example code for how to properly do the delays and what not for "+++" and "ATDB" in the loop? I think the issue is the SoftwareSerial after this discussion. Everything is on a breadboard so no worries about plugging and unplugging.

I haven't tried software serial with an XBee, like I said only fairly recently has the library been upgraded to work with it. Paul Stoffregen certainly knows what he's about though.

Still, and this is not a comment on the latest XBee library (after all, I haven't even tried it), it may be more straightforward to use the hardware serial for the XBee and software serial for debugging messages. I'd definitely want the advantages of the hardware port for the more critical of the two purposes which is the XBee.

But here is another advantage of API mode. Since when in API mode the XBee ignores any input that doesn't start with the 0x7E (~) frame delimiter, I can use the hardware serial port to output all manner of debug prints as long as I don't send the delimiter, which is no limitation whatsoever! I do this all the time. The debug messages get interspersed with packets the µC sends to the XBee, but with low data rates to the XBee, this is not a problem for me. The only real issue is uploading a new sketch, the connection between the XBee TX (Dout) line and the Arduino RX pin needs to be broken to allow the upload, so that two devices (the PC and the XBee) aren't simultaneously trying to talk to the µC.