引言
在网上买了一个导航定位模块,自己鼓捣鼓捣,成功接收到了卫星信号,得到了定位数据,下面记录一下整个实验流程。
系统硬件
系统整体由:卫星信号接收天线、导航定位模块、USB转TTL线及计算机几部分组成。
天线:用于接收电磁波信号,并将电磁波信号转换为电信号
导航定位模块:对卫星信号进行解算,得到定位和授时结果,即得到当前经纬度信息和时间信息
USB转TTL线:用于将模块解算数据传输至电脑中进行进一步处理和显示(该模块将解算数据通过串口的方式实时传输至电脑中)
计算机:处理串口传输的数据,解析导航数据,提取关键信息
图1 卫星天线
图2 导航定位模块
图3 USB转TTL线
图4 计算机
模块连接
购买模块赠送手册中给了接线方式,直接用杜邦线连接即可
注意:模块上那个四个引脚需要用电烙铁焊接上
图5 模块接线图
数据格式
按上面连接好系统后,可直接打开商家提供的串口调试助手读取数据,定位成功后,串口助手界面如下:
注意:由于使用的低成本模块,且导航信号是扩频体制的信号,因此落地信号强度很弱,在室内或者遮挡处无法定位成功,需去室外开阔地进行测试
可以看到我们得到了不同的数据开头,仅需解析$GNRMC开头的数据即可,对于该数据的描述如下:
$GPRMC,055430.00,A,2256.25353,N,11343.15605,E,2.440,177.00,080119,,,A*69
055430.00, <1> UTC 时间,hhmmss(时分秒)格式
A, <2> 定位状态,A=有效定位,V=无效定位)
2256.25353, <3>纬度ddmm.mmmm(度分)格式(前面的0也将被传输 22°+56.25353
N, <4> 纬度半球N(北半球)或S(南半球)
11343.15605, <5>经度dddmm.mmmm(度分)格式(前面的0也将被传输)<6> 经度半球E(东经)或W(西经)
E, <6> 经度半球E(东经)或W(西经)
2.440, <7>地面速率(000.0~999.9节,前面的0也将被传输)*1.852 = KM
177.00, <8>地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
080119, <9> UTC 日期,ddmmyy(日月年)格式
, <10>磁偏角(000.0~180.0度,前面的0也将被传输)
, <11> 磁偏角方向,E(东)或W(西)
A*69 <12>模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
dd+(mm.mmmm/60)
代码解析
核心思想:python中导入读取串口数据的数据包,实时读取模块传送给电脑的数据,然后将相应的数据解析出来
其实商家已经给好了串口软件用于读取数据,但是它不易于我们查看,因此我在这里用python再处理一下,便于得到我想要的结果,排除冗余数据带来的影响
需要提前在环境中下好serial库
import os
import time
import serial
import serial.tools.list_ports
os.system('cls')
serial_portlist = list(serial.tools.list_ports.comports())
if len(serial_portlist) <= 0 :
print('未发现可用串口')
else :
for i in range (len(serial_portlist)):
print(serial_portlist[i])
port_gps = 'COM'+input('请输入GPS模块所在串口:')
ser = serial.Serial(port_gps,9600,timeout = 2)
while True:
if ser.in_waiting > 0 :
time.sleep(0.6)#请在0.4-0.8范围内调试修改
#过低数据不完整,过高数据被覆盖!
os.system('cls')
GETBYTES = ser.read(ser.in_waiting)
GETSTR = GETBYTES.decode()
#print('原始数据:')
GETSTR_List = GETSTR.split('\n')
#print(GETSTR_List) #检查接收情况
for i in GETSTR_List:
#print(i)
i_index=i.split(',')
# print(i_index)
if i_index[0]=="$GNRMC":
data_num=len(i_index)
if data_num==13:
UTC = i_index[1][0:2] + ':' + i_index[1][2:4] + ':' + i_index[1][4:6]
print("世界时:")
print(UTC)
Beijing_Time=str(int(i_index[1][0:2])+8) + ':' + i_index[1][2:4] + ':' + i_index[1][4:6]
print("北京时间")
print(Beijing_Time)
weidu=int(i_index[3][0:2])+float(i_index[3][2:11])/60
jingdu=int(i_index[5][0:3])+float(i_index[5][3:12])/60
print("经度:"+i_index[4])
print(jingdu)
print("纬度:"+i_index[6])
print(weidu)