NEO-6M GPS模块使用指南 – Arduino教程

释放双眼,带上耳机,听听看~!

本教程介绍如何将 NEO-6M GPS 模块与 Arduino 一起使用来获取 GPS 数据。GPS 代表全球定位系统,可用于确定旅行时的位置、时间和速度。

NEO-6M GPS模块使用指南 - Arduino教程

你将学习如何:

  • 将 NEO-6M GPS 模块连接到 Arduino UNO
  •  获取原始 GPS 数据
  • 解析原始数据以获取选定且可读的 GPS 信息
  •  获取位置

介绍 NEO-6M GPS 模块

NEO-6M GPS模块如下图所示。它带有一个外部天线,并且没有带接头引脚。因此,您需要获得并焊接一些。

NEO-6M GPS模块使用指南 - Arduino教程
  • 该模块具有外部天线和内置 EEPROM。
  •  接口:RS232 TTL
  • 电源:3V至5V
  • 默认波特率:9600 bps
  • 适用于标准 NMEA 句子

NEO-6M GPS模块还与其他微控制器板兼容。要了解如何将 NEO-6M GPS 模块与 Raspberry Pi 一起使用,您可以阅读:使用 Raspberry Pi 和 GPS 模块更改位置的电子邮件警报系统。

 哪里可以买到?

您可以以 6 美元到 5 美元的价格购买 NEO-20M GPS 模块。我们建议您查看 Maker Advisor 上的 NEO-6M GPS 模块页面,比较不同商店的价格并找到最好的。

 引脚接线

NEO-6M GPS 模块有四个引脚:VCC、RX、TX 和 GND。该模块使用 TX 和 RX 引脚通过串行通信与 Arduino 通信,因此接线再简单不过了:

 NEO-6M GPS模块  连接到Arduino UNO
VCC 5V
RX 软件串行中定义的 TX 引脚
TX 软件串行中定义的RX引脚
GND GND

获取 GPS 原始数据

要获取原始 GPS 数据,您只需使用软件串行开始与 GPS 模块进行串行通信。继续阅读以了解如何做到这一点。

 所需零件

若要测试此示例,需要以下部件:

  • Arduino
  •  NEO-6M GPS模块
  •  跳线

 连接图

按照下面的原理图将 NEO-6M GPS 模块连接到您的 Arduino。

NEO-6M GPS模块使用指南 - Arduino教程
  • 模块GND引脚连接到Arduino GND引脚
  • 模块RX引脚连接到Arduino引脚3
  • 模块TX引脚连接到Arduino引脚4
  • 模块VCC引脚连接到Arduino 5V引脚

 使用方法

将以下代码复制到Arduino IDE并将其上传到Arduino开发板。

 

此程序假设您使用引脚 4 和引脚 3 作为 RX 和 TX 串行引脚,以建立与 GPS 模块的串行通信。如果您使用的是其他图钉,则应在以下行中对其进行编辑:

SoftwareSerial ss(4, 3);

此外,如果您的模块使用的默认波特率与 9600 bps 不同,则应修改以下行中的代码:

ss.begin(9600);

该程序监听GPS串口,当从模块接收到数据时,将其发送到串口监视器。

while (ss.available() > 0){
  // get the byte data from the GPS
  byte gpsData = ss.read();
  Serial.write(gpsData);
}

以 9600 的波特率打开串行监视器。

NEO-6M GPS模块使用指南 - Arduino教程

您应该以 GPS 标准语言 NMEA 获得一堆信息。您在串行监视器中得到的每一行都是一个 NMEA 语句。

NMEA 代表美国国家海洋电子协会,在 GPS 世界中,它是 GPS 制造商支持的标准数据格式。

理解 NMEA 句子

NMEA 语句以 $ 字符开头,每个数据字段用逗号分隔。

$GPGGA,110617.00,41XX.XXXXX,N,00831.54761,W,1,05,2.68,129.0,M,50.1,M,,*42
$GPGSA,A,3,06,09,30,07,23,,,,,,,,4.43,2.68,3.53*02
$GPGSV,3,1,11,02,48,298,24,03,05,101,24,05,17,292,20,06,71,227,30*7C
$GPGSV,3,2,11,07,47,138,33,09,64,044,28,17,01,199,,19,13,214,*7C
$GPGSV,3,3,11,23,29,054,29,29,01,335,,30,29,167,33*4E
$GPGLL,41XX.XXXXX,N,00831.54761,W,110617.00,A,A*70
$GPRMC,110618.00,A,41XX.XXXXX,N,00831.54753,W,0.078,,030118,,,A*6A 
$GPVTG,,T,,M,0.043,N,0.080,K,A*2C

NMEA 句子有多种类型。消息的类型由第一个逗号前的字符指示。

