Arduino to xBee API problem

I am trying to get an Arduino connected to an xBee (Series 2) to send a remote command to another xBee, and get it's I/O pin to blink the LED.

The hardware setup is trivial:
The Arduino ground and 3.3v pins are connected to the coordinator's gnd (Pin 10) and Vcc (1) pins respectively, Arduino pin 5 goes to Din (3), pin 6 goes to Dout (2).
The remote xbee is connected to power and ground, and D0 (pin 20) is connected to an LED through a 150 Ohm resistor.

The firmware setup is right out of Faludi's book - coordinator set to API mode, DH and DL set to the remote xBee's. I've tried both 1 and 2 for API enable. Since I'm not using the xBee library, not sure which one is correct. Remote xbee is setup as a router in AT mode, D0 is set to 4 (low digital).

When I put the coordinator into a USB explorer and fire up the Processing sketch from the Faludi book for the Simple Actuator Network (the one with the swtches) - it works fine - flipping the switch on the screen turns the LED on and off. So I believe the xBees are configured properly.

Here's my Arduino sketch:

#include <NewSoftSerial.h>

NewSoftSerial xbeeser(6,5);  //receive, then transmit

void setup()
{
  Serial.begin(57600);
  Serial.println("Activating");
  
  xbeeser.begin(4800);
}

void loop()
{
  PulsePin('0', xbeeser, 500);
  delay(1000);
}
  
void PulsePin(int PinNumber, NewSoftSerial xbeeSer, int delaytime)
{
  Serial.println("Sending On Command");
  
  setRemoteState(PinNumber, 0x4, xbeeSer); //turn on
  
  delay(delaytime);

  Serial.println("Sending Off Command");

  setRemoteState(PinNumber, 0x5, xbeeSer); //turn off
  
}
  
void setRemoteState(int pinnumber, int value, NewSoftSerial xbeeSer)
{
  SendByteToXBee(0x7E, xbeeSer); //start byte
  SendByteToXBee(0x0, xbeeSer); //high part of length
  SendByteToXBee(0x10, xbeeSer); //low part of length
  SendByteToXBee(0x17, xbeeSer); //remote AT command
  SendByteToXBee(0x0, xbeeSer); //frame ID (no reply)
  
  // 64bit of recipient of recipirnt, or 0xFFFF for broadcast
  SendByteToXBee(0x00, xbeeSer);
  SendByteToXBee(0x00, xbeeSer);
  SendByteToXBee(0x00, xbeeSer);
  SendByteToXBee(0x00, xbeeSer);
  SendByteToXBee(0x00, xbeeSer);
  SendByteToXBee(0x00, xbeeSer);
  SendByteToXBee(0xFF, xbeeSer);
  SendByteToXBee(0xFF, xbeeSer);
  
  //16 bit of recipient, or 0xFFFE if unknown
  SendByteToXBee(0xFF, xbeeSer);
  SendByteToXBee(0xFE, xbeeSer);
  
  SendByteToXBee(0x02, xbeeSer); //apply changes immediately
  
  SendByteToXBee('D', xbeeSer); //command name in ASCII
  SendByteToXBee(pinnumber, xbeeSer); //command name in ASCII
  
  SendByteToXBee(value, xbeeSer); //turn on or off
  
  //checksum
  
  long sum = 0x17 + 0xFF + 0xFF + 0xFF + 0xFE + 0x02 + 'D' + pinnumber + value;
  
  SendByteToXBee(0xFF - (sum & 0xFF), xbeeSer); //calculate checksum
  
  delay(10);
  
  Serial.println("");
  
}

void SendByteToXBee(byte Data, NewSoftSerial xbeeSer)
{
  Serial.print(Data, HEX);
  Serial.print(" : ");
  xbeeSer.print(Data, BYTE);
  
}

Checking the serial monitor, I'm getting the expected results being printed to the screen. But there's no action from the LED at all (the LED is good - connecting it to power lights it right up).

I tried hooking up the arduino with the above sketch to a second arduino set up to just pipe everything from a NewSoftSerial input to the Serial output (just piping from the software serial port to the hardware serial port), and it shows that the data is being correctly sent. So the problem has to be either in my xBee setup (unlikely, as it works with the Processing sketch), or with the way I put together the request frame.

Any advice on what I'm doing wrong would be greatly appreciated.

PS: Here's what I'm seeing on the serial monitor:

Activating
Sending On Command
7E : 0 : 10 : 17 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 4 : 73 : 
Sending Off Command
7E : 0 : 10 : 17 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 5 : 72 : 
Sending On Command
7E : 0 : 10 : 17 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 4 : 73 : 
Sending Off Command
7E : 0 : 10 : 17 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 5 : 72 :

xbeeser is a global instance of the NewSoftSerial class.

  PulsePin('0', xbeeser, 500);

is making a copy of the object and passing it to the PulsePin function. I don't think that that is a good idea. You now have two instance of the NewSoftSerial class, connected to the same pins. Only one NewSoftSerial instance can be active at once.

  setRemoteState(PinNumber, 0x5, xbeeSer); //turn off

Now, you are making another copy. Now, you have three instances tied to the same pins.

  SendByteToXBee(0x7E, xbeeSer); //start byte

