XBee Newbie needs help getting started

Uploaded the "Physical Pixel" sketch to one Arduino + SainSmart module + XbeeS2 and the usual "Transmitter Code" (serial.print("H"), followed by Serial.print("L")) to another identical Arduino + XBee. I confirmed both Arduinos working properly and sketches working correctly. Then I unplugged them from the computer, switched the jumpers to "XBee" from USB, plugged them back in and nothing happens.

How to troubleshoot?

I did get one defective SainSmart board replaced with a new one, and now at least the LEDs all light up.

Can someone help get me started?

I'm not sure how/whether to try to configure these boards, as the instructions say this shouldn't be necessary.
Thanks!

The series 2 XBees are mesh network models that you are trying to use as point to point models. Why did you choose series 2 models?

How have you configured them? How are they connected to the Arduinos?

What code are you running on the Arduinos?

Why I got the series 2: I was worried that the 802 type would interfere with my LAN. I don't know much about all this, as is already clear! So I got the series 2 because I thought that worked at higher frequency. I was also eager to get going and overwhelmed trying to figure this all out, so just took the plunge and got some hardware.

I have not configured them, because the arduino hardware page said to send a series of three "+" separated by 1 second, and with no carriage returns. I don't know how to do this, as the serial monitor requires the character be "entered" or "sent". That page also said that no configuration was likely needed.

The XBee is installed on the SainSmart board, which is installed on the Arduino.

I have an oscilloscope, if that would be helpful to figure out what's happening, but I don't know what should be on each pin.

The code I am using is below, taken almost without changes from the Arduino wireless page:
Arduino 1 (transmitter):
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
}

void loop()
{
Serial.print('F');
digitalWrite(13, HIGH); // set the LED on
delay(5000);
Serial.println('L');
digitalWrite(13, LOW); // set the LED on
delay(1000);
}

Arduino 2 (receiver):
/*
Physical Pixel

An example of using the Arduino board to receive data from the
computer. In this case, the Arduino boards turns on an LED when
it receives the character 'H', and turns off the LED when it
receives the character 'L'.

The data can be sent from the Arduino serial monitor, or another
program like Processing (see code below), Flash (via a serial-net
proxy), PD, or Max/MSP.

The circuit:

  • LED connected from digital pin 13 to ground

created 2006
by David A. Mellis
modified 30 Aug 2011
by Tom Igoe and Scott Fitzgerald

This example code is in the public domain.

*/

const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into

void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}

void loop() {
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial.read();
Serial.println(incomingByte);
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'F') {
digitalWrite(ledPin, HIGH);
}
// if it's an L (ASCII 76) turn off the LED:
if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
}
}
}

/* Processing code for this example

// mouseover serial

// Demonstrates how to send data to the Arduino I/O board, in order to
// turn ON a light if the mouse is over a square and turn it off
// if the mouse is not.

// created 2003-4
// based on examples by Casey Reas and Hernando Barragan
// modified 30 Aug 2011
// by Tom Igoe
// This example code is in the public domain.

import processing.serial.*;

float boxX;
float boxY;
int boxSize = 20;
boolean mouseOverBox = false;

Serial port;

void setup() {
size(200, 200);
boxX = width/2.0;
boxY = height/2.0;
rectMode(RADIUS);

// List all the available serial ports in the output pane.
// You will need to choose the port that the Arduino board is
// connected to from this list. The first port in the list is
// port #0 and the third port in the list is port #2.
println(Serial.list());

// Open the port that the Arduino board is connected to (in this case #0)
// Make sure to open the port at the same speed Arduino is using (9600bps)
port = new Serial(this, Serial.list()[0], 9600);

}

void draw()
{
background(0);

// Test if the cursor is over the box
if (mouseX > boxX-boxSize && mouseX < boxX+boxSize &&
mouseY > boxY-boxSize && mouseY < boxY+boxSize) {
mouseOverBox = true;
// draw a line around the box and change its color:
stroke(255);
fill(153);
// send an 'H' to indicate mouse is over square:
port.write('H');
}
else {
// return the box to it's inactive state:
stroke(153);
fill(153);
// send an 'L' to turn the LED off:
port.write('L');
mouseOverBox = false;
}

// Draw the box
rect(boxX, boxY, boxSize, boxSize);
}

*/

