UBLOX NEO6M校验和检查?

时间:2017-10-24 22:03:47

标签: python

我正在从串行连接中读取串行输入,并且正在接收这样的数据输入。这些是来自UBLOX NEO6M GPS接收器的NMEA字符串。

go tool compile -S examle.go

每行的最后两位数字是其校验和。从美元符号开始并在星号之前结束是有效载荷。校验和应该使用手册中的算法从有效负载计算:

$GPRMC,202325.00,A,4008.94847,N,11135.48840,W,0.011,,241017,,,D*6F
$GPVTG,,T,,M,0.011,N,0.020,K,D*24
$GPGSA,A,3,18,24,32,51,08,10,15,27,20,14,21,,1.60,0.86,1.35*0A
$GPGSV,4,1,15,04,44,270,32,08,15,319,30,10,57,284,42,13,04,036,*74
$GPGSV,4,2,15,14,08,205,21,15,30,049,43,16,04,259,,18,74,010,41*7C
$GPGSV,4,3,15,20,18,072,28,21,65,114,36,24,22,100,24,27,41,292,41*72
$GPGSV,4,4,15,32,25,204,28,46,39,160,27,51,43,173,42*4D
$GPGLL,4008.94847,N,11135.48840,W,202325.00,A,D*77

以下是手册中有关如何操作的代码。我不确定代码是用什么语言编写的,但它不是python。

The checksum algorithm used is the 8-Bit Fletcher Algorithm, which is used in the 
TCP standard (RFC 1145).  This algorithm works as follows:
Buffer[N] contains the data over which the checksum is to be calculated.
The two CK_ values are 8-Bit unsigned integers, only! 
If implementing with larger-sized integer values, make sure to 
mask both CK_A and CK_B with 0xFF after both operations in the loop.
After the loop, the two U1 values contain the checksum, 
transmitted at the end of the packet.

这是我同样瑕疵的python版本:

CK_A = 0, CK_B = 0
For(I=0;I<N;I++)
    {
    CK_A = CK_A + Buffer[I]
    CK_B = CK_B + CK_A
    }

我收到此错误(并不奇怪):

                x=0
                ck_a=0
                ck_b=0
                lentemp=len(payloadstr)
                while x < lentemp:
                        ck_a = ck_a + payloadstr[x]
                        ck_b = ck_b + ck_a
                        x+=1
                print('ck_a='+str(ck_a))
                print('ck_b='+str(ck_b))

说完所有这些之后,我知道我的数据类型不匹配。我不知道如何将ck_a和ck_b变成8位整数。另外,我不确定如何将有效载荷[str]转换为数字。他们在谈论ASCII值吗?或者他们是在谈论十六进制呢?

以下是manual

的链接

第85页关于校验和。

1 个答案:

答案 0 :(得分:0)

虽然雅致,但使用@larsks的link中的comment以及我可以召集的一点正则表达式:

stringz = ('$GPRMC,202325.00,A,4008.94847,N,11135.48840,W,0.011,,241017,,,D*6F',
           '$GPVTG,,T,,M,0.011,N,0.020,K,D*24',
           '$GPGSA,A,3,18,24,32,51,08,10,15,27,20,14,21,,1.60,0.86,1.35*0A',
           '$GPGSV,4,1,15,04,44,270,32,08,15,319,30,10,57,284,42,13,04,036,*74',
           '$GPGSV,4,2,15,14,08,205,21,15,30,049,43,16,04,259,,18,74,010,41*7C',
           '$GPGSV,4,3,15,20,18,072,28,21,65,114,36,24,22,100,24,27,41,292,41*72',
           '$GPGSV,4,4,15,32,25,204,28,46,39,160,27,51,43,173,42*4D',
           '$GPGLL,4008.94847,N,11135.48840,W,202325.00,A,D*77')

import re

for s in stringz:

    # https://docs.python.org/2/howto/regex.html#matching-characters

    result   = re.search('\$(.*)\*', s) # everything between '$' and '*' (escaped with '\')

    # https://rietman.wordpress.com/2008/09/25/how-to-calculate-the-nmea-checksum/
    # see also https://forum.u-blox.com/index.php/14618/python-generate-checksums-validate-coming-serial-interface

    checksum = 0
    for thing in result.group(1):
        checksum = checksum ^ ord(thing)  # Xor

    ck  = hex(0x100 + checksum)[-2:]
    sck = s[-2:].lower()

    print ("{} == {}: {}".format(ck, sck, ck==sck))

返回

6f == 6f: True
24 == 24: True
0a == 0a: True
74 == 74: True
7c == 7c: True
72 == 72: True
4d == 4d: True
77 == 77: True