• 欢迎大家分享资料!前往留言板评论即可!

如何计算GPS的NMEA校验码

合宙 模组资料网 2年前 (2021-05-15) 470次浏览 0个评论 扫描二维码

众所周知,GPS芯片输出的格式,是符合NMEA0183标准的。每一个语句的结尾,都要加上一个校验码。

如果校验码错误,上位机发给GPS芯片的命令,GPS芯片将直接抛弃;而上位机也不会理校验码错误的语句。但是很多开发者并不知道校验码是如何计算的,这对开发造成了一定的影响。所以本文就实操一下,给大家讲解如何计算。

首先我们来看一下一个标准的语句是什么样的:
$GPGGA,092725.00,4717.11399,N,00833.91590,E,1,08,1.01,499.6,M,48.0,M,,*5b\r\n

我们参与校验值计算的部分,是从 $ 符号后起,到最后的不含 \r\n 的部分止。以上边的语句为例,参与计算的部分是:
GPGGA,092725.00,4717.11399,N,00833.91590,E,1,08,1.01,499.6,M,48.0,M,,

我们接下来就以它为基础,看计算出来的结果是不是 5b

##原理
NMEA通讯协议所规定的通讯语句都已是以ASCII码为基础的,NMEA-0183协议语句的数据格式如下:“$”为语句起始标志;“,”为域分隔符;“ ”为校验和识别符,其后面的两位数为校验和,代表了“$”和“”之间所有字符的按位异或值(不包括这两个字符);“/”为终止符,所有的语句必须以来结束,也就是ASCII 字符的“回车”(十六进制的0D)和“换行”(十六进制的0A)
摘自 GPS的NMEA协议数据校验和是怎么算的

##Python
如何在上位机检查校验码是否合法呢?不多说,直接上代码:

import re

def checksum(sentence):
    sentence = sentence.replace("\r", "").replace("\n", "").replace("", "")
    nmeadata,cksum = re.split('\*', sentence)

    calc_cksum = 0
    for s in nmeadata:
        calc_cksum ^= ord(s)

    return nmeadata,'0x'+cksum,hex(calc_cksum)

if __name__=='__main__':
    line = "GPGGA,092725.00,4717.11399,N,00833.91590,E,1,08,1.01,499.6,M,48.0,M,,*5b\n"
    data, cksum, calc_cksum = checksum(line)

    if cksum != calc_cksum:
        print("Error in checksum for: %s" % (data))
        print("Checksums are %s and %s" % (cksum, calc_cksum))
    else:
        print("checksum is: %s" % (calc_cksum))

运行一下看看结果如何:

如何计算GPS的NMEA校验码

正如所料,输出5b;校验ok。

##Lua
如何使用Lua给GPS芯片发控制指令呢?实际上gps.lua已经写好了相关的函数,开发者只需要直接调用即可:

require"gps"
gps.write("xxxx", false)

函数原型如下:

-- GPS串口写命令操作
-- @string cmd,GPS指令(cmd格式:"PGKC149,1,115200*"或者"PGKC149,1,115200*XX\r\n")
-- @bool isFull,cmd是否为完整的指令格式,包括校验和以及\r\n;true表示完整,false或者nil为不完整
-- @return nil
-- @usage gps.writeCmd(cmd)
function writeCmd(cmd,isFull)
    local tmp = cmd
    if not isFull then
        tmp = 0
        for i=2,cmd:len()-1 do
            tmp = bit.bxor(tmp,cmd:byte(i))
        end
        tmp = cmd..(string.format("%02X",tmp)):upper().."\r\n"
    end
    uart.write(uartID,tmp)
    log.info("gps.writecmd",tmp)
    --log.info("gps.writecmd",tmp:toHex())
end

开发者也可以使用以下代码测试校验值:

function checkSum(cmd)
    local tmp = cmd

    tmp = 0
    for i=1,cmd:len() do
        tmp = bit.bxor(tmp,cmd:byte(i))
    end
    tmp = cmd..(string.format("%02X",tmp)):upper().."\r\n"

    return tmp
end

print(checkSum("GPGGA,092725.00,4717.11399,N,00833.91590,E,1,08,1.01,499.6,M,48.0,M,,"))

下载到模块跑一下,看看输出的结果:

如何计算GPS的NMEA校验码

正如所料,输出5b;校验ok。

##c
感谢开发者 维维宁(Q号940791105) 贡献代码:
如何计算GPS的NMEA校验码


转载请注明原文链接:如何计算GPS的NMEA校验码
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址