problem using GP-135T and Serial Monitor.

I’m having a problem with the GP-635T gps receiver. I’m coding w/Arduino 1.6.4 on a Windows 7 system. I’m using an Arduino UNO R2 board.

The following code works as expected:

    #include <SoftwareSerial.h>
    #define BUFFERSIZE 256
    SoftwareSerial _gps(11, 10);
    char Buffer[BUFFERSIZE];

    void setup() {
      _gps.begin(9600);
      Serial.begin(9600);
    }

    void loop() {
      int bufferLength = 0;

      while (_gps.available()) {
        //load the gps data stream into the buffer
        Buffer[bufferLength++] = _gps.read();
      }

      //if data was found, zero terminate the stream
      if (bufferLength > 0) {
        Buffer[bufferLength] = 0x00;
      }

      //dump the buffer to the serial monitor
      if (bufferLength > 0) {
        Serial.write(Buffer);
      }
    }

Serial Montor output:

$GPRMC,,V,,,,,,,,,,N*53
    $GPVTG,,,,,,,,,N*30
    $GPGGA,,,,,,0,00,99.99,,,,,,*48
    $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
    $GPGSV,1,1,03,09,,,24,17,,,08,18,,,24*74
    $GPGLL,,,,,,V,N*64

However, if I modify the last part of the loop method as shown below I nothing but ‘$’ characters displayed

void loop() {
      // [...]
      if (bufferLength > 0) {
        //Serial.write(Buffer);
        while(true) {
          for(int i = 0; i < BUFFERSIZE; i++) {
            char c = Buffer[i];
            if(c == '\0') { break; }
            Serial.write(c);
          }
        }
      }
    }

Am I missing something here? Thanx,

        while(true) {
          for(int i = 0; i < BUFFERSIZE; i++) {
            char c = Buffer[i];
            if(c == '\0') { break; }
            Serial.write(c);
          }
        }

What is the purpose of this? If Buffer is a NULL terminated string, there is absolutely no point in printing it character by character. There is no point in putting a for loop side a while loop.

Other than the uselessness of this code, you have hidden the rest of the code in loop(), so we can only assume that you have something wrong before this useless code.

the purpose of the code snippet was to illustrate the problem I was having. of course the code is “useless” - it was stripped down in order to highlight the problem without including a lot of unnecessary clutter. i expected both approaches to produce the same result but they didn’t and it wasn’t clear to me why. in some “real” code i’m developing, i try to walk through the buffer in order to parse it. i’ve tried several approaches and each time, i end up getting mangled output. this code snippet was an example of the type of behavior i was seeing. the idea was, if i can understand the nature of this problem, it will help me with the other issues i’m having. that’s why i posted the question. as for hiding the “rest of the code in loop()”, i simply showed the change. i saw no need to reenter the entire script just to illustrate a single (and simple) change.

that said, you did offer a useful hint. i removed the outer while loop and it worked. not sure what i was thinking doing that but it eliminated at least one problem.

Good you found a useful hint in PaulS' remarks,

I agree with Paul that it makes it easier to understand/debug if we have the whole sketch or better strip down to a minimal sketch that still shows the problem. Often the stripping process reveals a lot of insight in the code. What helps for me is using paper and pencil and "play the processor" to understand what steps are needed.

Can you please post your solution for future reference?

read my original post. the first code block is the entire script. The second code block, not counting the serial output details, shows the change to that script.

i wrote "if I modify the last part of the loop method as shown below " … that is, i modified the last part of the loop method. i didn’t change anything else with the original script.

why repost the entire script when all I did was make a very small change to the original?

secavian: why repost the entire script when all I did was make a very small change to the original?

To have an exact copy of what you have. I have made too many assumptions about others (missing) code. Not seldom there were small changes in the "unchanged" part. That happens if you're on a forum for long.

(and yes you're right about the first code, that is complete, sorry)

i’ve posted questions in different forums over the years often enough to not require the reader to make assumptions. at least it try. all of which is besides the point. my original post did not illustrate the problem i’m having. i have no idea what i was thinking when i posted that for loop nested in the while loop. what follows does illustrate the problem. Here is the corrected code

#include <SoftwareSerial.h>
#define BUFFERSIZE 256
SoftwareSerial _gps(11, 10);
char Buffer[BUFFERSIZE];

void setup() {
  _gps.begin(9600);
  Serial.begin(9600);
}

void loop() {
  int bufferLength = 0;

  while (_gps.available()) {
    //load the gps data stream into the buffer
    Buffer[bufferLength++] = _gps.read();
  }

  //if data was found, zero terminate the stream
  if (bufferLength > 0) {
    Buffer[bufferLength] = 0x00;
  }

  //dump the buffer to the serial monitor
  if (bufferLength > 0) {
    Serial.write(Buffer);
    //Serial.println();
  }
}

once again, if i run this code as posted above i get valid output to the serial monitor.

$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64

however, if i uncomment the Serial.println(); statement on line 27, i get mangled output. no idea why. this is the issue i was trying to resolve.

$GPGGA
,,,,,,0,00,
99.99,,,,,,*48

$GPGSA,A,1,,,,,
,,,,,,,,99.99,99.99
,99.99*30
$GPGSV,2,1,
06,01,,,26,05,,,10,09,,,
25,12,,,24*76
$GPGSV,2,2,0
6,13,,,24,27,,,22*7E
$GPGLL,,
,,,,V,N*64

any thoughts?

however, if i uncomment the Serial.println(); statement on line 27, i get mangled output. no idea why. this is the issue i was trying to resolve.

That happens because you are printing the data in less than full sentences. Printing a carriage return and line feed, after printing part of a sentence, and then printing the rest of the sentence will do exactly that.

You'll notice that every sentence ends with a * followed by some digits and a carriage return and line feed. The number that follows the * is a checksum that you should compare to the checksum you compute to determine that the sentence was received correctly.

The * also indicates that the end of the sentence is near (the checksum is, I'm pretty sure, always 2 digits or less).

You should only print the sentence when you have received a complete (and valid) sentence.

that was the problem. the following code works correctly now whether or not i comment out the Serial.println(); statement on line 15. my key error was to assume that the when _gps.available() returned a value > 0, the _gps queue would only have complete sentences.

#include <SoftwareSerial.h>

#define BUFFERSIZE 256
SoftwareSerial _gps(11, 10);
char Buffer[BUFFERSIZE];

void setup() {
  _gps.begin(9600);
  Serial.begin(9600);
}

void loop() {
  getNextSentence();
  Serial.write(Buffer);
  Serial.println();
}

void getNextSentence() {
  int bufferLength = 0;
  while(1) { // endless loop to allow gps data to arrive in spurts
    char c = 0x00;
    
    //read whatever is in the gps output queue
    while (_gps.available()) {
      c = _gps.read();
      Buffer[bufferLength++] = c;
    }
    
    //sentences terminate with <CR><LF> (\r\n) chars
    if(c == '\n') {
      //zero terminate the stream
      Buffer[bufferLength] = 0x00;
      return;
    }
    
    //if we *didn't* find a \n char, we don't have a complete
    //sentence, so keep reading.
  }
}