Go Down

Topic: Arduino and XBee Software Serial (Read 5715 times) previous topic - next topic

boulavogue

Thanks for taking the time to review this.

As part of a much larger project I've been having some issues when using software serial pins.

I have 2 xbees (series 2) configured as a router & coordinator

When a blank sketch is uploaded to the coordinator the data stream is read perfectly but when the simple sketch (using software serial pins) is used the the coordinator receives no packets.

I've tried changing the rx pins and a few different sketches. To no avail.
Both XBees are set to the same PAN ID & baud rates with the SH =DH and SL=DL parameters correct.

Any input or troubleshooting ideas are very much appreciated.


Router: (sending data)
Code: [Select]
#include <SoftwareSerial.h>
#define rxPin 11
#define txPin 12

SoftwareSerial xbee =  SoftwareSerial(rxPin, txPin);
void setup(){
 Serial.begin(19200);
 pinMode(rxPin, INPUT);
 pinMode(txPin, OUTPUT);
 xbee.begin(19200);
}

void loop(){
 xbee.print('A');
 Serial.println('B'); //
}



Coordinator: (receiving data)
Code: [Select]
#include <SoftwareSerial.h>
#define rxPin 8
#define txPin 9

SoftwareSerial xbee =  SoftwareSerial(rxPin, txPin);

void setup(){
 pinMode(rxPin, INPUT);
 pinMode(txPin, OUTPUT);
 
 xbee.begin(19200);
 Serial.begin(19200);
 Serial.println("Starting XBee Comunication");
}


void loop(){
 char someChar = xbee.read();
 Serial.println(someChar);
 delay(1000);
 //Serial.println(rec);
}

boulavogue

The coordinator reads everything when this blank sketch is uploaded (and the Serial Monitor is set to the correct baud).

Code: [Select]
void setup() { }
void loop() { }


I believe it to be a problem with the coordinators code/rx pin but hitting a wall at this stage.
I'm trying to work through the issue and will post any updates.

PaulS

#2
Dec 06, 2014, 02:30 pm Last Edit: Dec 06, 2014, 02:32 pm by PaulS
Quote
When a blank sketch is uploaded to the coordinator the data stream is read perfectly
Read by what? With a blank sketch, the serial data is NOT read by the Arduino. It simply arrives at the serial-to-USB converter chip and is converted and sent to the USB cable.

Quote
but when the simple sketch (using software serial pins) is used the the coordinator receives no packets.
Have you made the appropriate changes to the hardware, so that the XBee's outputs are connected to the software serial pins, instead of the hardware serial pins?

Quote
I've tried changing the rx pins
How? To what? How have you changed where the pins that the XBee is actually connected to?

The Arduino shield uses either the hardware serial pins or pins 2 and 3. Why are you using 8 and 9 in your code?

boulavogue

#3
Dec 06, 2014, 08:23 pm Last Edit: Dec 07, 2014, 12:24 am by boulavogue
Quote
Read by what? With a blank sketch, the serial data is NOT read by the Arduino. It simply arrives at the serial-to-USB converter chip and is converted and sent to the USB cable
I'm not sure why I imagined that the blank sketch magically opened all ports or something, after setting up the PanID's etc I finally saw data and I was thrilled. Thanks, yes data feeding directly to Serial-to-USB converter chip (when a blank sketch is loaded) makes much more sense.

Quote
Have you made the appropriate changes to the hardware, so that the XBee's outputs are connected to the software serial pins, instead of the hardware serial pins?
No. I originally tried pins 2,3 with no luck and then last night tried a series of combinations (2,4 2,5 8,7 8,9 etc) in hopes something would come alive. I guess I was at 8,9 when I copied the code. I have now changed back to
Code: [Select]
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3


No hardware changes were/have been made & Serial Select switch on the Wireless shield is set to Micro.

A little background:
I plan to have characters (using the format <0.75>) being sent from the router.
I hope to parse the data on the coordinador and send it to xlively.com via an Ethernet shield (that sits between the UNO & Wireless Shield). I have successfully tested a demo feed via the Ethernet shield and am now in hopes of reading the feed via Xbee and sending it to xlively.

As it stands my xbee router is sending the data, I see constant RSSI LEDs on both the router and coordinator and the Serial monitor on the coordinator is printing (if the router is powered on or not)


Code: [Select]
ÿ
ÿ
ÿ

boulavogue

#4
Dec 07, 2014, 01:08 am Last Edit: Dec 07, 2014, 12:38 pm by boulavogue
I believe the issue to be the lack of MALE ICSP headers on the ethernet shield.



As @PaulS pointed out
Quote
With a blank sketch, the serial data is NOT read by the Arduino. It simply arrives at the serial-to-USB converter chip and is converted and sent to the USB cable.
The serial monitor appears to show the xbee is reading the data stream but in fact the arduino never processes this.

It's frustrating to say the least but there are options
Adding extra ICSP headers 

PaulS

The Arduino wireless shield is really a piece of crap. There is no way to make it use anything other than the hardware serial pins. The Sparkfun shield is the best of the shields, though I do not like recommending Sparkfun after the crap they pulled with their "free" day a while back.

Their shield's switch DOES switch between the hardware serial pins (0 and 1) and the next set of pins (2 and 3). It's a shame that there isn't a XBee shield with jumpers that lets you choose which pins to use. Picking the external interrupt pins was a lousy choice, even though it made routing the traces easy.

boulavogue

@PaulS Thanks a million for your input man. I've been trying to get this setup working for over a week and shamefully it didn't cross my mind that the headers were the issue.

