Xbee protocol

I have 2 Xbeee 900 pro units. All seems to work as advertised using Xctu.

I now am using an Arduino Duemilanove, Softwareserial to the Xbee, and normal uart to laptop. The second Xbee is sending a data packet at 5-second intervals,( both are in API-mode) which I am able to interpret, and display the analogue and digital signals ... no problem.

What I would like to acheive, is to be able to send remote AT commmands, from the Arduino's Xb to switch LEDs and things on the remote ..... I can do this with XCTU perfectly well, but cannot get it right when using the Arduino to send the data-package. I have copied the message which Xctu says it sends exactly, and get nowhere.

Does anyone have more info for me with regards the format of remote AT commands when in API mode ??

I have tried to follow the examples in the XBEE Library, but there is too much there which I don't clearly understand .... for example, what does "Xbee.loop();" do ? and where can i find this.

Cheers, Charles

Does anyone have more info for me with regards the format of remote AT commands when in API mode ??

If the XBee is in API mode, sending AT commands doesn't make sense. Why do you feel the need to use API mode? Is the XBee reading/writing digital or analog data directly?

Hi Paul. Yes, the remote Xb is sending regular digital and 3 analog samples. I am receiving these flawlessly both via Xctu and via a sketch on my arduino board - using newsoftwareserial -on pins 3 & 2. What I need to achieve is to change parameters - like sample interval - on the remote unit, using the Arduino sketch. I can do this with Xctu, and have copied the exact frame Xctu sends into the sketch, and send it ... no action ... I do not even get a response of any sort from the Xb.

I really appreciate your help

I can do this with Xctu, and have copied the exact frame Xctu sends into the sketch

I must have missed that part of your code. The fact that you haven't posted any code probably explains why I missed it.

I have a drawer full of XBees...

This is what I have tried …

[code]
#include <Printers.h>
#include <XBee.h>

#include <SoftwareSerial.h>

SoftwareSerial nss(3, 2); // RX, TX
char incomingByte = 0;   // for incoming serial data

const int ledPin =  13;            // the number of the LED pin
int ledState = LOW;                // ledState used to set the LED
uint32_t previousMillis = 0;  // will store last time LED was updated
const long interval = 5000;        // interval at which to blink (milliseconds)
int inByte = 0;
uint16_t Length = 0;
uint8_t DataSampleIndicator = 0;
uint8_t SourceAdress64[8];
uint8_t SourceAdress16[2];
uint8_t RxOption = 0;
uint8_t Samples = 0;
uint8_t DigChannelMask[2];
uint8_t AnalogChannelMask = 0;
uint16_t AnaZero;
uint16_t AnaOne;
uint16_t AnaTwo;
uint16_t DigVal;
uint8_t CheckSum = 0;
uint8_t LocalChecksum = 0;
//  Add all bytes (include checksum, but not the delimiter and length).
//  If the checksum is correct, the sum will equal 0xFF.
uint8_t RxData[50];

const uint8_t CmdPumpOn[]    = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x50, 0x31, 0x05, 0x21};
const uint8_t CmdPumpOff[]   = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x50, 0x31, 0x04, 0x22};
const uint8_t CmdTamperOn[]  = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x44, 0x38, 0x05, 0x26};
const uint8_t CmdTamperOff[] = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x44, 0x38, 0x04, 0x27};
const uint8_t CmdWDogOn[]    = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x44, 0x34, 0x05, 0x2A};
const uint8_t CmdWDogOff[]   = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x44, 0x34, 0x04, 0x2B};
const uint8_t OneMin[]       = {0x7E, 0x00, 0x11, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x49, 0x52, 0xEA, 0x60, 0xC2};
const uint8_t FiveSec[]      = {0x7E, 0x00, 0x11, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x49, 0x52, 0x13, 0x88, 0x71};
const uint8_t OneSec[]       = {0x7E, 0x00, 0x11, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x66, 0x1E, 0xC8, 0xFF, 0xFE, 0x02, 0x49, 0x52, 0xE3, 0xE8, 0x41};


void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  Serial.println(" Running");
  nss.begin(9600);
  Serial.println("Ready to receive from Remote");
}

void hexprint(uint8_t v) {
  Serial.print(v >> 4, HEX);
  Serial.print(v & 0XF, HEX);
  //  Serial.print('-');
}
void nssHexprint(uint8_t v) {
  nss.print(v >> 4);
  nss.print(v & 0XF);
}


