Broadcasting Strings from 1 Arduino to Another via XBee

Hi everyone, I’m having trouble broadcasting strings between two Arduino Uno units each equipped with an XBee-Pro S2C radio.

Background

I am attempting to build a system that relays lap times and messages from a laptop to remote display units installed on 4 go-karts. The program should send a laptime as a string to the Arduino via USB cable serial connection, which then broadcasts the unchanged string through the XBee software serial connection.

Based on my research it is my understanding that the XBee broadcast-to-all function should suit my needs. My intention is to have 1 coordinator connected to a laptop, broadcasting to multiple end devices. Currently I am working on a proof-of-concept with one transmitter and one receiver. I should be able to enter a 6-character string beginning with ‘A’ into the Java program, and the receiving units should all update their screens to show the last 4 characters of the string. However, this has not occurred.

The laptop runs a Java program that obtains lap times and user input messages and outputs them to an XBee unit. From what I could gather, the use of a USB XBee Explorer (in my case, Sparkfun P/N: WRL-11812) necessitates the use of the RXTXSerial DLL which would prevent the software from being packaged wholly in an executable JAR file, so I decided to send serial data to an Arduino with an XBee in AT mode configured as a coordinator which allows me to use the Java-Arduino Communication Library.

I strongly suspect this is an XBee config or data interpretation issue, but just in case, the full setup info is included below along with my work done:

Hardware

Transmitter (Coordinator)

1 x Arduino Uno
1 x Seeed Studio XBee Shield V2.0 (Tx/Rx jumpers set to pins 2 and 3 respectively)
1 x XBee-Pro S2C ZigBee (P/N: XBP24CZ7SITB003)
1 x Arduino USB cable (to laptop)

Receiver (Router)

1 x Arduino Uno
1 x Seeed Studio XBee Shield V2.0 (Tx/Rx jumpers set to pins 2 and 3 respectively)
1 x XBee-Pro S2C ZigBee (P/N: XBP24CZ7WITB003)
1 x Generic 128x64 Monochrome OLED Display (Compatible with Adafruit SSD_1306 library)

Software

Transmitter Arduino Code

#include <SoftwareSerial.h>

SoftwareSerial XBee(2,3);

void setup() {
Serial.begin(9600);
while(!Serial){
  
}
XBee.begin(9600);
XBee.write("AMBOOT");
}

void loop() {
while(Serial.available()){ 
  XBee.print(Serial.readString());
}
}

Receiver Arduino Code

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <Wire.h>
#include <SoftwareSerial.h>

SoftwareSerial XBee(2,3); // RX,TX

// If using software SPI (the default case):
#define OLED_MOSI   11
#define OLED_CLK   12
#define OLED_DC    9
#define OLED_CS    8
#define OLED_RESET 10
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

/* Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
*/

#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM bmp[] =
{ 
//bitmap code omitted
};

#define SSD1306_LCDHEIGHT 64
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

int clap = 1;
String clapt = "1";
String indata = "MTRACE";
String ddata = "RACE";

void setup() {
            Serial.begin(9600);
              pinMode(13, OUTPUT);       
              digitalWrite(13, HIGH); 
              
              display.begin(SSD1306_SWITCHCAPVCC);
             display.clearDisplay();
             display.drawBitmap(0,0, bmp, 128,64, WHITE);
             display.display();
             delay(4000);
             
              XBee.begin(9600);
              Serial.begin(9600);
              //XBee.write("n");
             //Code to display startup message omitted
              
              XBee.begin(9600);
              XBee.setTimeout(6000);
}

void loop() {
while (XBee.available())
            { 
              indata = XBee.readString();
              if (indata.charAt(0)== 'M' or indata.charAt(0) == 'A'){
                if (indata.charAt(1)== 'T'){
                clap++;
                clapt = clap;

                //Code to display lap count omitted
          
                }
                indata.remove(0,2);
                ddata = indata;
               //code to display lap time omitted
              }        
            }
}

XBee Configuration

Transmitter

Firmware Ver:   4060
Coordinator:     Enabled
DH:              0
DL:              FFFF

Receiver

Firmware Ver:    4060
Coordinator:     Disabled
DH:              0
DL:              0

(to be continued below)

(continued from OP)

Detail

The Java program appears to necessitate the configuration of the XBee coordinator in AT mode since the RSSI LED on the XBee Shield did not light up under any circumstances when it was configured in API mode as would be required using the standard XBee Java Library and the XBee USB Explorer.

I was able to confirm that the output of the Java program to Arduino was correct by plugging in a Receiver unit directly to the laptop and running the following code, and observed that the screen updated correctly given various inputs to the Java program.

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <Wire.h>
#include <XBee.h>

// If using software SPI (the default case):
#define OLED_MOSI   11
#define OLED_CLK   12
#define OLED_DC    9
#define OLED_CS    8
#define OLED_RESET 10
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

/* Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
*/

#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM bmp[] =
{ 
//bitmap code omitted
};

#define SSD1306_LCDHEIGHT 64
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

int clap = 1;
String clapt = "1";
String indata = "MTRACE";
String ddata = "RACE";

void setup() {
            Serial.begin(9600);
              pinMode(13, OUTPUT);       
              digitalWrite(13, HIGH); 
              display.begin(SSD1306_SWITCHCAPVCC);
             display.clearDisplay();
             display.drawBitmap(0,0, bmp, 128,64, WHITE);
             display.display();
             delay(4000);
             //code to display startup message omitted
}

void loop() {
while (Serial.available())
            { 
              indata = Serial.readString();
              if (indata.charAt(0)== 'M'){
                if (indata.charAt(1)== 'T'){
                clap++;
                clapt = clap;

                //code to display lap count omitted
          
                }
                indata.remove(0,2);
                ddata = indata;
                //code to display lap time omitted
              }        
            }
}

When switching to the XBee software serial it was observed that the RSSI LEDs on the XBee Shields of both the transmitter and remote receiver turn on, indicating some data is transmitted and received. However the remote receiver screen does not update. Attempting to diagnose the received data using the following code on the remote receiver connected to a PC yielded nothing at all appearing on the Serial Monitor.

#include <SoftwareSerial.h>

SoftwareSerial XBee(2,3);

void setup() {
Serial.begin(9600);
while(!Serial){
  
}
XBee.begin(9600);
}

void loop() {
while(XBee.available()){
  Serial.print(XBee.readString());
}
}

Using the XCTU serial console I was able to confirm that the receiving XBee could correctly read the strings sent from the Java program through the coordinator unit.

Following this I’m stumped. I’ve tried changing pins, swapping XBee Shields, and using spare radios in the same config but nothing works. This setup is based on a previous working setup that used the Digi XBee Java library and a USB Explorer to send data instead of an Arduino. The receiver Arduino programming is almost completely unaltered except for the addition of the If loop to read the string and remove characters, i.e. the receiving unit hardware and software has been proven to work with the Digi Java XBee library.

My best theory right now is that the receiving Arduino somehow isn’t able to identify the incoming characters as a string over SoftwareSerial where it could using plain Serial.

I hope I have been thorough enough in this description and thank you for reading this far if you did. I’d be grateful for any help I can get figuring this out. Thanks in advance.