Adafruit Ultimate GPS and 28X2

I have been going blue in the face here today trying to get a PICaxe 28X2 to parse strings from the Adafruit Ultimate GPS module. I can see that the GPS module is producing valid NMEA strings, but all attempts to read them using PIXaxe serin() commands seem to produce garbage. It looks like a baud rate mismatch, but I've tried most baud rate permutations on the 28X2. I even tried setting the GPS module to 4800 baud, but it seemed to ignore the command.

This is the last step in a complex multi-processor project, and everything else is working just fine. The GPS is to be used solely for a time reference.

If anyone had an avenues to suggest that I could try. Or has crossed this bridge?
 
I'm not familiar with that GPS module but I found it helpful in the past to run a 16MHz PICAXE clock for 9,600 baud serin, also is the serial logic set for True? I guess there's a lot of NMEA messages, are you using a qualifier to focus on what you want?

Think you'd need to post your code for broader support.
 
You are using PICAXE foreground serial reception for 9600 baud data, which is unlikely to ever work reliably.

Several years ago, I developed code for a 28X2 that reliably receives and decodes NMEA data from a GPS module. I documented it in the 'User Projects - Miscellaneous' section of the forum - here.
 
If anyone had an avenues to suggest that I could try. Or has crossed this bridge?
+1 upvote for inglewoodpete's post #3.

Using the X2 chip's background serial receive feature for HSERIN will likely be able to capture all the NMEA strings from the GPS and write them to a circular buffer in the scratchpad RAM.

Your main program will spend part of it's time checking the scratchpad RAM waiting for the specific NEMA strring(s) you are interested in to arrive and then running the code for that string. So long as your code to process the strings is short enough you won't miss any strings.
 
I'm not familiar with that GPS module but I found it helpful in the past to run a 16MHz PICAXE clock for 9,600 baud serin, also is the serial logic set for True? I guess there's a lot of NMEA messages, are you using a qualifier to focus on what you want?

Think you'd need to post your code for broader support.
At present – to debug, various decoding methods having failed – it's just a readback:

read_gps:
sertxd("rdgps", CR, LF)
raw_loop:
serin [5000, gps_timeout], GPS_PIN, N4800_8, clk_temp
sertxd(clk_temp)
goto raw_loop

I will look at. Inglewood Pete's approach today. Many thanks for replies.
 
You are using PICAXE foreground serial reception for 9600 baud data, which is unlikely to ever work reliably.

Several years ago, I developed code for a 28X2 that reliably receives and decodes NMEA data from a GPS module. I documented it in the 'User Projects - Miscellaneous' section of the forum - here.
Thank you. I was hoping someone had coded around this issue. I will study in details.

Steve
 
At present – to debug, various decoding methods having failed – it's just a readback:

read_gps:
sertxd("rdgps", CR, LF)
raw_loop:
serin [5000, gps_timeout], GPS_PIN, N4800_8, clk_temp
sertxd(clk_temp)
goto raw_loop

I will look at. Inglewood Pete's approach today. Many thanks for replies.
PS The N4800_8 is wrong here: I was trying to set the GPS module to 4800 baud in other code, but it didn't seem to comply.
 
Hi Steve,
The combination of hserial and scratchpad is one of my top reasons when choosing an X2 over an M2. On the other hand, the code below seems to be reliable with a lowly 08M2, so I guess you could adapt it for X2 and serin too. :)

Not sure if you'd get overruns with scratchpad with the amount of streaming noise I've seen from NMEA in the past. My simple code saves a lot of parsing but obviously doesn't include an error check.

For my NEO-M8N projects, I ditched listening to variable length ASCII NMEA messages and used their UBX protocol instead, it worked a treat and has an easy Fletcher-16 checksum for data integrity. Suddenly the serial goes quiet and you only get responses to what you request. The replies are fixed length and byte values, not char[?]. Also, with the numbers I found it much easier to set times and alarms with my RTC etc.