void loop() {
  unsigned long currentMillis = millis();
  LocalChecksum = 0;

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
    Serial.print(".");
  }

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    Serial.println();
    switch (incomingByte) {
      case 'a':    // Pump LED ON
        Serial.print("Tx a ");
        //       nss.write(CmdPumpOn, 8);
        for (int(i) = 0; i < 20; i++) {
          nssHexprint(CmdPumpOn[i]);
          hexprint(CmdPumpOn[i]);
        }
        break;
      case 'b': // Pump LED OFF
        Serial.print("Tx b ");
        for (int(i) = 0; i < 20; i++) {
          nssHexprint(CmdPumpOff[i]);
          hexprint(CmdPumpOff[i]);
        }
        break;
      case 'c':  // Tamper LED ON
        Serial.print("Tx c ");
        for (int(i) = 0; i < 20; i++) {
          nssHexprint(CmdTamperOn[i]);
          hexprint(CmdTamperOn[i]);
        }
        break;
      case 'd':  // Tamper LED OFF
        Serial.print("Tx d ");
        for (int(i) = 0; i < 20; i++) {
          nssHexprint(CmdTamperOff[i]);
          hexprint(CmdTamperOff[i]);
        }
        break;
      case 'e':  // WatchDog LED ON
        Serial.print("Tx e ");
        for (int(i) = 0; i < 20; i++) {
          nssHexprint(CmdWDogOn[i]);
          hexprint(CmdWDogOn[i]);
        }
        break;
      case 'f':  // WatchDog LED OFF
        Serial.print("Tx f ");
        for (int(i) = 0; i < 20; i++) {
          nssHexprint(CmdWDogOff[i]);
          hexprint(CmdWDogOff[i]);
        }
        break;
      case 'o':  // 1-Minute Cycle
        Serial.print("Tx o ");
        for (int(i) = 0; i < 21; i++) {
          nssHexprint(OneMin[i]);
          hexprint(OneMin[i]);
        }
        break;
      case 'k':  // 5 Second Cycle
        Serial.print("Tx k ");
        for (int(i) = 0; i < 21; i++) {
          nssHexprint(FiveSec[i]);
          hexprint(FiveSec[i]);
        }
        break;
      case 'm':  // 1 Second Cycle
        Serial.print("Tx m ");
        for (int(i) = 0; i < 21; i++) {
          nssHexprint(OneSec[i]);
          hexprint(OneSec[i]);
        }
        break;
      default:
        Serial.println("Tx ? ");
        // if nothing else matches, do the default
        // default is optional
        break;
    }
  }
  //  delay(500);
  if (nss.available() > 0) {
    Serial.println();
    Serial.print("Got Summit !");
    while (nss.read() != (0x7E)) {
    }; // do nothing, wait for 0x7E
    Serial.println();
    delay(100);

    for (int(i) = 0; i < 50; i++) {  // was 30
      if (nss.available() > 0) {
        RxData[i] = nss.read();
      }
    }
    Length = RxData[0];
    Length = Length << 8;
    Length = (Length | RxData[1]);
    for (int(i) = 0; i < (Length + 3); i++) {
      hexprint(RxData[i]);
    }
    Serial.print("  Length = ");
    Serial.println(Length, DEC);
    if (Length > 2) { /// was = 22
      for (int(i) = 2; i < (Length + 3); i++) {
        LocalChecksum = LocalChecksum + RxData[i];
      }
      if (LocalChecksum == 0xFF) {
        if (Length == 24) {
          Serial.println();
          DigVal = RxData[18];
          DigVal = DigVal << 8;
          DigVal = (DigVal | RxData[19]);
          AnaZero = RxData[20];
          AnaZero = AnaZero << 8;
          AnaZero = (AnaZero | RxData[21]);
          AnaOne = RxData[22];
          AnaOne = AnaOne << 8;
          AnaOne = (AnaOne | RxData[23]);
          AnaTwo = RxData[24];
          AnaTwo = AnaTwo << 8;
          AnaTwo = (AnaTwo | RxData[25]);

          Serial.print(DigVal, HEX);
          Serial.print(" / ");

          Serial.print(AnaZero * 2.75, 1);
          Serial.print("mV / ");
          Serial.print(AnaOne * 2.75, 1);
          Serial.print("mV / ");
          Serial.print(AnaTwo * 2.75, 1);
          Serial.println("mV");

        }
      }
    }
    // now to process other responses fron the XB
    if (Length == 18) {  // length of button-press message...
      Serial.println();
      Serial.print("Digital Data = ");
      DigVal = ((RxData[15 + 3]) || (RxData[16 + 3] << 8));
      hexprint(RxData[15 + 3]);
      hexprint(RxData[16 + 3]);
      Serial.print(DigVal, HEX);
      Serial.println();
    }
  }
}

[/code]

That last bit of the sketch .... if Length == 18 ... is where I can see that the remote Xbee message, which is sent on a digital pin-change, arrives as expected.

Cheers, Charles

I have also tried the examples which came with the LIB … Remote AT Command returns the following

Starting...
Sending command to the XBee
No response from radio
Sending command to the XBee
No response from radio
void nssHexprint(uint8_t v) {
  nss.print(v >> 4);
  nss.print(v & 0XF);
}

When you call this function with 0x7E, you are sending '7' and 'E'. Why?

You don't have an nss connected to pins 2 and 3, do you? Why does the SoftwareSerial instance not have a name that reflects what it actually represents?

Aaargh ! That is what happens when you don't pay attention to what you copy-paste-change ... such a dumb mistake. I will change the nss.print to read easier as Xb.print - I had used that as a reference to NewSoftwareSerial, so no, I don't have an nss connected there - just an Xb.

Thanks so much for your input