[ntp:questions] Sure GPS: Programming it now works

Terje Mathisen "terje.mathisen at tmsw.no" at ntp.org
Tue Apr 5 07:06:20 UTC 2011


unruh wrote:
> On 2011-04-04, Terje Mathisen<"terje.mathisen at tmsw.no">  wrote:
>> Terje Mathisen wrote:
>>> I.e. the proper programming setup seems to be:
>>>
>>> 1: Listen to incoming chars.
>>>
>>> 2: After a CRLF sequence, start a timer: If a new char arrives within
>>> less than 40 ms, goto 1.
>>>
>>> 3: Send '0', start timer waiting for CD to drop.
>>>
>>> 4: If CD drops before any new chars arrive, we are ready to send our
>>> command, so send it out before the 100 ms gps timeout.
>>
>> I've written a tiny program to do exactly this and this is the output:
>>
>> c:\>nmea-mtk
>> BaudRate = 9600, ByteSize = 8, Parity = 0, StopBits = 0
>>
>> Waiting for idle time
>> $GPGGA,190635.000,5955.1055,N,01038.4217,E,2,7,1.18,11.6,M,40.8,M,0000,0000*65<0
>> x0d><0x0a>
>> Found a 50 ms opening
>> CD_on
>> CD is now off, ready to send cmd
>> $PMTK301,2*2E
>>
>> Waiting for idle time
>> $GPGGA,190636.000,5955.1054,N,01038.4217,E,2,7,1.18,11.4,M,40.8,M,0000,0000*65<0
>> x0d><0x0a>
>> $PMTK001,301,3*32<0x0d><0x0a>
>> Found a 50 ms opening
>> CD_on
>> CD is now off, ready to send cmd
>> $PMTK313,1*2E
>>
>> Waiting for idle time
>> $GPGGA,190637.000,5955.1054,N,01038.4218,E,2,7,1.18,11.2,M,40.8,M,0000,0000*6D<0
>> x0d><0x0a>
>> $PMTK001,313,3*31<0x0d><0x0a>
>> Found a 50 ms opening
>> CD_on
>> CD is now off, ready to send cmd
>> $PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0*29
>> $GPGGA,190638.000,5955.1054,N,01038.4218,E,2,7,1.18,11.0,M,40.8,M,0000,0000*60<0
>> x0d><0x0a>
>> $PMTK001,314,3*36<0x0d><0x0a>
>> $GPGGA,190639.000,5955.1055,N,01038.4219,E,2,7,1.18,10.8,M,40.8,M,0000,0000*68<0
>> x0d><0x0a>
>> $GPGGA,190640.000,5955.1056,N,01038.4220,E,2,7,1.18,10.6,M,40.8,M,0000,0000*61<0
>> x0d><0x0a>
>> $GPGGA,190641.000,5955.1057,N,01038.4220,E,2,7,1.18,10.4,M,40.8,M,0000,0000*63<0
>> x0d><0x0a>
>> MTK GPS successfully reconfigured.
>>
>> I.e. I am sending three different commands here:
>> $PMTK301,2*2E 	# Enable SBAS
>> $PMTK313,1*2E   # Turn on WAAS
>> $PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0*29 # Turn on only GGA, all
>> other off
>>
>> A short time after each programming command I get an ack message back:
>> $PMTK001,301,3*32<0x0d><0x0a>
>> $PMTK001,313,3*31<0x0d><0x0a>
>> $PMTK001,314,3*36<0x0d><0x0a>
>>
>> I.e. packet type 001, followed by the command # and the ack code, where
>> '3' means OK.
>>
>> BTW, I forgot to enable the initial transmission of a '0' byte, but the
>> command was accepted anyway, so this doesn't seem to be really required.
>>
>> I also tried to program the default set of NMEA output ($PMTK314,-1*),
>> that set turns out to be different from what the Sure board sets up:
>>
>> RMC, GGA, GSA, GSV (repeated 4 times to cover all sats received).
>>
>> BTW, this morning I got 14 sats in the (4!) GSV messages, that's the
>> first time I've seen a GPS with info about more than 12 sats! :-)
>
> So you  have the code for this program available? Is it really necessary

Sure, but it is very definitely a hack-in-progress:

http://norloff.org/ntp/nmea-mtk/

> to only send the commands in the window while none are received? (eg if
> you made a mistake and told it to send more commands than can fit into 1
> sec, there would never be such a window, and you could never correct
> your mistake-- which seems a crazy way of setting up a system)

Recovery _could_ be based on the "if without power for more than N 
hours, reset to board defaults" which the Sure board is obviously doing, 
but I believe you're most probably right.

I did discover by accident that even without sending a '0' and waiting 
for CD to drop, the commands were still accepted and acknowledged.

> Also do they really demand that you include the hash code at the end? In
> the garmin that is optional.

I haven't tried without, and it does protect against some line errors, 
so why not?

The calculation is after all really trivial:

	len = strlen(buffer);
	// Add trailing '*' if missing:
	if (buffer[len-1] != '*')
		buffer[len++] = '*';
	// XOR sum of all bytes, except the first and last:
	unsigned xor_sum = 0;
	for (int i = 1; i < len-1; i++)
		xor_sum ^= buffer[i];
	// Append the hex checksum + CRLF:
	sprintf(buffer + len, "%02X\r\n", xor_sum);
	len += 4;

Terje
-- 
- <Terje.Mathisen at tmsw.no>
"almost all programming can be viewed as an exercise in caching"




More information about the questions mailing list