Troubleshooting Arduinos in a XBee peer2peer net

Hello,

currently I'm struggeling with a relative simple sketch (see below) that enables me to pass strings over a xbee peer2peer network to a couple arduino. each of the arduinos has it's own id and is connected to a xbee series 1 module. As far as i know protocols like firmata or messenger cannot address multiple arduinos, so i'm creating a new protocol.

By sending a string such as "02foo;" the arduino with ID 2 receives the message and so far simply answers by sending back the received string. ID 00 is a kind of broadcast id, so that all arduinos answer to it.

This works fine if only one arduino is in the xbee network, but I'm experiencing strange behaviour if a second arduino joins the network. Only the last arduino that responded will respond the next time. if i try to access an arduino with another id, i have to send the string twice until the module answers.

This behaviour is strange and i think i have misconfigured the xbee modules (I'm currently testing with three of them, configured all the same, see below). Or is something wrong with my code?

Any ideas?

BTW: is there a difference between peer2peer and a star-architecture? I think star is the architecture of choice. is it's xbee-configuration the same? The xbee manual doesn't give me a light bulb moment.

The configuration profile of the XBee modules looks like the following:

XBP24_15_4_1084.mxi
FE
0
241
1084
0
[A]CH=C
[A]ID=3332
[A]DH=0
[A]DL=0
[A]MY=0
[A]RN=0
[A]MM=0
[A]CE=0
[A]SC=1FFE
[A]SD=4
[A]A1=0
[A]A2=0
[A]PL=4
[A]CA=2C
[A]SM=0
[A]ST=1388
[A]SP=0
[A]DP=3E8
[A]BD=3
[A]RO=3
[A]D7=1
[A]D6=0
[A]D5=1
[A]P0=1
[A]AP=0
[A]PR=FF
[A]RP=28
[A]CT=64
[A]GT=3E8
[A]CC=2B

The sketch i'm working with is this:

#include <WString.h>

#define maxLength 16

int ownID = 2; // Adjust according to module ID

String command = String(maxLength);
boolean commandComplete = false;
int recID;

void setup() {
  Serial.begin(9600);
  recID = 0;
}

void loop () {
  if(Serial.available() > 0) {
    getIncomingChars();
  }

  if (commandComplete == true) {
    processCommand();
  }

}

void getIncomingChars() {
  char inChar = Serial.read();
  if(inChar == 59){
    commandComplete = true;
  } else {
    if(inChar != 10 || inChar != 13){
      command.append(inChar);
    }
  }
}

void processCommand(){
  if(commandCorrect() && (recID == ownID || recID == 0)){
    Serial.print("-");
    Serial.print(ownID);
    Serial.print("- received: ");
    Serial.println(command);
  }
  
  command = "";
  recID = 0;
  commandComplete = false;
}

boolean commandCorrect(){
  boolean ret = false;
  if(command.charAt(0) == '0' || command.charAt(0) == '1'){
    if(isNumeric(command.charAt(1))){
      recID = command.charAt(1) - 48;
      if(command.charAt(0) == '1'){ recID = recID + 10; }
      ret = true;
    }
  }
  return ret;
}

what series XBees do you have? what flavour firmware are you using?

not sure what could be issue but my first thought is on your commandComplete flag. Looks like you sit in a loop until you receive 59 chars. are all of your messages that length?

i'm using xbee series 1 with firmware version 1084..

the messages i try to send are not longer than about 10 characters.

i don't think i'm waiting for 59 characters, do i? i thought i'm only waiting for a character with ascii code 59 (";") which is the termination character of the strings, which means that the command is complete and ready for processing. i could also use ascii 10 or 13, but for debugging i use a character that is printable. am i wrong here?

any ideas?

you're right, when I glanced at your code yesterday, I thought I saw some sort of char count. sorry for the bad comment.

Since the module seems to ignore you until a second string is sent, I'm still suspicious of the cmd complete or the cmd correct flags. I'd probably comment out some of your compare logic and start back at basic parsing and work back up.

i think i solved the problem.

the xbee configuration seems to be correct, but when addressing all network participants at once, only on reply comes through. but all participants receive the message and can process it. so i removed the possibility to broadcast commands for now, because i need the answers for debugging purposes.

the code which is the basis for my new protocol looks like this:

#include <WString.h>

#define maxLength 16

int ownID = 0; // Adjust according to module ID
boolean answer = false;

String command = String(maxLength);
boolean commandComplete = false;
int recID;

void setup() {
  Serial.begin(9600);
  recID = 0;
}

void loop () {
  if(Serial.available() > 0) {
    getIncomingChars();
  }

  if (commandComplete == true) {
    processCommand();
  }

}

void getIncomingChars() {
  char inChar = Serial.read();
  if(inChar == 59 || inChar == 10 || inChar == 13){
    commandComplete = true;
  } else {
    command.append(inChar);
  }
}

void processCommand(){
  if(commandCorrect() && (recID == ownID)){
  // process command
  }
  
  command = "";
  recID = 0;
  commandComplete = false;
}

boolean commandCorrect(){
  boolean ret = false;
  if(command.charAt(0) == '0' || command.charAt(0) == '1'){
    if(isNumeric(command.charAt(1))){
      recID = command.charAt(1) - 48;
      if(command.charAt(0) == '1'){ recID = recID + 10; }
      ret = true;
    }
  }
  return ret;
}

boolean isNumeric(char character){
  boolean ret = false;
  if(character >= 48 && character <= 75){
    ret = true;
  }
  return true;
}

in my blog (see my web link) i will write about the progress of the protocol, soon.

A first working version of my firmware/protocol can be found at

I'd be glad to receive feedback!

This project is exactly what I need, thank you for making it.

My only problem is that I can't seem to get it to verify/compile. There doesn't seem to be any documentation or examples to help me figure out what I'm doing wrong. I am currently using Arduino 16 (Tried 15 as well).

I have String(Version 0.4) installed, as per the directions from the informational page, but when I go to verify the initial setup code, I get this:

error: 'String' does not name a type In function 'void allFunc()':
In function 'void analogWriteFunc()':
In function 'void digitalWriteFunc()':
In function 'void pinModeFunc()':

I'm new to the Arduino platform, though I've been studying it nonstop for the past couple of weeks (4 to 7 hours a day some days) but I just can't seem to figure out the issue.

I notice some of the directions say to put libraries in the /lib/targets/library directory, which i know does not work as there is no such place, but I've tried recreating it, to no avail. Currently String resides in the hardware/libraries folder, where it seems to be recognized.

I've tried getting this Sketch to work from PC, Mac & Linux, but i get the same error no matter what I try.

I'm not completely new to programing, but this just goes above my current skill level. Can anyone help me out? :slight_smile:

Hi Tievx0r,

Thank you for your interest in SerialControl! :slight_smile:
The problem you describe sounds strange.I tried to reproduce the problem with no success. Everything works fine, here. The only thing I can do is giving you a step-by-step how-to which works for me:

I'm working with Linux (Ubuntu 9.04), but other systems may work similarly.

After downloading the current Arduino environment (version 16) from http://arduino.cc/en/Main/Software and extracting the archive e.g. in my Desktop folder, I downloaded the String library (direct download link: http://arduino.cc/en/uploads/Tutorial/String.zip). You are right when you write that there is no lib/targets/library directory. It is not used anymore. So after decompressing the String archive, copy the contained String folder (on the same level as the __MACOSX folder, which can be ignored) to the hardware/libraries/ directory of your Arduino environment.

The directory tree should look like this (excluded sub-folders that are irrelevant to this problem):

./arduino-0016
|-- examples
|-- hardware
|   |-- bootloaders
|   |-- cores
|   |-- libraries
|   |   |-- EEPROM
|   |   |-- Ethernet
|   |   |-- Firmata
|   |   |-- LiquidCrystal
|   |   |-- Matrix
|   |   |-- Servo
|   |   |-- SoftwareSerial
|   |   |-- Sprite
|   |   |-- Stepper
|   |   |-- String             <== the important part!!!
|   |   |   `-- examples
|   |   |       `-- [...]
|   |   `-- Wire
|   `-- tools
|-- lib
|-- reference
`-- sketchbook

Not load and extract the complete SerialComtrol archive into your sketchbook folder. The SerialControl folder has to be named SerialControl, like the main file SerialControl.pde (without the .pde ending). Then the code should work without any issues.

I hope this helps. If not, feel free to ask further questions. :wink:

I tried getting it working on Ubuntu 8.10. It worked, though there were some errors in the debugger that didn't affect anything.

Installed Ubuntu 9.04, everything seems work fine now.

I have an idea as to why its not working. Arduino can't find all the header files under XP & OSX.

the xbee configuration seems to be correct, but when addressing all network participants at once, only on reply comes through. but all participants receive the message and can process it.

You're probably seeing the radio signals colliding with each other. Think of it as a vocal conversation, where you can only hear one person talk at a time.

I think the easiest way to prevent collision for a broadcast acknowledgment is for each participant to wait a random delay duration before responding. An alternative is to have the participants respond in ID order, but participants who can't hear other participants will still need to know how long to wait.

Hi,

I'm trying to get SerialControl running on my Duemilanove, but when sending the proposed command "00dw13HIGH", my onboard LED does not light up. I tried the Arduino serial console, as well as HyperTerminal...

The command structure

01 23 4567 8901 23456
id cm arg1 arg2

indicates that arg1 has to have four characters, but even if I try "00dw 13HIGH", nothing happens.

Am I doing something wrong...?

What zigbee do you have attached to the Arduino that is sending? Do you have that same type attached to the one that is receiving? What ID have you assigned to the zigbee that is sending? What ID do you have assigned to the one that is supposed to be receiving?

Do they talk to each other without this protocol?

What does the sketch on the receiver look like?

Oh, sorry, I obviously didn't include enough information in my original post...

I'm not sending from Arduino to Arduino, instead I'm just using the console to fire commands at the Arduino. Just like described under "Usage" here: Arduino Playground - SerialControl.

Right now I'm receiving

-0- dw -17587 HIGH

on the console when I enter the command

00dw  13HIGH;

I'm using a completely unmodified SerialCommand package. Somehow the pin number is calculated incorrectly. I took a look at the parseArgument() function and walked through all the if-statements, which should deliver a correct pin number (13)... I have no idea what might be going wrong there...

Hi Marcus,

try

00dw0013HIGH;

This should finally work, if your already those get strange answers. Always fill up empty numbers with zeros. When you use arguments with letter, use whitespaces for filling up.

Sorry, I should add this to the documentation (or see it as a bug and fix it ;-)).

Hope it helps,
Eckard

Great, this works! Thanks for the hint, I tried any other variation of the command already, but I didn't think of just inserting zeroes...