Razor 9DOF + GPS + arduino serial com with NewSoftSerial

Hello,

  I am trying to combine a Razor9dof, a GPS (ls20031) to an arduino (duemi).
I have configured the Razor with the ftdi cable. Works fine. Also connected to the arduino, on pin0, works fine. 
Here is the code:
void setup() {
  Serial.begin(57600);  
}

void loop() {
  if (Serial.available()) {
    Serial.print(Serial.read(), BYTE);
  }
}


However, using NewSoftSerial library doesnot work. I get lots of giberish as output.

My code is:
#include <NewSoftSerial.h>
NewSoftSerial nss (4,5);

void setup() {
  Serial.begin(115200);
  nss.begin(57600);
}

void loop() {
  if(nss.available()) {
    Serial.print(nss.read(),BYTE);
  }


I have the gps connected on pin2 and the razor on pin4. Using the above code (and changing pin 4,5 to 2,3); I get the nmea sentences alright.

Any ideas on why serial on pin0 works fine, but NewSoftSerial does not?

Regards,
Nicolas

Tags: newsoftserial, razor

Views: 1030

Reply to This

Replies to This Discussion

ok, dropping the razor baud rate to 38400 made it work.
new problem is with the gps; I don't get the whole sentences through newsoftserial. Through serial pin0, everything is fine.
Is newsoftserial the way to go?
Regards,
Nico
I use NewSoftSerial for a GPS logging application and an EM-406A SiRF modem - it works fine.

Code is like this:

// On the GPS Shield tie TX to Arduino pin 2, RX to pin 3 - works at 4800 baud (see GPSRATE constant)
// tie PWR to Arduino pin 4 ... when set to ground potential, it turns on the GPS module

// digital pin to apply power to the EM-406A
#define gpspowerpin 4

// baud rate for Arduino-GPS communication. The EM-406A device must already be configured to communicate at this baud rate.
#define GPSRATE 4800

NewSoftSerial gpsSerial = NewSoftSerial(2, 3);

// raw GPS NMEA sentences checksum results
int nmea_chksumerrors = 0;
boolean nmea_chksumerror = false;

// buffer to receive GPS output lines
#define BUFFSIZ 90 // plenty big
char buffer[BUFFSIZ];
int buffidx;


void Setup() {
gpsSerial.begin(GPSRATE); // GPS modem

if (gpspowerpin) {
pinMode(gpspowerpin, OUTPUT);
}

}

void Loop() {

// read GPS sentences from gpsSerial - the modem sends them automatically approximately once each second

if (!gpsSerial.available())
return;

// this is a blocking read. GPS sentences are output by the EM-406A every second or so
buffidx = read_gps_sentence(buffer, BUFFSIZ);


// handle bad NMEA input
if (nmea_chksumerror) {
// ...report checksum error ...
return; // leave loop()
}


// ... process the NMEA string in outbuf ...

}




// "blocking" reads a line of data from gpsSerial into buffer[]
// reading stops when bufsize-1 characters, or \r character are received
// if too many characters are received, additional characters are flushed (ignored) until a \r is received
// non-printing characters are not stored, except for space
// the buffer is returned null-terminated
// returns the number of characters placed in the buffer, excluding the trailing null byte
//
// NMEA checksum processing: sets nmea_chksumerror=true if the buffer contains an NMEA sentence with
// a checksum and the calculated checksum is different. Also updates nmea_chksumerrors
// which counts the number of lines with a checksum error.
int read_gps_sentence(char * outbuf, int bufsize) {
char c;
char idx;
byte chksum;
boolean calc_chksum = false;
boolean compare_chksum = false;

idx = 0;
nmea_chksumerror = false;

// loop forever
while (1) {

// place a null in the next position to be filled
outbuf[idx] = 0;

// BLOCK until next character from mySerial is available
c = gpsSerial.read();
if (c == -1) continue;

// when \r is found, return number of characters placed into the buffer
if (c == '\r') {

// checksum comparison, only for lines which appear to contain one
if (compare_chksum) {
// char chkstr[3];
sprintf(chkstr, "%02X", chksum);

if ((outbuf[idx-2] != chkstr[0]) || (outbuf[idx-1] != chkstr[1])) {
nmea_chksumerrors++;
nmea_chksumerror = true;
}
}

return idx;
}

// checksum calculation for NMEA sentences
if (c == '$') {
calc_chksum = true;
chksum = 0;
}

else if (c == '*') {
if (calc_chksum)
compare_chksum = true;

calc_chksum = false;
}

else {
if (calc_chksum) {
chksum = chksum ^ (byte)c;
}
}

// store printable character and advance the index to next location, ignore non-printables such as \n,
// or characters received after buffer is full
if ((c >= ' ') && (idx < (bufsize-1)))
outbuf[idx++] = c;
}
}
Hey,
Can you show me how you build up the program further if you want to use for example the acceleration measuring? I don’t know how to do it.
Thanks in advance
Johan
Ive had lots of issues with NewSoftSerial and GPS. My (NMEA style) GPS is running at a set preferred 38400 baud, and the newsoftserial would only receive the GGA sentences. Funny thing was that if i hooked the gps's RX line to the serial RX on the arduino, i could read the other (FMC) sentences as well... BUT they were missing formatting like the $ which is much needed when trying to decrypt the data via software. sadly i didn't find an answer.

still working on it though...
If the sentences are coming out of the GPS, suspect your code first!

Just make a small loop which receives a character (if available) received from the GPS via newsoftserial and output it with Serial.print. Use Arduino IDE's serial monitor to see the result.
I actually did just that. i should have been more clear

All the arduino was programed for was a single Newsoftserial port, and the standard serial port to relay the output to the arduino ide serial monitor.

when I used a sirfIII that was only communicating at 4800 baud, it worked fine

when i changed newsoftserial buad to 38400, hooked it up to the faster 38400 buad 5hz gps, I only get the GGA sentences.

when hooking the gps RX to the arduino newsoftserial RX (non-sensical lol), i get the FMC and GGA sentences.. just missing the $'s and some of the trailing data.


my conclusion is that NewSoftSerial isn't stable at 38400 baud???
The GPS is overflowing the receive buffer (data overrun) because there is no flow control, and your program cannot run fast enough to take the characters out of the buffer. My GPS runs at 4800, if I try to run at faster baud rate I start getting CRC errors due to lost characters.

See http://arduiniana.org/libraries/NewSoftSerial/ for a description of the overflow() function, and future RTS/CTS flow control.

You could play with larger buffer size _NewSS_MAX_RX_BUFF in NewSoftSerial.h - default is 64 characters.

Consider also that Serial.print is introducing additional work for the processor and delays - although not bit-banged like NewSoftSerial. The less you echo to the computer the more quickly you can read the NewSoftSerial port.
very interesting indeed! i was not aware of any of that!

please excuse my ignorance though - i am still new to this. would increasing buffer size have negative consequences? (im not at home right now to demo it) also, i didn't understand the implementation of the last bit you said. Were you suggesting that a serial.print was only called once or twice a second? or not at all possibly?

thanks!
Increasing the buffer size reduces the amount of memory storage available for other things (variables and stack) which might or might not be an issue for your application. If you can afford a large buffer, make it large enough to hold the largest possible NMEA sentence, multiple sentences if possible. As you increase the buffer size, you should be able to raise the baud rate too - provided your application reads the data out of the NewSoftSerial buffer quickly enough.

FYI the buffer used by Serial.read and the Arduino RX pin is 128 bytes, plus Serial uses the Atmega's built-in UART which is more efficient than the NewSoftSerial technique which is more CPU-intensive.

GPS modems can be configured to output only when polled, or more usually to output automatically at regular intervals. Mine outputs $GPRMC once per second along with $GPGGA and/or $GPGSA, $GPRMC. GGA is the longest at almost 70 characters, RMC is just over 60 characters.

To handle the occasional overflow, make sure your application calculates the checksum and compares it for each NMEA sentence (discard sentences which contain errors) and that it resets when \n$ is received (which signals the start of a new sentence).
Thank you very much for taking to time to help me out!! very informative!!!!
To calculate accereleration, and acceleration vector, you will need to at least know distance travelled. www.movable-type.co.uk/scripts/latlong.html shows you how to calculate distance between two lat-lon points.

RSS

Social Networking

Contests

Season Two of the Trust Time Trial (T3) Contest has now begun. The fourth round is an accuracy round for multicopters, which requires contestants to fly a cube. The deadline is April 14th.

A list of all T3 contests is here

Groups

Advertisement

© 2013   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service