尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【ESP32S3 + ATGM332D GPS模块实战:从NMEA解析到本地速度计算】
【ESP32S3 ATGM332D GPS模块实战从NMEA解析到本地速度计算】项目概述一、硬件准备1.1 核心部件1.2 硬件连接二、软件配置2.1 PlatformIO环境配置2.2 核心库介绍三、代码实现3.1 完整代码3.2 关键技术解析3.2.1 NMEA数据解析3.2.2 本地墨卡托投影ENU坐标系3.2.3 速度与航向计算四、测试结果4.1 输出示例4.2 数据对比分析4.3 关键指标五、常见问题排查5.1 定位无效5.2 速度为05.3 航向跳变六、总结项目概述本文详细介绍如何使用ESP32通过硬件串口读取ATGM332D GPS模块数据使用TinyGPSPlus库解析NMEA语句并通过本地墨卡托投影ENU坐标系计算真实速度和航向。源码地址https://download.csdn.net/download/VOR234/93024101一、硬件准备先采用GnssToolKit3配置GPS使用模式为航海模式更新速率为10Hz配置波特率为9600查看原始NEMA数据查看收星情况1.1 核心部件部件型号说明主控板ESP32-S3开发板GPS模块ATGM332D支持GPS/北斗双模定位天线GPS有源天线SMA接口1.2 硬件连接ATGM332D模块 ESP32-S3 TX ---------- GPIO17 (UART1_RX) RX ---------- GPIO18 (UART1_TX) VCC ---------- 3.3V GND ---------- GND注意事项ATGM332D默认波特率为9600使用硬件串口Serial1避免占用调试串口GPS模块需外接有源天线并放置在开阔处二、软件配置2.1 PlatformIO环境配置在platformio.ini中添加依赖库[env:freenove_esp32_s3_wroom] platform espressif32 board freenove_esp32_s3_wroom framework arduino monitor_speed 115200 upload_speed 921600 lib_deps mikalhart/TinyGPSPlus^1.0.3 ; GPS NMEA解析库2.2 核心库介绍TinyGPSPlus是一个轻量级、高效的NMEA解析库特点支持所有标准NMEA语句自动解析经纬度、时间、速度、航向等信息内存占用小适合嵌入式设备三、代码实现3.1 完整代码#includeArduino.h#includeTinyGPSPlus.h#includemath.h// GPS模块配置#defineGPS_UARTSerial1// 使用硬件串口1#defineGPS_BAUD_RATE9600// ATGM332D默认波特率#defineGPS_TX_PIN18// UART1_TX#defineGPS_RX_PIN17// UART1_RX#definePRINT_INTERVAL_MS500// 2Hz输出频率// TinyGPSPlus对象TinyGPSPlus gps;// 参考点初始位置作为本地坐标系原点doublerefLat0.0;doublerefLng0.0;boolrefSetfalse;// 上一时刻的位置和时间doublelastEast0.0;doublelastNorth0.0;unsignedlonglastTimeMs0;// 计算得到的速度和航向floatcalcSpeed0.0;floatcalcHeading0.0;// 将经纬度转换为本地ENU坐标voidlatLngToENU(doublelat,doublelng,doublerefLat,doublerefLng,doubleeast,doublenorth);voidsetup(){Serial.begin(115200);delay(500);Serial.println(ATGM332D GPS模块测试 - 本地墨卡托投影计算);// 初始化GPS串口GPS_UART.begin(GPS_BAUD_RATE,SERIAL_8N1,GPS_RX_PIN,GPS_TX_PIN);delay(1000);Serial.printf(GPS UART: Serial1, TX%d, RX%d, Baud%d\n,GPS_TX_PIN,GPS_RX_PIN,GPS_BAUD_RATE);Serial.printf(输出频率: %d Hz\n,1000/PRINT_INTERVAL_MS);Serial.println();}voidloop(){// 持续读取并解析GPS数据while(GPS_UART.available()0){gps.encode(GPS_UART.read());}// 定时输出2HzstaticunsignedlonglastPrintTime0;if(millis()-lastPrintTimePRINT_INTERVAL_MS){lastPrintTimemillis();Serial.println();if(gps.location.isValid()){doublelatgps.location.lat();doublelnggps.location.lng();// 设置参考点if(!refSet){refLatlat;refLnglng;refSettrue;Serial.println([INFO] 参考点已设置);}// 转换为ENU坐标doubleeast,north;latLngToENU(lat,lng,refLat,refLng,east,north);// 计算速度和航向unsignedlongcurrentTimeMsmillis();if(lastTimeMs0refSet){doubledt(currentTimeMs-lastTimeMs)/1000.0;if(dt0.01){doubledxeast-lastEast;doubledynorth-lastNorth;// 速度: m/s - km/hcalcSpeedsqrt(dx*dxdy*dy)/dt*3.6;// 航向: 弧度转角度0-360度calcHeadingatan2(dx,dy)*180.0/M_PI;if(calcHeading0)calcHeading360.0;}}// 更新状态lastEasteast;lastNorthnorth;lastTimeMscurrentTimeMs;// 输出数据Serial.println(定位状态: 有效);if(gps.time.isValid()){Serial.printf(UTC时间: %02d:%02d:%06.3f\n,gps.time.hour(),gps.time.minute(),gps.time.second()gps.time.centisecond()/100.0);}if(gps.date.isValid()){Serial.printf(日期: %04d-%02d-%02d\n,gps.date.year(),gps.date.month(),gps.date.day());}Serial.printf(纬度: %.6f°\n,lat);Serial.printf(经度: %.6f°\n,lng);Serial.printf(东向偏移: %.3f m\n,east);Serial.printf(北向偏移: %.3f m\n,north);Serial.printf(计算航速: %.6f km/h\n,calcSpeed);Serial.printf(计算航向: %.6f°\n,calcHeading);Serial.printf(原始航速: %.6f km/h\n,gps.speed.kmph());Serial.printf(原始航向: %.6f°\n,gps.course.deg());Serial.printf(卫星数量: %d\n,gps.satellites.value());if(gps.hdop.isValid()){Serial.printf(HDOP: %.2f\n,gps.hdop.hdop());}if(gps.altitude.isValid()){Serial.printf(海拔高度: %.2f m\n,gps.altitude.meters());}}else{Serial.println(定位状态: 无效);Serial.println(请将天线放置在开阔地带...);Serial.printf(已处理字符数: %lu\n,gps.charsProcessed());}Serial.println();Serial.println();}if(gps.charsProcessed()10){Serial.println(等待GPS数据...);delay(500);}}// 经纬度转ENU坐标voidlatLngToENU(doublelat,doublelng,doublerefLat,doublerefLng,doubleeast,doublenorth){constdoubleR6378137.0;// 地球半径(米)doublelatRadlat*M_PI/180.0;doublelngRadlng*M_PI/180.0;doublerefLatRadrefLat*M_PI/180.0;doublerefLngRadrefLng*M_PI/180.0;doublecosLatcos(refLatRad);eastR*(lngRad-refLngRad)*cosLat;northR*(latRad-refLatRad);}3.2 关键技术解析3.2.1 NMEA数据解析TinyGPSPlus通过gps.encode()方法逐字符解析NMEA数据流while(GPS_UART.available()0){gps.encode(GPS_UART.read());}解析后的关键数据gps.location.lat()- 纬度十进制度gps.location.lng()- 经度十进制度gps.speed.kmph()- 对地速度km/hgps.course.deg()- 航向角度度3.2.2 本地墨卡托投影ENU坐标系原理将地球表面近似为平面以首次定位点为原点建立东-北-天坐标系。核心公式eastR*(lng-refLng)*cos(refLat)northR*(lat-refLat)其中R 地球半径6378137米refLat,refLng 参考点经纬度east,north 相对于参考点的东向、北向偏移米3.2.3 速度与航向计算// 速度 位移 / 时间calcSpeedsqrt(dx*dxdy*dy)/dt*3.6;// 航向 arctan2(东向位移, 北向位移)calcHeadingatan2(dx,dy)*180.0/M_PI;说明速度单位转换m/s × 3.6 km/h航向范围0°正北→ 90°正东→ 180°正南→ 270°正西四、测试结果串口接收数据4.1 输出示例 定位状态: 有效 UTC时间: 13:01:11.600 日期: 2026-06-24 纬度: 38.869444° 经度: 121.532086° 东向偏移: -1.430 m 北向偏移: 2.727 m 计算航速: 3.079846 km/h 计算航向: 317.520691° 原始航速: 2.277960 km/h 原始航向: 323.150000° 卫星数量: 21 HDOP: 0.80 海拔高度: 82.00 m 4.2 数据对比分析参数原始GPS数据计算值ENU说明航速2.28 km/h3.08 km/h计算值更接近实际运动状态航向323.15°317.52°计算值基于实际位移方向4.3 关键指标定位精度水平精度优于1米HDOP 1.0卫星数量21颗GPS北斗双模更新频率约10Hz模块输出计算频率2Hz程序设定五、常见问题排查5.1 定位无效现象定位状态: 无效排查步骤检查天线连接是否牢固确保天线在室外开阔处等待至少30秒冷启动时间检查串口波特率是否正确ATGM332D默认96005.2 速度为0现象计算航速: 0.00 km/h排查步骤检查是否有连续的位置变化确认参考点已设置首次定位后检查时间差计算是否正确5.3 航向跳变现象航向角度突变原因GPS定位存在微小抖动低速运动时位移量小噪声影响大解决方案增加滤波算法如卡尔曼滤波对连续多个采样点进行平滑处理六、总结本文实现了从GPS数据采集到速度航向计算的完整流程硬件层面使用ESP32硬件串口与ATGM332D模块通信数据解析利用TinyGPSPlus库高效解析NMEA语句坐标转换通过本地墨卡托投影建立ENU坐标系速度计算基于位移差分计算真实运动参数该方案适用于无人机、机器人、车辆等需要实时定位和运动状态监测的应用场景。参考资料TinyGPSPlus官方文档ATGM332D模块手册NMEA-0183协议标准
RELATED