/*
Max/MSP version 5 patch to run with this example:

----------begin_max5_patcher----------
1672.3oc2ZszaaiCD9ryuBBebQVCQRYao8xhf1cQCPVfBzh8RRQ.sDsM2HSZ
HQmlzh9eu7gjsjsEk7y0oWjiHoHm4aluYHGlueUmtiDuPy5B9Cv8fNc99Uc5
XZR2Pm726zcF4knDRlYXciDylQ4xtWa6SReQZZ+iSeMiEQR.ej8BM4A9C7OO
kkAlSjQSAYTdbFfvA27o2c6sfO.Doqd6NfXgDHmRUCKkolg4hT06BfbQJGH3
5Qd2e8d.QJIQSow5tzebZ7BFW.FIHow8.2JAQpVIIYByxo9KIMkSjL9D0BRT
sbGHZJIkDoZOSMuQT.8YZ5qpgGI3locF4IpQRzq2nDF+odZMIJkRjpEF44M3
A9nWAum7LKFbSOv+PSRXYOvmIhYiYpg.8A2LOUOxPyH+TjPJA+MS9sIzTRRr
QP9rXF31IBZAHpVHkHrfaPRHLuUCzoj9GSoQRqIB52y6Z.tu8o4EX+fddfuj
+MrXiwPL5+9cXwrOVvkbxLpomazHbQO7EyX7DpzXYgkFdF6algCQpkX4XUlo
hA6oa7GWck9w0Gnmy6RXQOoQeCfWwlzsdnHLTq8n9PCHLv7Cxa6PAN3RCKjh
ISRVZ+sSl704Tqt0kocE9R8J+P+RJOZ4ysp6gN0vppBbOTEN8qp0YCq5bq47
PUwfA5e766z7NbGMuncw7VgNRSyQhbnPMGrDsGaFSvKM5NcWoIVdZn44.eOi
9DTRUT.7jDQzSTiF4UzXLc7tLGh4T9pwaFQkGUGIiOOkpBSJUwGsBd40krHQ
9XEvwq2V6eLIhV6GuzP7uzzXBmzsXPSRYwBtVLp7s5lKVv6UN2VW7xRtYDbx
7s7wRgHYDI8YVFaTBshkP49R3rYpH3RlUhTQmK5jMadJyF3cYaTNQMGSyhRE
IIUlJaOOukdhoOyhnekEKmZlqU3UkLrk7bpPrpztKBVUR1uorLddk6xIOqNt
lBOroRrNVFJGLrDxudpET4kzkstNp2lzuUHVMgk5TDZx9GWumnoQTbhXsEtF
tzCcM+z0QKXsngCUtTOEIN0SX2iHTTIIz968.Kf.uhfzUCUuAd3UKd.OKt.N
HTynxTQyjpQD9jlwEXeKQxfHCBahUge6RprSa2V4m3aYOMyaP6gah2Yf1zbD
jVwZVGFZHHxINFxpjr5CiTS9JiZn6e6nTlXQZTAFj6QCppQwzL0AxVtoi6WE
QXsANkEGWMEuwNvhmKTnat7A9RqLq6pXuEwY6xM5xRraoTiurj51J1vKLzFs
CvM7HI14Mpje6YRxHOSieTsJpvJORjxT1nERK6s7YTN7sr6rylNwf5zMiHI4
meZ4rTYt2PpVettZERbjJ6PjfqN2loPSrUcusH01CegsGEE5467rnCdqT1ES
QxtCvFq.cvGz+BaAHXKzRSfP+2Jf.KCvj5ZLJRAhwi+SWHvPyN3vXiaPn6JR
3eoA.0TkFhTvpsDMIrL20nAkCI4EoYfSHAuiPBdmJRyd.IynYYjIzMvjOTKf
3DLvnvRLDLpWeEOYXMfAZqfQ0.qsnlUdmA33t8CNJ7MZEb.u7fiZHLYzDkJp
R7CqEVLGN75U+1JXxFUY.xEEBcRCqhOEkz2bENEWnh4pbh0wY25EefbD6EmW
UA6Ip8wFLyuFXx+Wrp8m6iff1B86W7bqJO9+mx8er4E3.abCLrYdA16sBuHx
vKT6BlpIGQIhL55W7oicf3ayv3ixQCm4aQuY1HZUPQWY+cASx2WZ3f1fICuz
vj5R5ZbM1y8gXYN4dIXaYGq4NhQvS5MmcDADy+S.j8CQ78vk7Q7gtPDX3kFh
3NGaAsYBUAO.8N1U4WKycxbQdrWxJdXd10gNIO+hkUMmm.CZwknu7JbNUYUq
0sOsTsI1QudDtjw0t+xZ85wWZd80tMCiiMADNX4UzrcSeK23su87IANqmA7j
tiRzoXi2YRh67ldAk79gPmTe3YKuoY0qdEDV3X8xylCJMTN45JIakB7uY8XW
uVr3PO8wWwEoTW8lsfraX7ZqzZDDXCRqNkztHsGCYpIDDAOqxDpMVUMKcOrp
942acPvx2NPocMC1wQZ8glRn3myTykVaEUNLoEeJjVaAevA4EAZnsNgkeyO+
3rEZB7f0DTazDcQTNmdt8aACGi1QOWnMmd+.6YjMHH19OB5gKsMF877x8wsJ
hN97JSnSfLUXGUoj6ujWXd6Pk1SAC+Pkogm.tZ.1lX1qL.pe6PE11DPeMMZ2
.P0K+3peBt3NskC
-----------end_max5_patcher-----------

*/

