Arduino实现基于ESP32控制M5311上传北斗定位信息
使用的模块
- NodeMCU-32S的ESP32开发板
- ATGM336H-5N-31 北斗(BDS) GPS定位模块
- M5311的NB-IoT模块、物联网卡
GNRMC格式
$GNRMC,012919.000,A,3032.9857,N,10403.5769,E,0.00,0.00,260421,,,A*7B
解析后的数据
字段 | 值 | 名 | 取值 |
---|---|---|---|
1 | $GNRMC | 消息头标识 | |
2 | 012919.000 | UTC时间 | hhmmss.sss 转换成北京时间需要加8小时 |
3 | A | 状态 | A-有效定位,V-未定位 |
4 | 3032.9857 | 纬度 | ddmm.mmmm,度分格式(前导位数不足则补0) |
5 | N | 纬度方向 | N-北纬,S-南纬 |
6 | 10403.5769 | 经度 | dddmm.mmmm,度分格式(前导位数不足则补0) |
7 | E | 纬度方向 | E-东经,W-西经 |
8 | 0.00 | 地面节 | 一节约等1.852 千米/小时 |
9 | 0.00 | 地面航向 | |
10 | 260421 | UTC日期 | DDMMYY |
11 | 磁偏角 | 000.0 - 180.0(前导位数不足则补0) | |
12 | 磁偏角方向 | E-东,W-西 | |
13 | 模式指示 | A-自动,D-差分,E-估测,N-数据无效(3.0协议内容) | |
14 | *7B | 校验值 | *后hh为$到*所有字符的异或和 |
15 | \r\n |
简单压缩GPS数据的方法
通过北斗芯片拿到的典型折定位数据如下$GNRMC,012919.000,A,3032.9857,N,10403.5769,E,0.00,0.00,260421,,,A*7B
其中GPS数据为3032.9857,N,10403.5769,E
,其有效信息占4+4+1+5+4+1=19
字节数据,有点浪费物联网卡上传时的流量资源,因此可以简单压缩一下。
如果采用两个浮点数float32
存,再加南、北纬和东、西经的话需要4+4+1=9
字节,但仔细思考一下会发现纬度数据整数部分最大为9000
,经度数据整数部分最大为18000
。他们的小数部分最大都为9999
。因此需要存他们的比特位空间如下:
信息 | 最大值 | 所需比特数 |
---|---|---|
纬度整数 | 9000 | 14 |
纬度小数 | 9999 | 14 |
经度整数 | 18000 | 15 |
经度小数 | 9999 | 14 |
南、北纬 | - | 1 |
东、西经 | - | 1 |
因此需要的总的比特位数为14+14+15+14+1+1=59
,所以需要8个字节来存储,还能空出5个bit位。
再仔细考虑一下,如果去除小数点,纬度数据的最大值为90000000
,经度的最大值为180000000
,把这两个按 经度纬度
的形式组合起来的最大值为 18000000090000000
,这个值需要54个bit,再加1个纬度方向,1个经度方向bit,共56bit,正好7个字节,比上面的方案正好省出一个字节。