相关推荐

最近,架构的招聘市场已经疯掉了。。。

最近,架构的招聘市场已经疯掉了。。。

AI Coding,问世不到3年,职场已经天翻地覆! 感受到最近的招聘变化了吗?尤其是大厂的招聘动作:以前还分前端、后端、架构师……现在岗位表上只写四个字:Agent工程师! 为什么会有如此变化&#x…

📅 2026/9/20 14:32:35
早期停止聚合:用并行短任务加速统计推断与机器学习计算

早期停止聚合:用并行短任务加速统计推断与机器学习计算

1. 项目概述:当“提前下班”遇上统计推断在统计建模和机器学习的世界里,我们常常面临一个经典困境:计算成本与推断精度之间的拉锯战。无论是运行一个复杂的贝叶斯马尔可夫链蒙特卡洛模拟,还是执行一个需要大量重采样的频率派自助法…

📅 2026/9/18 13:39:05
Burp Suite与安卓模拟器抓包实战:解密HTTPS与微信小程序网络分析

Burp Suite与安卓模拟器抓包实战:解密HTTPS与微信小程序网络分析

1. 项目概述:为什么需要抓包模拟器?在移动应用和微信小程序的开发、测试乃至安全评估过程中,一个核心的痛点就是:我们如何像在浏览器里按F12一样,清晰地看到手机里每一个APP、每一个小程序发出的网络请求和接收的响应&…