Get the X-CTU program from Digi.com and load the Coordinator firmware into one of the two XBees. Also set the DH and DL parameters (destination address, high and low) on each XBee to be the other XBee's address. Then the two S2 modules should work fine, effectively in point-to-point mode. Each S2 network requires exactly one Coordinator. S2 XBees are normally shipped with the Router firmware. A network can have multiple Routers, but must have one Coordinator.

Do I have to remove the microcontroller from Arduino board to do this?

ipsolutions:
Do I have to remove the microcontroller from Arduino board to do this?

Either that or I think perhaps loading a do-nothing sketch is OK. Then the jumpers on the shield also need to be moved. I think. I've never used one of those shields, so you might want to read the doc. I assume you are using this shield? [Discontinued] XBee Shield for Arduino – SainSmart.com

Removed the microprocessor, and now it claims to have written to the board successfully, but I saw no opportunity for choosing a DH or DL. The defaults are 0 DH and FFFF DL.

Lots of LEDs now flashing on both boards.

Wireless communication WORKS!! THanks, Jack!

Glad to hear. See attached X-CTU screen snap. DH and DL is set to the other XBee's SH and SL. This can be done via X-CTU, or with AT commands.

I have one more rather basic question: I need this RF capability to allow me to change my satellite settop box with a remote from anywhere in the house. The remote uses a hex number, like FB30CF, to communicate to the box. How do I pass this number in hex between the Arduinos, so that the receiving Arduino treats it as hex number? Would I treat it as a character string? I thiought the Read.serial() only reads the incoming byte. Would I Serial.print the hex number, and Read.serial() 6 times? How would it then treat it as a 6-digit hex number?

To clarify, the receiving Arduino will be parked in front of the settop box, and will drive an IR emitter with whatever hex code it receives from the other transmitting Arduino.

The Arduinos with (or without) XBees transfer bytes. Whether that byte represents a character or a 2 digit hex value matters only to the sender and the receiver.

If you want to send 0xFB, 0x30, and 0xCF, do that.

OK, thanks, but I need a bit more guidance. As mentioned, the IRsend program will send a hex value, such as 0xFB30CF to the sending subroutine. I want to receive this value wirelessly using the Xbee. How do I transmit it byte-wise? Sorry to be such an idiot, but I am missing the concept here, and this certainly doesn't work:

#include <IRremote.h>

IRsend irsend;

byte Button1 = 0;
byte Button2 = 0;
byte Button3 = 0;

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

void loop() {
if (Serial.available() > 0) {
//read the incoming byte:
Button1 = Serial.read();
Button2 = Serial.read();
Button3 = Serial.read();
Serial.print("I have received: "); Serial.print(0xButton1, HEX);Serial.print(0xButton2, HEX);Serial.println(0xButton3, HEX);
}
delay(100);

}

THis is a fundamental lack of understanding on my part, and I would appreciate it if someone would explain things a bit to me.

Please put code between code tags: [ code ] [ /code ] ... makes it easier to read. Click the # button when composing a post to insert the tags.