Code:
#picaxe 08M2 
#no_data
#no_debug
setfreq M16
#terminal 19200
Main:
    do
        sertxd(cr,lf,"Waiting for data")
        bptr = 100
        'The line below captures the 1st 6 bytes of the $GPGGA message containing the time in ASCII hhmmss.
        serin [5000],c.2,T9600_16,("$GNRMC,"),@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
    loop until bptr = 106
    bptr = 100
    'This outputs the text to the terminal.
    sertxd(cr,lf,"The time is ",@bptrinc,@bptrinc,":",@bptrinc,@bptrinc,":",@bptrinc,@bptrinc)
    
    goto Main

Screenshot from 2026-03-21 13-57-17.png

Regards, Alan
 
Hi Steve,
The combination of hserial and scratchpad is one of my top reasons when choosing an X2 over an M2. On the other hand, the code below seems to be reliable with a lowly 08M2, so I guess you could adapt it for X2 and serin too. :)

Not sure if you'd get overruns with scratchpad with the amount of streaming noise I've seen from NMEA in the past. My simple code saves a lot of parsing but obviously doesn't include an error check.

For my NEO-M8N projects, I ditched listening to variable length ASCII NMEA messages and used their UBX protocol instead, it worked a treat and has an easy Fletcher-16 checksum for data integrity. Suddenly the serial goes quiet and you only get responses to what you request. The replies are fixed length and byte values, not char[?]. Also, with the numbers I found it much easier to set times and alarms with my RTC etc.

Code:
#picaxe 08M2
#no_data
#no_debug
setfreq M16
#terminal 19200
Main:
    do
        sertxd(cr,lf,"Waiting for data")
        bptr = 100
        'The line below captures the 1st 6 bytes of the $GPGGA message containing the time in ASCII hhmmss.
        serin [5000],c.2,T9600_16,("$GNRMC,"),@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
    loop until bptr = 106
    bptr = 100
    'This outputs the text to the terminal.
    sertxd(cr,lf,"The time is ",@bptrinc,@bptrinc,":",@bptrinc,@bptrinc,":",@bptrinc,@bptrinc)
   
    goto Main

View attachment 27027

Regards, Alan
Thanks so much for posting this. I will feed it into my machinations :)

(I had not heard of the UBX protocol. Something to be researched.)
 
You are using PICAXE foreground serial reception for 9600 baud data, which is unlikely to ever work reliably.

Several years ago, I developed code for a 28X2 that reliably receives and decodes NMEA data from a GPS module. I documented it in the 'User Projects - Miscellaneous' section of the forum - here.
Thank you inglewoodpete. I used your suggested method of hserin() and, after a bit of struggling, it's working well. That is certainly the way to do it. I remember reading your article about the public clock when I first started researching this project, but I had forgotten about it. And with all the other stuff that my program does (sound tracks, text strings from eeprom, OLED display and so on), managed to get it all onto a 28X2 with 500 bytes to spare.

Many thanks indeed!
 
This example help ?

do

Date_Time:
serin [1000],3,T4800,b1',b2,b3,b4,b5,b6
sertxd ("Time ",b1,b2,b3,b4,b5,b6,13,10)

Fix:
serin 3,T4800,("$GPRMC,"),#b0,#b0,b1
sertxd ("Fix ",b1,13,10)

Latitude:
serin 3,T4800,("$GPRMC,"),#b0,#b0,b1,#w1,#w2
sertxd ("Latitude ",#w1,46,#w2,"S",13,10)

Longitude:
serin 3,T4800,("$GPRMC,"),#b0,#b0,b1,#b0,#b0,b0,#w1,#w2
sertxd ("Longitude ",#w1,46,#w2,"E",13,10)

loop
 
I love the way that an 08M2 can not only pick out fixed or dynamic serin delimiters but can pull out whole multi digit ASCII decimal numbers and poke them into byte / word variables: ALL in one line of code !
"Go Them 8 PIN DIL packages"
;)
 
Back
Top