Some spare IC sockets and a hacksaw later I'm broadcasting online :) (yes i'll probably solder these in place but for a test at least it's working)

jpg attached for anyone who wishes to do the same.
 


PaulS

Quote
Some spare IC sockets and a hacksaw later I'm broadcasting online
Cool.

kyleyeung000

Hi everyone, I'm having the same trouble OP had (XBees transmitting and receiving data but Arduino does not appear to process it as the Serial Monitor remains blank).

I'm using the Seeed Studio XBee Shield V2.0 which has jumpers for the Tx and Rx pins that I've set to 2 and 3 respectively, matching the software code. The shields also connect to the ICSP headers on the Arduinos.

I only need one-way broadcasting to the end device, and have verified both radios are transmitting and receiving properly using XCTU, and it looks like I've solved the issues affecting OP but my serial monitor is still entirely blank. Can anyone help me?

Software

Transmitter Arduino Code
Code: [Select]

#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

Code: [Select]

#include <SoftwareSerial.h>

SoftwareSerial XBee(2,3);

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while(!Serial){
}
XBee.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
while(XBee.available()){
Serial.println(XBee.readString());
}
}

XBee Configuration

Transmitter

Code: [Select]

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

Receiver

Code: [Select]

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


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)


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)


Sorry for bumping an old thread and thanks for taking the time to help.

PaulS

Why do you have the transmitter XBee in broadcast mode? Why is the receiver listening to everyone?

It would be far better to talk to, or listen to, ONE other radio, on each end.

Instead of sending only what is read from the Serial instance, send (using print(), not write()) a known string at a known interval (using the blink without delay philosophy, not delay()).


kyleyeung000

#10
Oct 02, 2018, 04:34 pm Last Edit: Oct 02, 2018, 04:39 pm by kyleyeung000
Why do you have the transmitter XBee in broadcast mode? Why is the receiver listening to everyone?

It would be far better to talk to, or listen to, ONE other radio, on each end.

Hi Paul,

For my finished project (a lap time display system for 4 go-karts) I want to have one transmitter broadcasting to 4 receivers. A full write-up of my project is posted here and I'm happy to add any info you want.

You're right that the receivers should only be listening to the transmitter, I'll rectify that at the earliest opportunity and update when I do.

Instead of sending only what is read from the Serial instance, send (using print(), not write()) a known string at a known interval (using the blink without delay philosophy, not delay()).
I'll look into this, but would receiving and processing strings frequently increase power consumption by a significant amount? Because the receivers will be using the smallest batteries possible I'm inclined to keep power draw as low as I can.

Out of curiosity, when testing programming for a display I found the Receiver did exactly what I wanted when it was using Serial instead of SoftwareSerial. I'm fairly new to Arduino, but is there any reason SoftwareSerial doesn't work while Serial does? Thanks.

EDIT: Actual Receiver Code (works when replacing XBee with Serial and using Serial Monitor to input data):
Code: [Select]


#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);

#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);
             //Code to display startup message omitted         
}

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
              }       
            }
}



kyleyeung000

Instead of sending only what is read from the Serial instance, send (using print(), not write()) a known string at a known interval (using the blink without delay philosophy, not delay()).
I used the following code to and confirmed through the RSSI LED and serial monitor that the transmitter was indeed broadcasting at ~7000ms intervals

Code: [Select]

#include <SoftwareSerial.h>

SoftwareSerial XBee(2,3);

unsigned long prevms = 0;
const long intervalms = 7000;
unsigned long currentms = 0;

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

void loop() {
currentms = millis();

if(currentms-prevms>=intervalms){
  prevms = currentms;
  Serial.print("AMBOOT");
  XBee.print("AMBOOT");
}

}


Also confirmed using the Receiver RSSI LED that the receiving XBee had data incoming. However the serial monitor for the receiver remained completely blank. The serial port and baud rate of the monitor were both correctly configured.

(Receiver Code as in Reply #8 of this thread)

It should be noted that the receiver Arduino code did work on a previous project where the transmitter was an XBee in API mode plugged into a Sparkfun USB explorer outputting data from a Java program using the Digi XBee Java library and the SendBroadcastData function, and I'm stumped as to why that is. Think it's worth trying Write instead of Print to output in bytes?


kyleyeung000

#12
Oct 03, 2018, 11:00 am Last Edit: Oct 03, 2018, 11:18 am by kyleyeung000
Based on the Reply #6 in this thread I investigated using getBytes to convert the string to a byte array.

Not knowing whether the post was referring to AT or API mode I nonetheless wrote the code below for the transmitter in AT mode just to take a shot at it. In the writeByteArray code I tried both print AND write but neither worked.

Code: [Select]

#include <SoftwareSerial.h>

SoftwareSerial XBee(2,3);

unsigned long prevms = 0;
const long intervalms = 7000;
unsigned long currentms = 0;
String outdata = "AMBOOT";
uint8_t payload[10];

void setup() {
Serial.begin(9600);
while(!Serial){
 
}
outdata.getBytes(payload, 10);
XBee.begin(9600);
//XBee.println("AMBOOT");
}

void loop() {
currentms = millis();

if(currentms-prevms>=intervalms){
  prevms = currentms;
  Serial.print("AMBOOT");
  writeByteArray(payload, 10);
}

}

void writeByteArray(uint8_t array[], int arrlength){
  for(int j=0;j<arrlength;j++){
    Serial.write(array[j]);
    XBee.write(array[j]);
  }
}


The next step will be to try transmitting in API mode, and figure out how to do a broadcast in API mode.

EDIT: Array size is 10 because that's the length of the string to be transmitted in the final product, it's a placeholder for now.

Go Up