Serial communication; lost data; GPS & Nano; serial.Event()

I am using the Serial Event example from Arduino Reference to receive the output from a Neo6m GPS module to a Nano. With the unmodified example sketch the sentences are received intact and complete.

When I add a few statements in the loop data is lost. I'd like to understand why that happens and how to fix it.

The physical setup is:
GPS VCC to Nano 5v
GPS TX to Nano RX (GPS RX unconnected)
Nano connected to laptop via USB cable
9600 baud rate at both GPS and monitor (they have to be the same as they are both connected to the same hardware serial)

Using hardware serial, not software serial. So the serial is serving two separate devices -- the GPS module and the IDE monitor. Am I asking for problems doing that? The sketch does not send anything to the GPS and does not receive anything from the monitor.

Below is the sketch with my addition of some steps to measure the duration between successive received complete sentences and the length of each sentence. In the first case those statements are commented out and so are not effective. The data appears on the monitor perfectly (first image from monitor).

When I un-comment those statements, some data is lost (second image from monitor). There should be three GSV sentences, but the second and third are stitched together. This is regular -- same output on the monitor every GPS cycle.

Is it possible the data is lost between the Nano and the monitor rather than between the GPS and the Nano?

I have read robin2's excellent tutorial on serial comms.

  Serial Event example
  When new serial data arrives, this sketch adds it to a String.
  When a newline is received, the loop prints the string and clears it.
  A good test for this is to try it with a GPS receiver that sends out
  NMEA 0183 sentences.
  NOTE: The serialEvent() feature is not available on the Leonardo, Micro, or
  other ATmega32U4 based boards.
  created 9 May 2011
  by Tom Igoe
  This example code is in the public domain.

String inputString = "";         // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete
int mark1, mark2;

void setup() {
  // initialize serial:
  // reserve 200 bytes for the inputString:

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
//    mark2 = millis();
//    Serial.print(mark2-mark1);
//    Serial.print("ms; ");
//    Serial.print(inputString.length());
//    Serial.println("bytes");
    // clear the string:
    inputString = "";
    stringComplete = false;
//    mark1 = mark2;

  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char);
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;

Monitor image when my statements are commented out (no lost data):

Monitor when my statements are not comments (lost data):

Got it in one

Do not connect 2 devices to a single serial port and expect it to work

As a side note, using seriaEvent() is generally a waste of time. You might just as well use Serial.available() to determine that Serial data is available to read

1 Like

This is likely a timing problem. Experiment with higher baud or consider using I2C. SPI does not ensure the data you get is correct, I2C does it after every byte sent. I2C also has clock stretching to equalize slump in speed.

Do not connect 2 devices to a single serial port and expect it to work


GPS TX to Nano RX (GPS RX unconnected)

The sketch does not send anything to the GPS and does not receive anything from the monitor.

In this configuration @HillmanImp should be fine if he disconnects the GPS from the RX pin when downloading new code.

In my opinion output to the monitor and input from another device on hardware serial is preferable to using software serial if you can get to the wires for loading code.

Well, i am handling an ir data line on an attiny rx due to lack of free pins. And because i am lazy after 100 flash cycles, the ir sensor just stays where it is :smiley: not recommended, but works... atleast for me and a ir sensor

In my opinion output to the monitor and input from another device on hardware serial is preferable to using software serial if you can get to the wires for loading code.

Depends on the project / sketch. You wont have fun using Serial when your sketch has a higher cpu load. I2C would be the deal.

This has been a useable arrangement for me. The monitor is only used for debugging messages and not a permanent part of the working project.

But to take it out of the equation, I connected an HC-05 Bluetooth module to the Nano. Now my print statements go from the sketch via software serial to the HC-05 to the laptop to the IDE monitor.

The results are much the same as when using the hardware serial to the monitor. The unedited example sketch delivers perfect sentences; my edited sketch delivers corrupted sentences.

I've played around and I reckon it's the fact that I'm printing long sentences. Even tho the Arduino operates much faster than the serial connection with the GPS module, if I send long sentences via serial (hardware or software) then I've just dragged the Arduino pace down to that of the GPS to serial. Is there sense in that idea?

I think I'll accept in faith that the GPS output is being correctly read and have my code extract the parameters I want and forget about print statements to oversee things. If the parameters are sensible and reliable, then that's success.

Did you remember to jack up the baud rate on the serial port after you separated GPS from monitor?

No. I can see the sense in doing that. I would have to also change the baud rate on the HC-05. I'll see if I can do that tomorrow and let you know the outcome. That's the software serial. I want the GPS to remain at 9600.

Software serial isn't reliable at the higher baud rates - 38400 is about as much as you can get, but anything greater than the 9600 for the GPS will help.

This is of course why it's more conventional to put the printing on the hardware serial.

Thanks. I'll see how it performs at 38400.

Why is it that in your original hardware serial configuration with the GPS on RX and TX going to the monitor you are at 9600 baud?

I think you could be using 115200 or whatever highest rate the gps and monitor can support. One of the advantages of using hardware serial instead of software serial is the higher baud rates supported.

No other reason than I prefer to leave the GPS at its default configuration.

At 9600 each batch of sentences takes 500ms to transmit. I don't need it to be fast. The sketch should be able to do all I want in the remaining 500ms. I actually only need the first two sentences.

Thanks for everyone's contributions.