📅 2026/9/19 10:25:05
MORE NEWS

更多资讯

📰

实时数据处理实战:DeepSeek流式响应与长文本分块全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

复购是最好的口碑!苏州银行再次成交御鑫箱智能电子印章柜项目,金融印章管控标杆案例这样炼成

近日,苏州银行苏州分行发布成交通知书,深圳市顺易通信息技术有限公司(智能印章品牌“御鑫箱”)经单一来源谈判,被确定为“2026年苏州银行苏州分行智能电子印章柜租赁货物采购项目”成交供应商。这是双方自2019年首次合…

📰

Microduck评测:399美元跑通具身智能与模仿学习全链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Adobe Acrobat 2026最新保姆级安装教程

一、Adobe Acrobat 2026 软件介绍 1. 什么是 Adobe Acrobat 2026? Adobe Acrobat 2026 是 Adobe 公司推出的新一代 PDF 文档处理软件,专注于 PDF 文件的创建、编辑、转换、管理和协作。 通过 Acrobat 2026,用户可以快速处理各种办公文档&a…

📰

Linux 启动流程与 systemd 运行目标实战手册

从按下电源键到出现登录提示符,要经过固件自检、GRUB2 引导、内核与 initramfs、systemd 拉起 target 一串环节,任何一环断了系统就起不来。 本文把启动过程拆成九步,讲清 systemd target 与传统运行级别的对应、运行目标的查看与切换&#x…

📰

单视频三维实时重构驱动的武警突发事件力量调度推演与区域封控方案智能生成技术白皮书

前言武警突发事件应急处置、现场力量调度、区域立体封控是遂行处突维稳、应急安保、风险隔离任务的核心关键环节。面对人群聚集滋事、突发冲闯、现场险情、陌生区域突发警情等各类突发事件,传统处置模式长期依赖“人工看屏、经验研判、口头调度、固定预案”&#xf…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