Basic electron serial reading fails, works on photon

Is there a known problem with the Electron and reading serial?

I’m using a really basic sketch to read off of a GPS device. I simplified it to a test to probe that there are problems on the Electron. I’m running this sketch on a Photon (it works) and the Electron (and it fails as seen). It looks almost like there are missing characters.

Output from Electron (running 0.4.8):

35N166,G11,,*V034,,7,,1,7,
45,,75
,4314L8.0A$GPRMC,023506.00,A,4531.97180,N,12241.94173,W,1.271
T,KP0.23.M,S,0,8
43,,03
260790$,,,802G14,5

Output from Photon (running 0.4.9):

$GPGSV,4,3,15,24,58,259,26,25,07,295,,28,15,105,26,32,05,330,*7F

$GPGSV,4,4,15,46,34,146,,48,37,194,,51,35,159,*40

$GPGLL,4531.96822,N,12241.94001,W,022932.00,A,A*7F

And here’s the code:

void setup()
{
  Serial.begin(115200);
  Serial1.begin(9600);
  delay(1000*5);

}

void loop()
{
    if (Serial1.available() ) {
        char c = Serial1.read();
        if (c == 10 || c == 13) {
            Serial.println();
        } else {
            Serial.write(c);
        }
    }
    
}

Going with the theory that printing was too slow, I changed the code to fast-buffer (borrowing some of the Tracker code). Still failing.

Sample output:

$GPRMC,025403.00,A,4531.97434,N,12241.94374,W,0.902*G96
25N44.,G6,44G,1,,,,$2,91,9G13,5,4,,,9G92W0
$GPRMC,025404.00,A,4531.97396,N,12241.94273,W,0.581
T4KP0.13.M,A0,3
44,,1,D4,7152
,1,2,,G,,,$3,707$GPRMC,025405.00,A,4531.97381,N,12241.94282,W,0.4391

Code:

#define MAX_LINE_LENGTH 160
int lineidx = 0;
char currentLine[MAX_LINE_LENGTH];

void setup()
{
  Serial.begin(115200);
  Serial1.begin(9600);
  delay(1000*5);

}

void loop()
{

    if (Serial1.available() ) {
        char c = Serial1.read();
        if (c == '\r' || c == '\n') {
            Serial.println(currentLine);
            currentLine[0] = 0;
            lineidx = 0;
        } else {
            currentLine[lineidx++] = c;
            currentLine[lineidx] = 0;
        }
    }
    
    if (lineidx - 2 > MAX_LINE_LENGTH) {
        Serial.println("string too long, resetting.");
        currentLine[0] = 0;
        lineidx = 0;
    } 
    
}

Okay. Thanks mostly to this thread I found out that I should use an inner loop to fetch the serial, rather than fetching one character on each loop().

Here’s the code I ended up using:

void loop() {
    if (Serial1.available() > 0 && Serial1.peek() != '$') {
        while (Serial1.peek() != '$' && Serial1.peek() != -1)
            Serial1.read(); // empty the buffer up to a new $ or end of buffer
    } else if (Serial1.available() > 0 && Serial1.peek() == '$') {
        while (Serial1.peek() != '\r' && Serial1.peek() != '\r') {
            char c = Serial1.read();
            if (gps.encode(c)) {
                onValidGpsSentence();
            }
        }
    }   
}

The documentation says both the Electron and Photon have the same serial buffer size (64 bytes), I assume that perhaps there’s more housekeeping work on the Electron?

This is advisable under any circumstance and on any platform to read all the data present.

So this should be part of most code that’s dealing with serial communication

  ...
  while (Serial1.available())
  {
    int x = Serial1.read();
    doStuffWith(x);
  }
  ...

Once you are going up with baud and data rate on the Photon you’ll see the limited buffer there too.

Yeah, ScruffR, sort of a “TIL”, I guess. As I said I assume the housekeeping on the Electron is longer, so I can’t rely on the buffer. It’s just a different mental model. Reading a sentence at a time seems to be really successful.

2 Likes