在前一教程我们学习了如何将SIM900 GSM-GPRS调制解调器与树莓派(RPi)和台式电脑连接起来。我们使用串行UART通信与SIM900调制解调器“交谈”。通过使用标准的双向数据与调制解调器进行通信UART接口在美国,我们可以在RPi和台式电脑上打电话、接电话、发短信。
通过使用本教程中相同的UART接口和协议,我们将连接一个全球定位系统(GSP)模块与RPi。
我们使用GPS模块NEO-6MV2。这是一个低成本的GPS接收器通常用于嵌入式设备和机器人项目(还有其他几个不同的供应商)。GPS接收器通过连接到可用的GPS卫星来给出它的位置。
GPS接收器可以用来追踪位置。例如,通过将GPS接收器(如NEO-6)和GSM调制解调器(如SIM900)连接到控制器或嵌入式计算机,我们可以设计一个车辆跟踪系统。在该系统中,GPS接收器获得车辆的当前位置,GSM-GPRS调制解调器通过移动网络将该位置通信到远程服务器。
类似地,我们可以在无人机上使用GPS接收器来跟踪它的位置,并管理GPS引导的飞行。同样的GPS接收器也用于智能手机、平板电脑和GPS导航系统。
现在,让我们学习如何将GPS接收器与嵌入式计算机(如树莓派)连接起来。
NEO-6MV2 GPS模块
NEO-6MV2是一个独立的GPS接收器,用于导航。GPS接收器与GPS卫星连接以获得自己的位置。然后,它输出其位置的经纬度作为串行数据。
NEO-6模块基于50通道ublox-6定位引擎,拥有1秒的第一次修复时间(TTFF)。这个GPS引擎有200万个相关器,能够进行大规模的并行时间/频率空间搜索。这使它能够立即找到卫星。该模块的外形较小,非常适合电池驱动的移动设备。
NEO-6M GPS调制解调器的供电电压为2.7 ~ 3.6V。它根据NMEA或UBX协议通信GPS数据。NMEA是一个标准的ASCII协议,而UBX是一个u-blox专有的二进制协议。
接收芯片组具有UART、USB、SPI和DDC (i2c兼容)接口来通信此数据。芯片组有三个配置引脚。其中一个配置引脚——CFG-GPS0——用于启用电源模式的引导配置。
另外两个配置引脚——CFG_COM0和CFG_COM1——用来决定GPS数据是通过NMEA协议还是UBX协议通信的。
NEO-6调制解调器有这样的引脚分配:
在这里使用的模块中,NEO-6调制解调器被预先配置为使用串行(UART)接口输出数据并将GPS数据编码到NMEA协议。
配置引脚CFG_COM0和CFG_COM1被拉到HIGH,结果,GPS数据通过NMEA协议以9600 bps的波特率通信。从上表中可以看到,通过这种配置,NMEA数据包括GSV、RMC、GSA、GGA、GLL和VTG消息。
该模块只公开4个通道,如图所示:
模块的最大导航更新速率为5hz。因此,控制器或嵌入式计算机可以在最少0.2秒内从调制解调器读取GPS数据。
modem上电后,冷启动需要32秒,热启动需要23秒,热启动需要1秒。由于该模块配置为冷启动,最初需要32秒才能第一次获得GPS读数。
该模块还配有一个外置天线,其灵敏度为-160dBm。该模块有一个板载EEPROM和RTC与电池备份。NEO-6M调制解调器可以在-40˚至85˚C的温度下工作。
NEO-6MV2 GPS模块接口
该模块与NEO-6M调制解调器的所有硬件连接都已预先配置好。根据硬件配置,该模块只公开调制解调器的4个通道:
1.VCC(调制解调器的引脚23)
2.UART接收器(调制解调器的引脚21)
3.UART发射机(调制解调器引脚20)
4.接地(可以是调制解调器的引脚10、12、13或24)
NEO-6MV2 GPS模块可以轻松地与控制器/计算机的串行TTL端口连接。但是,VCC引脚必须提供最大3.6V直流电压,接地引脚必须连接到公共接地。模块的TX引脚应该连接到控制器/计算机串行TTL端口的Rxd上。
如果要连接桌面电脑,可以使用usb串口板。记住,GPS模块的最大工作电压为3.6V。因此,当与控制器(如Arduino)或嵌入式计算机(如RPi)接口时,调制解调器应该从3V3电源输出引脚提供VCC。
当通过usb串行板连接到桌面计算机时,该板必须首先配置为使用3V3 TTL电压水平,通过将跳线放置到3.3V头部。
n mea协议
NMEA是美国国家海洋电子协会的缩写。在GPS上下文中,NMEA是所有GPS制造商都支持的标准数据格式。它是GPS接收器和相关软件使用的GPS数据协议。
nmea格式的GPS数据可以通过多种数据通信标准传输,包括UART、SPI、I2C、USB、Wi-Fi、UHF和蓝牙。
在NMEA协议中,GPS数据以NMEA消息串的形式进行通信。也有不同功能的GPS接收器。根据它们的功能,它们通常通信NMEA消息字符串的一个子集。所有NMEA消息都以$字符开头,后面是消息ID和各种数据字段(用逗号分隔)。消息以星号(*)结尾,后面跟着校验和字符。最后,回车和换行作为结束字符。
此处使用的GPS模块通信消息为GSV、RMC、GSA、GGA、GLL和VTG NMEA。让我们逐一检查NMEA消息字符串。
GPRMC -表示位置、速度和时间。它有这样的格式:
美元GPRMC hhmmss: ss、状态、纬度,N,经度,E, SOG,齿轮,ddmmyy, MV, MVE,模式* c < CR > <如果>
GPRMC NMEA消息的数据字段描述如下表所示:
GPVTG -指示已完成的航迹和在地面上的速度。它有这样的格式:
$ GPVTG cogt T cogm M, sog, N,公里,K,模式* c < CR > <如果>
GPVTG NMEA消息的数据字段描述如下表所示:
GPGGA- - - - - -显示时间、位置、补丁等相关数据。它有这样的格式:
美元GPGGA hhmmss: ss,纬度,N,经度,E, f, NoSV, HDOP,韩剧,m, Altref, m, DiffAge, DiffStation * cs < CR > <如果>
GPGGA NMEA消息的数据字段说明如下表所示:
GPGSA- - - - - -表示GPS DOP和活动卫星。它有这样的格式:
$ GPGSA Smode FS sv},{位置误差,HDOP, VDOP * cs < CR > <如果>
GPGSA NMEA消息的数据字段说明如下表所示:
GPGSV- - - - - -表示视图中的sv数量、PRN编号、仰角、方位角和SNR值。它有这样的格式:
$ GPGSV NoMessages MessageNumber NoSV,打印,仰角、方位角、信噪比,
<相同格式的第二个SV的信息>,
<第三个SV相同格式的信息>,
<第四SV相同格式的信息>,*cs
GPGSV NMEA消息的数据字段说明如下表所示:
GPGLL- - - - - -表示位置数据,如位置固定、位置固定时间、位置固定状态等。它有这样的格式:
DirLat GPGLL美元,纬度,经度,DirLongitude, hhmmss: ss, A, c < CR > <如果>
GPGLL NMEA消息的数据字段说明如下表所示:
NEO-6MV2 GPS与RPi接口
为了将新- 6mv2 GPS模块与树莓派连接,从RPi的3.3V引脚(板引脚1或17)为模块提供VCC,然后从RPi上的任何接地引脚(板引脚6、9、14、20、25、30、34或39)接地。
接下来,将模块的TX与树莓派的UART Rxd(板销10)。不需要向NEO-6调制解调器发送任何串行数据,这意味着不需要连接模块的RX。
检查NEO-6MV2 GPS模块是否正常工作
当GPS模块供电时,它最初需要一段时间准备。这取决于模块的配置,它是配置为冷启动、热启动还是热启动。
在唤醒后,如果接收器可以看到GPS卫星,并且它开始获得它的位置,模块上的状态LED将开始闪烁。
如果这个LED没有闪烁,要么是模块没有正常工作,要么是卫星不清楚。在这种情况下,您可以尝试从模块获得原始GPS数据。如果您能够获得至少一些信息(如UTC时间),但无法获得位置数据,这意味着模块是正常的,但GPS接收器看不到卫星。
等待一段时间(比如几分钟或半小时),然后再次尝试获取原始的GPS数据。如果模块正常工作,它可能在一段时间后获得位置数据。
使用Python从NEO-6MV2 GPS获取原始数据
原始GPS数据可以从NEO-6M GPS模块读取serial.read ()的serial.readline()方法Python.
方法如下:
- 导入serial、time和sys库。
- 使用serial. serial()方法打开与GPS模块相连的TTL端口serial。
- 该端口名称为/dev/serial0。或者,可以使用/dev/ttyAMA0或/dev/ttyS0作为端口名,这取决于各自的树莓派模型.
- 使用serial.readline()方法从GPS模块逐行读取串行数据。或者,使用serial.read()方法使用来自GPS模块的串行数据的特定字符数。
- 继续读取数据,直到NMEA消息字符串开始重复。
下面是一个从NEO-6M GPS模块读取原始GPS数据的Python脚本示例:
进口系列
从时间导入睡眠
导入系统
ser =系列。串行(“/ dev / ttyS0”)
试一试:
而真正的:
received_data = (str)(ser.readline()) #读取收到的NMEA字符串
打印(received_data“\ n”)
除了KeyboardInterrupt:
sys.exit (0)
当在树莓派中运行上述脚本时,我们在IDLE的控制台中收到了以下GPS数据:
使用Python从NEO-6MV2 GPS获取GPS位置
原始GPS数据包括RMS、VTG、GGA、GSA、GSV和GLL NMEA消息串。一次总共有9个原始GPS数据的消息字符串。
为了获得GPS位置,我们可以提取$GPGGA或$GPGLL消息字符串。这两个字符串都包含位置信息。这里,我们从$GPGGA消息字符串中提取了GPS位置。
原始GPS数据可以存储在字符串类型变量中。通过使用字符串操作函数,例如find(),我们可以在接收的字符串中搜索$GPGGA或$GPGLL。
如果接收到的GPS数据包含这些字符串中的一个,则使用split()函数将消息字符串拆分到$GPGGA或$GPGLL之后。接下来,通过在split()函数中使用逗号作为分隔符,将接收到的NMEA消息数据字段拆分为一个数组。
现在,在数组中有了$GPGGA或$GPGLL NMEA消息字符串的数据字段。您可以通过访问结果数组的不同索引来提取UTC时间、纬度和经度。通过对接收值使用简单的数学和格式化操作,可以将纬度和经度转换为度数。转换后的经度和纬度值也可以打印到控制台中,或转移到变量中。
下面是一个从NEO-6M GPS模块的原始GPS数据中提取GPS位置的Python脚本示例:
进口系列
从时间导入睡眠
导入系统
ser =系列。串行(“/ dev / ttyS0”)
GPGGA美元gpgga_info = ", "
GPGGA_buffer = 0
NMEA_buff = 0
def convert_to_degrees (raw_value):
decimal_value = raw_value / 100.00
度= int (decimal_value)
Mm_mmmm = (decimal_value - int(decimal_value))/0.6
位置=度+ mm_mmmm
位置= " %。4 f“%(位置)
返回的位置
试一试:
而真正的:
received_data = (str)(ser.readline()) #读取收到的NMEA字符串
GPGGA_data_available = received_data.find(gpgga_info) #检查NMEA GPGGA字符串
如果(GPGGA_data_available > 0):
GPGGA_buffer = received_data.split(" $GPGGA, ",1)[1] #存储在" $GPGGA, "字符串后的数据
NMEA_buff = (GPGGA_buffer.split (" "))
nmea_time = []
nmea_latitude = []
nmea_longitude = []
从GPGGA字符串中提取时间
从GPGGA字符串中提取纬度
从GPGGA字符串中提取经度
print(" NMEA Time: ", nmea_time, ' \n ')
lat =(浮动)(nmea_latitude)
lat = convert_to_degrees (lat)
longi =(浮动)(nmea_longitude)
longi = convert_to_degrees (longi)
print (" NMEA经度:",lat, " NMEA经度:",longi, ' \n ')
除了KeyboardInterrupt:
sys.exit (0)
当在RPi中运行上述脚本时,我们在IDLE的控制台中收到了以下GPS位置:
谷歌地图中的GPS位置使用Python
要在谷歌地图中显示GPS位置,可以使用Python的web浏览器库。您可以使用该库的open()方法打开一个谷歌Maps链接,该链接具有在上一个示例中获得的经纬度。
下面是一个Python脚本的示例,它显示了谷歌Maps中NEO-6M GPS模块的GPS位置:
进口系列
从时间导入睡眠
导入系统
导入web浏览器
ser =系列。串行(“/ dev / ttyS0”)
GPGGA美元gpgga_info = ", "
GPGGA_buffer = 0
NMEA_buff = 0
GPGGA_data_available = " "
def convert_to_degrees (raw_value):
decimal_value = raw_value / 100.00
度= int (decimal_value)
Mm_mmmm = (decimal_value - int(decimal_value))/0.6
位置=度+ mm_mmmm
位置= " %。4 f“%(位置)
返回的位置
received_data = (str)(ser.read(200)) #读取NMEA字符串
GPGGA_data_available = received_data.find(gpgga_info) #检查NMEA GPGGA字符串
如果(GPGGA_data_available > 0):
GPGGA_buffer = received_data.split(" $GPGGA, ",1)[1] #存储在" $GPGGA, "字符串后的数据
NMEA_buff = (GPGGA_buffer.split (" "))
nmea_time = []
nmea_latitude = []
nmea_longitude = []
从GPGGA字符串中提取时间
从GPGGA字符串中提取纬度
nmea_longitude = NMEA_buff [3]
print(" NMEA Time: ", nmea_time, ' \n ')
lat =(浮动)(nmea_latitude)
lat = convert_to_degrees (lat)
longi =(浮动)(nmea_longitude)
longi = convert_to_degrees (longi)
print (" NMEA经度:",lat, " NMEA经度:",longi, ' \n ')
map_link = ' http://maps.google.com/?q= ' + lat +”、“+ longi
webbrowser.open (map_link)
sys.exit (0)
当在RPi中运行上述脚本时,我们在谷歌地图中收到以下GPS位置:
在下一篇教程中,我们将介绍在树莓派中使用I2C进行串行通信。
了下:单片机项目,188app官网
与本文相关的问题?询问和讨论EDAboard.com而且Electro-Tech-Online.com论坛。
告诉我们你的想法!
你必须登录发表评论。