ROS2进阶 -- 硬件篇第三章第三节 -- ESP32 DEVKIT_V1通过串口获取ATGM336H GPS定位数据

第三节我们的任务是通过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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值