Show us the code on the sending end as well. By the way, the code as posted above doesn't compile. You knew that, yes?

Bottom line, numbers are numbers, and hex is just one possible representation. How the number is sent between the two Arduinos is probably of secondary importance. It could be sent as hex, decimal, octal, or in Morse code and work just fine. The best approach might be to consider how the data is generated and consumed and choose a format that is easiest to implement in that light. Some sort of protocol may also be needed so that the receiving end can recognize the start and end of the number. This could be important especially if the number is not always the same number of digits. Actually it's not a bad idea even if it is always the same. Some simple delimiters could work.

Here is the code that receives the signal from the IR decoder. I point the remote at the decoder, and this tells me what the value is. So the number I want to transmit is the results->value. I will next post the IRsender that can send this value to the settop box or TV, or whatever.

/*
 * IRremote: IRrecvDump - dump details of IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.println("Could not decode message");
  } 
  else {
    if (results->decode_type == NEC) {
      Serial.print("Decoded NEC: ");
    } 
    else if (results->decode_type == SONY) {
      Serial.print("Decoded SONY: ");
    } 
    else if (results->decode_type == RC5) {
      Serial.print("Decoded RC5: ");
    } 
    else if (results->decode_type == RC6) {
      Serial.print("Decoded RC6: ");
    }
    Serial.print(results->value, HEX);
    Serial.print(" (");
    Serial.print(results->bits, DEC);
    Serial.println(" bits)");
  }
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");

  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    } 
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
}


void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
}

Here is the code that sends the IR signal to the target device, i.e. settop box. It seems to work when I send the hex value decoded by the previous algorithm. FB30CF is the code to turn the power off and on. According to the decoder, all IR codes from the remote in question are 32 bits, NEC protocol.

/*
 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

IRsend irsend;


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

void loop() {
  if (Serial.read() != -1) {
    for (int i = 0; i < 1 
    ; i++) {
      irsend.sendNEC(0xFB30CF, 32); // NEC TV power code
      
      Serial.print("Sent FB30CF to device");
      delay(100);
    }
  }
}

So I see results->value is 32 bits, an unsigned long. So potentially it could be eight hex digits. I might just send it in decimal, then use the atol() function to convert it back at the other end. Put some delimiters around it.

So the sending side could do

Serial.print('<');    //starting delimiter
Serial.print(results->value, DEC);
Serial.print('>');    /ending delimiter

The receiving side would read one byte at a time, throwing away each byte until a '<' is received. Then copy the next bytes into an array (be sure to check for overrun), until '>' is received, at which point use atol() on the array.

Am trying to get the Arduino to send the correct sequence from a string received over the serial link. I am looking at the output on an oscilloscope. The first code outputs what looks like the correct sequence, the second one doesn't. The only difference is the argument for the IRsend.sendNEC command. It appears I am not handing the data conversion array --> unsigned long correctly, or the IRsend.sendNEC command required a hex representation. Any suggestions?

First code:

/*RECEIVER CODE
Receives a 5 digit decimal code (12495) which it will send as hex value BF30CF to IR emitter on pin 3.
*/

#include <IRremote.h>

IRsend irsend;
char message[] = {1,2,4,9,5};
unsigned long key = 0;

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

void loop() {
  for (int i = 1; i<6; i++)
  {
  //message[i] = Serial.read();
  }
  key = atol(message);

      irsend.sendNEC(0xBF30CF, 32); // 333TV power code
      delay(1000);
    }

Second code:

/*RECEIVER CODE
Receives a 5 digit decimal code (12495) which it will send as hex value BF30CF to IR emitter on pin 3.
*/

#include <IRremote.h>

IRsend irsend;
char message[] = {1,2,4,9,5};
unsigned long key = 0;

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

void loop() {
  for (int i = 1; i<6; i++)
  {
  //message[i] = Serial.read();
  }
  key = atol(message);

      irsend.sendNEC(key, 32); // TV power code
      delay(1000);
    }

12495 is the decimal representation for BC30CF.

ipsolutions:
12495 is the decimal representation for BC30CF.

I get 12333263.

12495 is the decimal representation for BC30CF

A reality check would indicate that the base 10 representation of a number can not possibly be less than the hexadecimal representation of the same number.