Oh, geez. Now there are 4 instances...

If serial data arrives from the remote XBee, which instance is going to deal with the data?

It's not passing by reference? I can re-code with a global variable, but I'm not sure that'll fix the problem, since the data goes out the Arduino's (soft) serial interface correctly - otherwise I wouldn't be able to read it when I hook it up into the second Arduino.

It's not passing by reference?

No, you need to use the & operator/symbol to make that happen. The Arduino IDE can not create function prototypes for functions with reference arguments, so you need to create them manually.

I don't know if fixing this will solve your problem. I kind of doubt it, but it still should be addressed.

Is the data going out from the Processing application the same as the data the Arduino is sending?

PaulS:

It's not passing by reference?

No, you need to use the & operator/symbol to make that happen. The Arduino IDE can not create function prototypes for functions with reference arguments, so you need to create them manually.

I don't know if fixing this will solve your problem. I kind of doubt it, but it still should be addressed.

Ok, changed the program. No, it didn't fix the problem.

Is the data going out from the Processing application the same as the data the Arduino is sending?

Don't really know - that's part of the issue. The Processing sketch uses the xBee library, so I don't actually see the raw datastream that goes to the xBee (plus, the Processing sketch uses escape characters, API 2, whereas I'm pretty sure that I should be using API 1).

So in an attempt to debug further, I decided to try to look for a response frame. Here's the new code:

#include <NewSoftSerial.h>

NewSoftSerial xbeeSer(6,5);  //receive, then transmit

byte frameCount;

void setup()
{
  Serial.begin(57600);
  Serial.println("Activating");
  
  xbeeSer.begin(4800);
  
  frameCount=0;
}

void loop()
{
  PulsePin('0', 500);
  delay(1000);
}
  
void PulsePin(int PinNumber, int delaytime)
{
  Serial.println("Sending On Command");
  
  setRemoteState(PinNumber, 0x4); //turn on
  
  delay(10);
  CheckResponseFrame();
      
  delay(delaytime);

  Serial.println("Sending Off Command");

  setRemoteState(PinNumber, 0x5); //turn off

  delay(10);
  CheckResponseFrame();
  
}
  
void setRemoteState(int pinnumber, int value)
{
  SendByteToXBee(0x7E); //start byte
  SendByteToXBee(0x0); //high part of length
  SendByteToXBee(0x10); //low part of length
  SendByteToXBee(0x17); //remote AT command
  SendByteToXBee(frameCount); //frame ID (no reply)
  
  // 64bit of recipient, or 0xFFFF for broadcast
  SendByteToXBee(0x00);
  SendByteToXBee(0x00);
  SendByteToXBee(0x00);
  SendByteToXBee(0x00);
  SendByteToXBee(0x00);
  SendByteToXBee(0x00);
  SendByteToXBee(0xFF);
  SendByteToXBee(0xFF);
  
  //16 bit of recipient, or 0xFFFE if unknown
  SendByteToXBee(0xFF);
  SendByteToXBee(0xFE);
  
  SendByteToXBee(0x02); //apply changes immediately
  
  SendByteToXBee('D'); //command name in ASCII
  SendByteToXBee(pinnumber); //command name in ASCII
  
  SendByteToXBee(value); //turn on or off
  
  //checksum
  
  long sum = 0x17 + frameCount + 0xFF + 0xFF + 0xFF + 0xFE + 0x02 + 'D' + pinnumber + value;
  
  SendByteToXBee(0xFF - (sum & 0xFF)); //calculate checksum
  
  delay(10);
  
  Serial.print("Frame Count:");
  Serial.println(frameCount, HEX);

  frameCount++;
  
}

void SendByteToXBee(byte Data)
{
  Serial.print(Data, HEX);
  Serial.print(" : ");
  xbeeSer.print(Data, BYTE);
  
}

void CheckResponseFrame()
{
  if (xbeeSer.available())
  {
    byte firstbyte = xbeeSer.read();
    Serial.print("Received: ");
    Serial.println(firstbyte, HEX);
    
    if (firstbyte == 0x7E)
    {
      Serial.println("Data received");
      for (int i=0; i<8;i++)
      {
        byte data = xbeeSer.read();
        Serial.print(data, HEX);
        Serial.print(" : ");
      }
      Serial.println("");
    }
  }
  else
  {
    Serial.println("No Data received");
  }
}

Unfortunately, I seem to not get any response back at all:

Activating
Sending On Command
7E : 0 : 10 : 17 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 4 : 73 : Frame Count:0
No Data received
Sending Off Command
7E : 0 : 10 : 17 : 1 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 5 : 71 : Frame Count:1
No Data received
Sending On Command
7E : 0 : 10 : 17 : 2 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 4 : 71 : Frame Count:2
No Data received
Sending Off Command
7E : 0 : 10 : 17 : 3 : 0 : 0 : 0 : 0 : 0 : 0 : FF : FF : FF : FE : 2 : 44 : 30 : 5 : 6F : Frame Count:3
No Data received

Well, I've figured out the problem, thanks to the "common xBee mistakes" section of the Faludi book and website:

For some reason, I set the soft serial port speed to 4800, whereas the xBee was expecting the default 9600....

Changing the speed to 9600 cleared it right up.