提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
北斗卫星导航系统(BDS)作为我国自主研发的全球卫星导航系统,其定位精度在亚太地区已达2.5米级别
。结合GPS系统形成双模定位,可显著提升可用卫星数量及定位可靠性。本文将以Arduino uno和ESP32-S3-DevKitC-1为例,详解基于ArduinoIDE的北斗/GPS开发全流程,并提供OLED实时定位显示方案。# 一、硬件准备
1.1 器件选择
- ESP32-S3-DevKitC-1或者Arduino uno
- ATGM336H版本模块(任意GPS模块都行)
- 陶瓷有源天线
注:实验要在空旷的场地,室内GPS会没信号。阳台不一定。
1.2 接线方案
方案一:
Arduino | 北斗模块 |
---|---|
3.3V | VCC |
GND | GND |
0(rx,不是A0) | TX |
方案二:
ESP32 | 北斗模块 |
---|---|
3.3V | VCC |
GND | GND |
16 | TX |
注:实验要在空旷的场地,室内GPS会没信号。阳台不一定。
第一次测试,北斗模块需要一分钟时间激活后,串口才能接收到
二、驱动实现
2.1 核心代码解析(arduino)
测试代码如下(示例):
/*
ESP32-S3 的默认 UART 配置如下:
UART0:
TX (发送): GPIO11
RX (接收): GPIO31
UART1:
TX (发送): GPIO171
RX (接收): GPIO16
*/
#define GPSSerial Serial
#define DEBUGSerial Serial
void setup() //初始化内容
{
GPSSerial.begin(9600);
DEBUGSerial.begin(9600);
DEBUGSerial.println("Wating...");
}
void loop() //主循环
{
while (GPSSerial.available()) {
DEBUGSerial.write(GPSSerial.read());//收到GPS数据则通过Serial输出
}
}
三、坐标解析代码(ESP32)
#include <functional>
#define GPSSerial Serial1
float lastLat = 0.0;
float lastLon = 0.0;
bool gpsValid = false;
unsigned long lastSendTime = 0;
const int sendInterval = 5000;
void parseGPS(String nmea);
void GPS_connect();
void GPS_read();
void setup() {
GPSSerial.begin(9600, SERIAL_8N1, 16, 17);//(RX是16,TX是17。此时用GPS的TX接16)
Serial.begin(9600);
Serial.println("GPS Parser Started");
}
void loop() {
GPS_connect();
if (millis() - lastSendTime >= sendInterval) {
lastSendTime = millis();
GPS_read();
}
}
void GPS_connect() {
while (GPSSerial.available()) {
String line = GPSSerial.readStringUntil('\n');
line.trim();
parseGPS(line);
}
}
void GPS_read() {
if (gpsValid) {
Serial.print("Latitude: ");
Serial.print(lastLat);
Serial.print("°, Longitude: ");
Serial.print(lastLon);
Serial.println("°");
gpsValid = false;
} else {
Serial.println("Waiting for valid GPS signal...");
}
}
void parseGPS(String nmea) {
if (nmea.length() < 6) return;
String type = nmea.substring(0, 6);
String content = nmea.substring(7); // 去掉类型标识(如 "$GNRMC,")
int starIndex = content.indexOf('*');
if (starIndex != -1) content = content.substring(0, starIndex);
String fields[20];
int fieldCount = 0;
int pos = 0;
// 正确分割字段(处理空字段)
while (content.length() > 0 && fieldCount < 20) {
int commaIndex = content.indexOf(',');
if (commaIndex == -1) {
fields[fieldCount++] = content;
break;
}
String field = content.substring(0, commaIndex);
fields[fieldCount++] = field;
content = content.substring(commaIndex + 1);
}
// 解析GNRMC
if (type == "$GNRMC" && fieldCount >= 7) {
String status = fields[1]; // 状态字段是索引1
if (status == "A" && fields[2].length() >= 4 && fields[4].length() >= 5) {
// 纬度: fields[2] (格式 ddmm.mmmm)
String latStr = fields[2];
double lat = latStr.substring(0, 2).toDouble() + latStr.substring(2).toDouble() / 60.0;
lat *= (fields[3] == "S") ? -1 : 1;
// 经度: fields[4] (格式 dddmm.mmmm)
String lonStr = fields[4];
double lon = lonStr.substring(0, 3).toDouble() + lonStr.substring(3).toDouble() / 60.0;
lon *= (fields[5] == "W") ? -1 : 1;
lastLat = lat;
lastLon = lon;
gpsValid = true;
}
}
}
3.2效果展示
四、典型问题排查
现象 | 解决方案 |
---|---|
无数据输出 | ①检查TX-RX是否反接 ②测量模块供电电压 ③更换USB数据线 |
坐标值异常(0,0) | ①确认天线方向 ②等待被动模块激活完成(约1分钟) |
数据帧不完整 | ①核对波特率设置 ②检查地线连接 ③避开强电磁干扰源 |
总结
本文是为验证《基于ArduinoIDE的任意型号单片机 + GPS北斗BDS卫星定位》