$ 后面的 GP 表示它是 GPS 位置。 $GPGGA是基本的 GPS NMEA 消息,提供 3D 位置和精度数据。在下面的句子中:

$GPGGA,110617.00,41XX.XXXXX,N,00831.54761,W,1,05,2.68,129.0,M,50.1,M,,*42
  • 110617 – 表示获取修复位置的时间,11:06:17 UTC
  • 41XX.XXXXX,N – 北纬 41 度 XX.XXXXX’
  • 00831.54761,W – 经度 008 度 31.54761′ W
  • 1 – 定位质量(0 = 无效;1 = GPS 定位;2 = DGPS 定位;3 = PPS 定位;4 = 实时运动学;5 = 浮动 RTK;6 = 估计(航位推算);7 = 手动输入模式;8 = 模拟模式)
  • 05 – 被跟踪的卫星数量
  • 2.68 – 水平稀释位置
  • 129.0, M – 海拔高度,以海平面以上米为单位
  • 50.1, M – WGS84 椭球体上方的大地水准面(平均海平面)高度
  • 空字段 – 自上次 DGPS 更新以来的时间(以秒为单位)
  • 空字段 – DGPS 站 ID 号
  • *42 – 校验和数据,始终以 * 开头

其他 NMEA 句子提供了其他信息:

  • $GPGSA – GPS DOP 和活动卫星
  • $GPGSV – 详细的 GPS 卫星信息
  • $GPGLL – 地理纬度和经度
  • $GPRMC – 基本 GPS pvt(位置、速度、时间)数据
  • $GPVTG – 速度很好

要了解每个数据字段在每句话中的含义,您可以在此处查阅 NMEA 数据。

使用 TinyGPS++ 库解析 NMEA 句子

您可以使用来自 GPS 的原始数据,也可以通过将字符序列保存到变量中来将这些 NMEA 消息转换为可读且有用的格式。为此,我们将使用 TinyGPS++ 库。

该库使以有用且易于理解的格式获取位置信息变得简单。您可以单击此处了解有关 TinyGPS++ 库的更多信息。

安装 TinyGPS++ 库

按照以下步骤在Arduino IDE中安装TinyGPS++库:

该库提供了几个关于如何使用它的示例。在Arduino IDE中,您只需要转到TinyGPS++>文件>示例,然后从提供的示例中进行选择。

注意:库中提供的示例假设 GPS 模块的波特率为 4800。如果您使用的是 NEO-9600M GPS 模块,则需要将其更改为 6。

使用 NEO-6M GPS 模块和 TinyGPS++ 库获取位置

您可以使用 TinyGPS++ 库以方便且有用的格式获取位置。下面,我们提供了一个代码来从 GPS 获取位置。这是其中一个库示例的简化版本。

/*
 *   https://www.qutaojiao.com
 */
 
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup(){
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

void loop(){
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){
      Serial.print("Latitude= "); 
      Serial.print(gps.location.lat(), 6);
      Serial.print(" Longitude= "); 
      Serial.println(gps.location.lng(), 6);
    }
  }
}

 

首先导入所需的库:TinyGPSPlus 和 SoftwareSerial

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

然后,定义软件串行 RX 和 TX 引脚,以及 GPS 波特率。如果您将其他引脚用于软件串行,则需要在此处进行更改。此外,如果您的 GPS 模块使用不同的默认波特率,您还应该对其进行修改。

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

然后,创建一个 TinyGPS++ 对象:

TinyGPSPlus gps;

并在您之前定义的引脚上启动串行连接

SoftwareSerial ss(RXPin, TXPin);

在 setup() 中,您可以初始化串行通信,既可以查看串行监视器上的读数,也可以与 GPS 模块进行通信。

