第三节我们的任务是通过ESP32 DEVKIT_V1通过串口获取ATGM336H GPS定位数据
参考资料:
零件说明:ROS2进阶 – 硬件篇第一章 – 使用ESP32,树莓派5,ROS2 从零组装一台差速控制的机器人
环境配置:ROS2进阶 – 硬件篇第二章 – 使用 ESP32 DEVKIT_V1 开发板基于 Arduino IDE 的环境搭建教程 windows / ubuntu 双系统安装
视频讲解:第六节:ESP32通过串口获取定位数据
使用本章内容时请提前将代码esp32_ros2_robot下载好
1. 本节需要准备的东西
ESP32,ATGM336H GPS, Arduino IDE
本节所使用的代码为06-esp32_GPS_BEIDOU_module
2. 电路图
先将esp32通过USB连接到电脑上,然后将ATGM336H GPS和ESP32按照下图连接
接线说明:
GPS VCC 正极 +(红⾊) ESP32_Vin (3.3V)
GPS GND 负极 -(⿊⾊) ESP32_Gnd(0V)
数据引脚 TX ESP32_RX2
数据引脚 RX ESP32_TX2
实物连接如下:
3. 代码
ATGM336H_GPS.h
/***********************************************************
GPS、北斗(BDS)双模模块
通信接口:
VCC:5.0V 或 3.3V
GND:0V
RX: 串口接收接口
Tx: 串口发送接口
波特率:9600
定位精度:2.5m (开阔地)
首次定位时间:32s
串口输出协议: NMEA0183 ,参见《CASIC多模卫星导航接收机协议规范》
***********************************************************/
#define GPS_BDS_Serial Serial2
// 定义的GPS信息结构体类型,用来存储接收的模组定位信息
struct GPS_BDS_DATA
{
char GPS_Buffer[80];
bool isGetData; //是否获取到GPS数据
bool isParseData; //是否解析完成
char UTCTime[11]; //UTC时间
char latitude[11]; //纬度
char N_S[2]; //N/S
char longitude[12]; //经度
char E_W[2]; //E/W
bool isUsefull; //定位信息是否有效
} Save_Data;
const unsigned int gpsRxBufferLength = 600;
char gpsRxBuffer[gpsRxBufferLength];
unsigned int ii = 0;
void GPS_BDS_Init()
{
GPS_BDS_Serial.begin(9600); // 模块的波特率决定
Save_Data.isGetData = false;
Save_Data.isParseData = false;
Save_Data.isUsefull = false;
}
void clrGpsRxBuffer(void)
{
memset(gpsRxBuffer, 0, gpsRxBufferLength); //清空
ii = 0;
}
// 然后根据$GNRMC 格式的定义,将其中的:定位状态、经纬度、东西半球、南北半球信息提取出来。
void parseGpsBuffer()
{
char *subString;
char *subStringNext;
if (Save_Data.isGetData)
{
Save_Data.isGetData = false;
for (int i = 0 ; i <= 6 ; i++)
{
if (i == 0)
{
if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
{
// return; //解析错误
}
}
else
{
subString++;
if ((subStringNext = strstr(subString, ",")) != NULL)
{
char usefullBuffer[2];
switch(i)
{
case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break; //获取UTC时间
case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break; //获取UTC时间
case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break; //获取纬度信息
case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break; //获取N/S
case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break; //获取纬度信息
case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break; //获取E/W
default:break;
}
subString = subStringNext;
Save_Data.isParseData = true;
if(usefullBuffer[0] == 'A')
Save_Data.isUsefull = true;
else if(usefullBuffer[0] == 'V')
Save_Data.isUsefull = false;
}
else
{
// return; //解析错误
}
}
}
}
}
// 通过串口读取 定位模组输出的定位信息,并根据帧头作为判断条件,只保存 $GNRMC 格式的数据帧
void gpsRead() {
while (GPS_BDS_Serial.available())
{
gpsRxBuffer[ii++] = GPS_BDS_Serial.read();
if (ii == gpsRxBufferLength)
clrGpsRxBuffer();
}
char* GPS_BufferHead;
char* GPS_BufferTail;
if ((GPS_BufferHead = strstr(gpsRxBuffer, "$GPRMC,")) != NULL || (GPS_BufferHead = strstr(gpsRxBuffer, "$GNRMC,")) != NULL )
{
if (((GPS_BufferTail = strstr(GPS_BufferHead, "\r\n")) != NULL) && (GPS_BufferTail > GPS_BufferHead))
{
memcpy(Save_Data.GPS_Buffer, GPS_BufferHead, GPS_BufferTail - GPS_BufferHead);
Save_Data.isGetData = true;
clrGpsRxBuffer();
}
}
}
esp32_gps_test.ino
#include "ATGM336H_GPS.h"
void setup() {
Serial.begin(115200);
GPS_BDS_Init();
}
void loop() {
gpsRead(); //获取GPS数据
parseGpsBuffer();//解析GPS数据
// 判断解析是否成功
if (Save_Data.isParseData)
{
Save_Data.isParseData = false;
// 世界标准时间,即格林威治时间,全球根据所在时区调整。
Serial.print("Save_Data.UTCTime = ");
Serial.println(Save_Data.UTCTime);
if(Save_Data.isUsefull)
{
// 打印经纬度信息 东西、南北半球信息
Save_Data.isUsefull = false;
Serial.print("Save_Data.latitude = ");
Serial.println(Save_Data.latitude);
Serial.print("Save_Data.N_S = ");
Serial.println(Save_Data.N_S);
Serial.print("Save_Data.longitude = ");
Serial.println(Save_Data.longitude);
Serial.print("Save_Data.E_W = ");
Serial.println(Save_Data.E_W);
}
else
{
Serial.println("GPS DATA is not usefull!");
}
}
}
4. 运行代码
在Arduino打开代码
选择开发板和端口号
点击验证和上传按钮
输出如下
因为我在室内,所以显示下面的内容
5. 视频调试过程如下
gps