GPS Timeout
David Gitz
Posts: 4
Hi, I'm working on a robotic application and am having the following problem. Besides other sensors, I have a GPS sensor on board. My problem is that in my current code, the program waits for a GPS message before continuing. And sense the GPS is only communicating at 4800 baud it really reduces the execution time of the program. What I would like to do is have this running in the background and the main program would keep running, and when a new message comes in it would get updated but not pause execution. This is probably a misunderstanding of how to use the FullDuplexSerial library file, since this is the reason why it uses another cog to do the uart. I wrote the getgpsrxbuffer function listed at the bottom. Here is my example code:
(For simplicity sake I'm not showing any irrelevant info).
con
GpsBaudRate = 4800
GpsMode = %0000
gpsrx = 2
txPin = 4
rxPin = 3
ComBaudRate = 115200
ComMode = %0000
waitdelay = 100_000
var
long stack[noparse][[/noparse]9]
byte gpsrxbuffer[noparse][[/noparse]50]
byte comrxbuffer[noparse][[/noparse]50]
obj
gpsuart: "Fullduplexserial" 'uart
comuart: "FullDuplexSerial" 'uart
pub init | cogsused
cogsused := cogsused + comuart.start(rxPin,txPin,ComMode,ComBaudRate)
cogsused := cogsused + gpsuart.start(gpsrx,PINNOTUSED,GpsMode,GpsBaudRate)
testsensor
PUB testsensor
repeat
getgpsrxbuffer(@gpsrxbuffer
comuart.str(@gpsrxbuffer)
waitcnt(waitdelay + cnt)
pri getgpsrxbuffer(rxbuffptr) | i
'' Retrieve rx stream into a data block. Fills the data block until a carriage
'' return is retrieved.
i := 0
repeat until (rxbyte := gpsuart.rxcheck) == 13
if rxbyte > 31 AND rxbyte < 126
byte[noparse][[/noparse]rxbuffptr] := rxbyte
i++
byte[noparse][[/noparse]rxbuffptr][noparse][[/noparse]i++] := 0
Thanks!
David
(For simplicity sake I'm not showing any irrelevant info).
con
GpsBaudRate = 4800
GpsMode = %0000
gpsrx = 2
txPin = 4
rxPin = 3
ComBaudRate = 115200
ComMode = %0000
waitdelay = 100_000
var
long stack[noparse][[/noparse]9]
byte gpsrxbuffer[noparse][[/noparse]50]
byte comrxbuffer[noparse][[/noparse]50]
obj
gpsuart: "Fullduplexserial" 'uart
comuart: "FullDuplexSerial" 'uart
pub init | cogsused
cogsused := cogsused + comuart.start(rxPin,txPin,ComMode,ComBaudRate)
cogsused := cogsused + gpsuart.start(gpsrx,PINNOTUSED,GpsMode,GpsBaudRate)
testsensor
PUB testsensor
repeat
getgpsrxbuffer(@gpsrxbuffer
comuart.str(@gpsrxbuffer)
waitcnt(waitdelay + cnt)
pri getgpsrxbuffer(rxbuffptr) | i
'' Retrieve rx stream into a data block. Fills the data block until a carriage
'' return is retrieved.
i := 0
repeat until (rxbyte := gpsuart.rxcheck) == 13
if rxbyte > 31 AND rxbyte < 126
byte[noparse][[/noparse]rxbuffptr] := rxbyte
i++
byte[noparse][[/noparse]rxbuffptr][noparse][[/noparse]i++] := 0
Thanks!
David
Comments
There are several ways to do this. One would be to put this code in a separate cog.
Another would be to use rxcheck diferently:
This will test (rxcheck) to see if a character has been received. If it sees a -1, then it skips adding the byte to the buffer. If it is not a -1, it adds they byte to the buffer. Then you can look at the byte to see if the byte received was a carriage return character and if it is, process the buffer and then clear it.
pri getgpsrxbuffer(rxbuffptr) | i,flag
'' Retrieve rx stream into a data block. Fills the data block until a carriage
'' return is retrieved.
flag := 0
i := 0
repeat while ((rxbyte := gpsuart.rxcheck) <> -1 AND flag == 0)
if rxbyte > 31 AND rxbyte < 126
byte[noparse][[/noparse]rxbuffptr] := rxbyte
i++
if rxbyte == 13
flag := 1
'uart.tx(rxbyte)
byte[noparse][[/noparse]rxbuffptr][noparse][[/noparse]i++] := 0
return 1
And in my main program I did this:
pri datapacketmode | i, j, value1, value2, value3, Ax, Ay, Az, CmpDegrees, GyroYaw, GyroPitch, gpsflag
comuart.str(@dpt)
repeat' until strcomp(@rxbuffer,string("done"))
gpsflag := 0
!outa[noparse][[/noparse]ledpin1]
getcomrxbuffer(@comrxbuffer)
gpsflag := getgpsrxbuffer(@gpsrxbuffer)
if gpsflag
waitcnt(waitdelay / 100 + cnt)
comuart.str(@gpsrxbuffer)
waitcnt(waitdelay + cnt)
Now it looks like I'm not getting a delay but I only get part of the gps message, sometimes its 15 characters long, sometimes just a couple comma's in a row.
It looks like you are trying to process the buffer as characters are received. That will complicate things. Wait till you have a full line (when you see the CR), then do a repeat loop through the buffer to process the string.
Also, as Mike said, the default buffer is rather small, you you either need to make it larger, or you will need to call getgpsrxbuffer many times a second so you do not miss characters.