void setup() {
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

在循环中是您请求信息的地方。要使 TinyGPS++ 正常工作,您必须使用 encode() 方法从 GPS 模块重复将字符汇集到它。

while (ss.available() > 0){
 gps.encode(ss.read());

然后,您可以查询 gps 对象以查看是否有任何数据字段已更新:

if (gps.location.isUpdated()){
  Serial.print("Latitude="); Serial.print(gps.location.lat(), 6);
  Serial.print("Longitude="); Serial.println(gps.location.lng(), 6);
}

获取纬度和经度很简单,分别使用 gps.location.lat() 和 gps.location.lng()。

将代码上传到Arduino,您应该会看到串行监视器上显示的位置。上传代码后,等待几分钟,模块调整位置以获得更准确的数据。

NEO-6M GPS模块使用指南 - Arduino教程

使用 TinyGPS++ 库获取更多 GPS 信息

TinyGPS++ 库允许您以简单的方式获得更多信息,而不仅仅是位置。除了位置,您还可以获得:

  •  日期
  •  时间
  •  速度
  •  课程
  •  高度
  •  卫星
  •  HDOP的

下面的代码举例说明了如何以简单的方式获取所有这些信息。

/*
 *   https://www.qutaojiao.com
 *
 * Based on the example TinyGPS++ from arduiniana.org
 *
 */
 
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup(){
  Serial.begin(9600);
  ss.begin(GPSBaud);
}

void loop(){
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){
      // Latitude in degrees (double)
      Serial.print("Latitude= "); 
      Serial.print(gps.location.lat(), 6);      
      // Longitude in degrees (double)
      Serial.print(" Longitude= "); 
      Serial.println(gps.location.lng(), 6); 
       
      // Raw latitude in whole degrees
      Serial.print("Raw latitude = "); 
      Serial.print(gps.location.rawLat().negative ? "-" : "+");
      Serial.println(gps.location.rawLat().deg); 
      // ... and billionths (u16/u32)
      Serial.println(gps.location.rawLat().billionths);
      
      // Raw longitude in whole degrees
      Serial.print("Raw longitude = "); 
      Serial.print(gps.location.rawLng().negative ? "-" : "+");
      Serial.println(gps.location.rawLng().deg); 
      // ... and billionths (u16/u32)
      Serial.println(gps.location.rawLng().billionths);

      // Raw date in DDMMYY format (u32)
      Serial.print("Raw date DDMMYY = ");
      Serial.println(gps.date.value()); 

      // Year (2000+) (u16)
      Serial.print("Year = "); 
      Serial.println(gps.date.year()); 
      // Month (1-12) (u8)
      Serial.print("Month = "); 
      Serial.println(gps.date.month()); 
      // Day (1-31) (u8)
      Serial.print("Day = "); 
      Serial.println(gps.date.day()); 

      // Raw time in HHMMSSCC format (u32)
      Serial.print("Raw time in HHMMSSCC = "); 
      Serial.println(gps.time.value()); 

      // Hour (0-23) (u8)
      Serial.print("Hour = "); 
      Serial.println(gps.time.hour()); 
      // Minute (0-59) (u8)
      Serial.print("Minute = "); 
      Serial.println(gps.time.minute()); 
      // Second (0-59) (u8)
      Serial.print("Second = "); 
      Serial.println(gps.time.second()); 
      // 100ths of a second (0-99) (u8)
      Serial.print("Centisecond = "); 
      Serial.println(gps.time.centisecond()); 

      // Raw speed in 100ths of a knot (i32)
      Serial.print("Raw speed in 100ths/knot = ");
      Serial.println(gps.speed.value()); 
      // Speed in knots (double)
      Serial.print("Speed in knots/h = ");
      Serial.println(gps.speed.knots()); 
      // Speed in miles per hour (double)
      Serial.print("Speed in miles/h = ");
      Serial.println(gps.speed.mph()); 
      // Speed in meters per second (double)
      Serial.print("Speed in m/s = ");
      Serial.println(gps.speed.mps()); 
      // Speed in kilometers per hour (double)
      Serial.print("Speed in km/h = "); 
      Serial.println(gps.speed.kmph()); 

      // Raw course in 100ths of a degree (i32)
      Serial.print("Raw course in degrees = "); 
      Serial.println(gps.course.value()); 
      // Course in degrees (double)
      Serial.print("Course in degrees = "); 
      Serial.println(gps.course.deg()); 

      // Raw altitude in centimeters (i32)
      Serial.print("Raw altitude in centimeters = "); 
      Serial.println(gps.altitude.value()); 
      // Altitude in meters (double)
      Serial.print("Altitude in meters = "); 
      Serial.println(gps.altitude.meters()); 
      // Altitude in miles (double)
      Serial.print("Altitude in miles = "); 
      Serial.println(gps.altitude.miles()); 
      // Altitude in kilometers (double)
      Serial.print("Altitude in kilometers = "); 
      Serial.println(gps.altitude.kilometers()); 
      // Altitude in feet (double)
      Serial.print("Altitude in feet = "); 
      Serial.println(gps.altitude.feet()); 

      // Number of satellites in use (u32)
      Serial.print("Number os satellites in use = "); 
      Serial.println(gps.satellites.value()); 

      // Horizontal Dim. of Precision (100ths-i32)
      Serial.print("HDOP = "); 
      Serial.println(gps.hdop.value()); 
    }
  }
}

 

TinyGPS++ 库在如何使用其所有功能方面得到了很好的评论。

 总结

希望本教程对您有所帮助。

给TA打赏
共{{data.count}}人
人已打赏
ArduinoArduino-进阶动态

SIM900 GSM Shield通过SMS获取传感器数据 - Arduino教程

2023-12-9 12:02:16

ArduinoArduino-进阶动态

nRF24L01 – 2.4GHz RF 收发器使用 - Arduino教程

2023-12-9 13:57:01

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
'); })();