Go Down

Topic: Use serial and NewSoftSerial together (Read 2376 times) previous topic - next topic

strange quark

Jan 27, 2011, 07:48 pm Last Edit: Jan 27, 2011, 09:11 pm by brian515 Reason: 1
I've been pulling my hair out for the past few days trying to get my XBees and GPS to play nice together. I have them connected both with their respective shields from SparkFun to my Arduino Uno. I want to run the XBee off uart, and the GPS off digital pins 2 and 3 using NewSoftSerial. But, as soon as I turn on the NewSoftSerial, I start getting interference and packet losses on the rx pin. However, the tx seems to work fine because I have my Arduino send some text, and that always comes through fine.

Here is my code:
Code: [Select]
NewSoftSerial gpsSerial(2,3);
char inData[5];
TinyGPS gps;
PWMServo servo; //have to use the servo library from 0016 otherwise NewSoftSerial messes up the servo

void setup() {
 servo.attach(10);
 servo.write(90);
 Serial.begin(57600);
 gpsSerial.begin(4800); //this seems to be causing the problem
 Serial.print("Hello there!");
}

void loop() {
 if(Serial.available() >=5) { //every command I send is 5 characters long
   for(int i=0; i < 5; i++) {
     inData[i] = Serial.read();
   }
 }
if(strcmp(inData, "right")==0) { //right
   servo.write(135);
 }
 else if(strcmp(inData, "lleft")==0) { //left
   servo.write(40);
 }
if(strcmp(inData, "strai")==0) { //straight
   servo.write(90);
 }
}


Interestingly enough, this setup works fine if I connect over USB.

Thanks everyone!

PaulS

Quote
Interestingly enough, this setup works fine if I connect over USB.

As opposed to how?

How are you powering this whole collection of parts - GPS, XBee, servo?

The strcmp function expects NULL terminated strings. Yours are not NULL terminated. You don't even have room add the NULL.

strange quark

Okay, thanks. How do NULL terminate the string?

If I don't connect over USB, I am powering the setup using a 9V battery connected to the bullet connector on the Arduino and (attempting) to communicate using the XBee. (I have a SparkFun USB explorer board attached to my computer).

Graynomad

#3
Jan 28, 2011, 01:54 am Last Edit: Jan 28, 2011, 03:22 am by Graynomad Reason: 1
Quote
How do NULL terminate the string?


Try

Code: [Select]
for(int i=0; i < 5; i++) {
     inData[i] = Serial.read();
   }
  inData[i] = '\0';   // terminate the string


Also, if you have 5 chars you need a 6-byte array to allow for the NULL terminator.

char inData[6];

Also, is a 9v battery up to powering all that, some Xbees draw 250mA by themselves.
______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

strange quark

Quote
Code: [Select]
for(int i=0; i < 5; i++) {
     inData[i] = Serial.read();
   }
  inData[i] = '\0';   // terminate the string


Okay, I did what you said, but if I do this, nothing works. It's like inData is cleared before I can do anything else.  

If I put,
Code: [Select]
if(Serial.available() >0) {
   for(int i=0; i<5; i++) {
     inData[i] = Serial.read();
   }
     inData[5] = '\0';
 Serial.println(inData);
 }
I get junk output if I echo what is read in. For example, if I send the command "right," I can get r???? or ight? or ri??? or any other combination of something that resembles "right" but replaces some letter with ?. This happens on both the XBee and USB.

Graynomad

The last code you posted won't work because you don't wait for 5 chars, so you get the first char then overwrite the array with 0s.

Also, my example did something similar because I had the

Code: [Select]
inData[i] = '\0';

in the wrong place. Try this.

Code: [Select]
NewSoftSerial gpsSerial(2,3);
char inData[5];
TinyGPS gps;
PWMServo servo; //have to use the servo library from 0016 otherwise NewSoftSerial messes up the servo

void setup() {
  servo.attach(10);
  servo.write(90);
  Serial.begin(57600);
  gpsSerial.begin(4800); //this seems to be causing the problem
  Serial.print("Hello there!");
}

void loop() {
  if(Serial.available() >=5) { //every command I send is 5 characters long
    for(int i=0; i < 5; i++) {
          inData[i] = Serial.read();
    }
    inData[i] = '\0';   // terminate the string
   
    if(strcmp(inData, "right")==0) { //right
        servo.write(135);
      }
      else if(strcmp(inData, "lleft")==0) { //left
        servo.write(40);
      }
     if(strcmp(inData, "strai")==0) { //straight
        servo.write(90);
    }
  }

}


Plus I've moved the servo stuff into the "if(Serial.available() >=5)" code block, there's no point running it until there are 5 chars to test.
______

Rob
Rob Gray aka the GRAYnomad www.robgray.com

draythomp

new softserial works pretty good for me.  I have a GPS and a serial display, but I have them both connected to digital pins so I can use the usb port to debug.  The thing I had to learn (the hard way) is that new softserial can lose characters if you don't attend to it often enough.  Also it is interrupt driven, but I haven't gone through the source to understand this completely.  Your problem matches the problems I had at first before I realized that you have to check it a lot and quickly or the characters get lost.  So what I had to do was only watch the GPS until I got the sentence from it that I needed then go look at the other port for what I needed there.  You'll notice that the GPS port will lose data while you're watching anything else.  Works pretty well that way.
Trying to keep my house under control http://www.desert-home.com/

Go Up