Hi, I'm seeing weird behaviour on a Raspberry Pi Pico setup (Earle F. Philhower, III board data), I'm reading GPS data from a SimCOM A7670E GMS/GNSS device over UART1, Arduino Serial 2. When I try to read the location string it always seems to be truncated at 17 characters.
The code I'm using is below including the AT command to request the location data:
std::string temp = "";
Serial2.println("AT+CGPSINFO"); // Request location
char c;
while (Serial2.available())
{
c = Serial2.read();
temp += c;
}
This returns: +CGPSINFO: XXXX.X (X replaces my location digits),
This should return something like: +CGPSINFO: XXXX.XXXXXX,N,YYYYY.YYYYY,W,270924,162032.00,114.8,0.175,
Now here's the weird thing - it works perfectly with all ESP32 devices I have tried!
Any ideas ?
You’re having trouble reading GPS data from your SimCOM A7670E with your Raspberry Pi Pico, but it works fine with your ESP32 devices. Here are a few things to try:
Check the Baud Rate: Make sure the baud rate on the Pico matches the GPS module.
Add a Delay: After sending the "AT+CGPSINFO" command, add a delay (e.g., delay(500)) to give the GPS module time to respond.
Read Until Line End: Modify your reading loop to capture data until you hit a newline character, which indicates the end of the response.
Debug Output: Print out the characters you receive to see exactly what data is being captured, which can help identify if it's being truncated.
The serial connection is what, 9600, 4800 baud? So one character every 1-2ms? So if your loop executes even a little faster than that (which it will, by orders of magnitude) it will eventually consume all the characters that accumulated in the serial Rx buffer before you got to that loop. And it'll exit... before the next character arrives a millisecond or two later.
ChatGPT's advice above aside, perhaps try adding a small delay inside the loop that's triggered when no characters are available. Something like:
while (Serial2.available())
{
c = Serial2.read();
temp += c;
if( !Serial2.available() ) {
delay(3); // allow a bit of time for any possible next character in the line
}
}
I have Serial1 and Serial2 connected to separate com/tty ports on a PC each running Putty. Using Putty I paste a long string of characters into the Serial2 Port on the Pi Pico, the response sent back via Serial1 is a truncated version of the data originally sent. An ARM Cortex M0+ @ 133MHz should be capable of that I would think !
Update - it truncates after 32 bytes, the size of the Pico serial buffer.
Interesting. I was able to more or less duplicate what you were seeing with 2 Picos.
Pico A first sent a 74 character string once a second to Pico B.
When Pico B did the "got a character, send a character" in the loop, it truncated early. So I had it buffer up characters until there were none for 5ms or it saw a LF. Only then would it print the string. That worked.
I then tried the setTimeout and readStringUntil method. Which as you've seen, doesn't work. Hmm. It really ought to, as it's pretty much what I was doing by hand. I need to go for a walk and think about this. I'm probably missing something obvious.
The only difference is in the latter, each iteration of loop takes at least 500ms. In that 500ms, Pico A could have fired off a complete message. But since the sketch isn't looking at the input for 500mS, it'll all stack up in the Rx buffer. And once it's full, the rest of the message is discarded.
In the former, the only time Pico B does a delay is once Pico A has stopped sending. So the Rx buffer never gets a chance to fill up and Pico B gets the full message.
That does indeed fix it for the serial to serial tests, however it "mostly" works for the GSM/GNSS module - i.e. there are times when it doesn't, and it seems to be random - I even tried adding RTS/CTS flow control without sucess.
I really appreciate your help on this but I think I'll try porting my app to the Pico from ESP32 some other time. Unpredictable is worse than not working at all for me I'm afraid. I may try it with the Pico SDK on native C in case it's an issue with the Arduino framework - as a test.