基于ArduinoIDE的任意型号单片机 + GPS北斗BDS卫星定位

发布于:2025-05-08 ⋅ 阅读:(17) ⋅ 点赞:(0)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

北斗卫星导航系统(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卫星定位》


网站公告

今日签到

点亮在社区的每一天
去签到