多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

ESP32+JY61P姿态传感器无线采集与UDP传输实战

ESP32+JY61P姿态传感器无线采集与UDP传输实战 最近在给一台小型机械臂做姿态反馈需要把JY61P姿态传感器的角度数据实时送到电脑上画曲线绕了一圈最后定了ESP32WiFi这套方案。这个项目一句话就能说清楚用ESP32读取JY61P模块的串口输出解析出roll、pitch、yaw三个姿态角再通过WiFi把数据发到同一局域网内的电脑上供上位机处理或显示。整套东西做下来难度不大非常适合刚接触物联网的人练手也适合需要快速搭建无线姿态采集链路的机器人爱好者参考。先说结论这套方案的成本不到五十块钱硬件连接只有四根线软件部分核心就是串口解析和UDP发包两个动作。如果之前玩过Arduino基本一个晚上就能跑通。下面我把完整的选型思路、接线方式、协议解析、代码实现和踩坑记录都写出来照着做就行。1. 项目整体设计与方案选型1.1 为什么是ESP32JY61P这套组合先聊选型。姿态采集方案其实有很多种常见的有直接用MPU6050裸传感器配STM32、用带蓝牙的模块、用ESP32直接读取MPU6050以及现在这套ESP32JY61P组合。我为什么最后选了后者ESP32的优势在于它天生就是为物联网设计的双核240MHz自带WiFi和蓝牙Arduino生态非常成熟一块开发板二十几块钱资料多到看不完。更重要的是它自带硬件UART接口读串口传感器非常方便根本不用外接USB转TTL芯片。JY61P则是维特智能推出的一款六轴姿态传感器模块内部已经把MPU6050的原始数据做了姿态解算直接通过串口输出欧拉角。换句话说你不需要自己去写卡尔曼滤波或互补滤波不用跟四元数死磕插上电就能拿到稳定的角度数据。这点在工程上太重要了因为姿态解算看着简单实际调起来非常耗时间尤其是动态漂移的问题没有点功底很难处理好。JY61P相当于把这块最费脑子的部分封装好了你花钱买时间划算。对比一下直接读MPU6050的方案虽然能省下模块的钱但你要自己处理I2C时序、自己写滤波算法、自己校准零漂。我早期做过一次光调试静态稳定性就花了两天。如果项目重点是无线链路的搭建而不是姿态解算本身那直接用JY61P是更理性的选择。1.2 通信链路串口采集、WiFi转发整个数据流是这样的JY61P通过UART串口把姿态数据实时输出给ESP32ESP32在这里扮演的其实是网关的角色它先把串口数据解析成有意义的姿态角再打包成UDP数据包通过WiFi发到电脑上。为什么中间非要加一个ESP32而不是让JY61P直接通过USB连电脑因为JY61P本身不具备联网能力它的接口只有串口而且它的供电电压是3.3V TTL电平插到电脑USB口上还得额外加转换芯片。加了ESP32之后整个系统就完全无线化了传感器可以装在移动设备上、机械臂末端、小车底盘上数据照样能回到电脑端。在传输层协议上我选的是UDP而不是TCP。原因很简单传感器数据是周期性的连续流每一帧数据之间有很强的时间相关性偶尔丢一两个包完全不影响整体效果下一帧马上就能补上。UDP是无连接的发送方只管把数据丢出去不需要握手、确认和重传延迟低、开销小。TCP虽然可靠但它的重传机制在这种高频数据流场景下反而是负担一旦网络抖动TCP会拼命重传旧数据导致新数据排队延迟越来越大。打个不严谨的比方TCP像快递签收每一件都要确认收到UDP像广播喇叭喊一嗓子就完事听不听得到看现场环境。姿态采集这种场景显然广播喇叭更合适。1.3 典型应用场景这个项目本质上是一条通用的“串口传感器WiFi无线传输”链路所以可复用的场景非常多机械臂关节角度反馈实时监控每个轴的转动状态自平衡小车/两轮车的姿态环数据采集代替有线连接云台角度闭环控制把传感器装在负载端通过WiFi把角度回传主控人体姿态捕捉的简易原型多个JY61P挂在四肢上数据汇集到PC端旋转平台、天线转台的远程角度监控。只要传感器是串口输出的这套代码框架都能直接用改一下协议解析部分就行。2. 硬件准备与关键接线2.1 硬件清单先列一下需要的材料都很常见ESP32开发板一块推荐DevKit V1这种30引脚的标准板某宝二十几块钱注意选带USB转串口芯片的版本用起来省心JY61P模块一个维特智能出品搜索型号就能找到三四十块钱杜邦线若干母对母的最方便建议准备四根面包板一块可选方便固定和供电MicroUSB或Type-C数据线一根用于给ESP32供电和烧录程序手机充电头或充电宝一个5V/1A以上即可。2.2 引脚定义与接线表JY61P模块常用的引脚有四个VCC、GND、TX、RX。其中VCC接电源正极GND接地TX是模块的串口发送脚RX是接收脚。接线方式很简单核心是“交叉连接共地供电”。我用的ESP32的UART2接口对应GPIO16RX2和GPIO17TX2。接线表如下JY61P引脚接ESP32引脚说明VCC3.3V模块供电3.3V更稳妥GNDGND必须共地否则数据乱码TXGPIO16RX2模块发送ESP32接收交叉接RXGPIO17TX2模块接收如果要配置模块才需要接平时可悬空为什么选择GPIO16和GPIO17因为这两个引脚对应的是ESP32的UART2和烧录用的UART0互不干扰。ESP32的UART0默认接在USB转串口芯片上用来和电脑通信和烧录程序。如果我把JY61P接到UART0的TX/RX引脚上每次烧录程序还要把线拔掉非常麻烦。UART2就是专门的通用串口留给外设正合适。2.3 接线注意事项与供电细节接线部分有几个细节特别值得注意都是我用实践换来的教训。第一共地必须强调一万遍。ESP32的GND和JY61P的GND一定要接在一起否则两个模块的电平基准不同串口数据必然乱码或者完全没反应。很多人说“我接好了但收不到数据”十有八九是共地没做好。第二电平匹配问题。JY61P支持3.3V~5V供电但它的串口电平是TTL 3.3V而ESP32的GPIO也是3.3V电平两者直连没有问题。我建议给模块统一供3.3V这样最安全。不要用5V去给JY61P供电然后直连ESP32虽然有些板子内部有电平处理但跨压操作始终不放心。第三注意上电顺序。我习惯先把JY61P的供电接好然后再给ESP32上电烧录。因为USB枚举瞬间的电压抖动可能导致模块异常复位如果恰好卡在烧录的时候会莫名其妙地出现连接失败。第四千万别把JY61P的TX接到GPIO0或者GPIO12这类启动时有关键电平要求的引脚上。GPIO0在ESP32下载程序时要求是低电平如果这个引脚被外部设备拉高或拉低会造成烧录失败或者启动异常现象很诡异程序烧不进去或者烧进去跑不起来。所以老老实实用GPIO16和GPIO17最省事。3. 软件环境准备Arduino IDE与ESP32支持包3.1 Arduino IDE安装与ESP32开发板支持软件部分我用的Arduino IDE因为ESP32的Arduino支持包非常成熟代码写起来直观调试也方便。如果你还没安装Arduino IDE建议直接装2.x版本界面和包管理比1.8好很多。安装完IDE之后第一步是添加ESP32开发板支持包。打开“文件”-“首选项”在“附加开发板管理器网址”里添加以下地址https://dl.espressif.com/dl/package_esp32_index.json然后打开“工具”-“开发板”-“开发板管理器”搜索“esp32”找到“esp32 by Espressif Systems”安装。这个包比较大下载时间取决于网络情况耐心等待即可。安装完成后在开发板列表里选择“ESP32 Dev Module”就完成了基础配置。有一个小坑刚安装完支持包后编译速度会偏慢因为第一次要编译很多底层的库后面就快了。如果编译报错提示找不到“WiFi.h”说明开发板支持包没装好重新在开发板管理器里检查一下。3.2 烧录与串口验证在正式写代码之前建议先用一个最简单的Blink程序验证工具链是否正常。Arduino自带的Blink示例就可以只是注意ESP32板载LED的引脚通常接在GPIO2上要把示例里的LED_BUILTIN换成2或者直接用LED_BUILTIN不同开发板定义不一样看自己的板子说明书。编译通过后连接ESP32到电脑在“工具”-“端口”里选择对应的COM口。点击上传按钮如果出现连接失败试着按住开发板上的BOOT键再点上传等待出现“Connecting..._____”之后松手。烧录完成后板载LED应该开始闪烁这说明环境已经OK了。4. JY61P数据协议解析与读取代码4.1 JY61P的输出帧结构JY61P默认波特率是115200数据位8停止位1无校验也就是常说的115200 8N1。模块上电后会主动向上位机发送数据包不需要发送任何配置指令。这点很方便特别是对新手来说少了一道交互流程。它的数据包以帧头0x55起始第二个字节是数据类型标识常见的三种0x51加速度数据包0x52角速度数据包0x53角度数据包本项目只需要角度数据所以关注0x53这个类型即可。一个完整的角度数据包总长11字节结构如下字节序号内容说明00x55帧头10x53数据类型角度包2RollLRoll角度低字节3RollHRoll角度高字节4PitchLPitch角度低字节5PitchHPitch角度高字节6YawLYaw角度低字节7YawHYaw角度高字节8TL温度低字节9TH温度高字节10SUM校验和角度数据是int16类型小端序存储实际角度值的换算公式是角度 原始值 / 32768 * 180度。因为模块内部的角度量程是±180度而int16的满量程正好是±32768对应关系非常直接。温度值也是int16换算公式是 温度 原始值 / 100摄氏度不过本项目的重点是姿态角温度不处理也没关系。校验和的算法是从帧头0x55开始一直到第9字节的TH所有字节累加取累加和的低8位结果等于第10字节的SUM。也就是说SUM (0x55 0x53 RollL RollH PitchL PitchH YawL YawH TL TH) 0xFF这个校验非常重要因为串口通信在干扰环境下偶尔会出错如果不对校验和可能解析出完全离谱的角度值导致上位机数据乱跳。4.2 解析思路状态机处理串口字节流串口的本质是一个字节一个字节地往外吐数据中间没有明显的“帧”边界。如果直接在循环里一个个找0x55非常容易出错因为数据内容里也可能出现0x55这个字节比如角度值恰好是0x55XX。这时候就需要用状态机来切帧。状态机的思路是定义一个状态变量记录当前解析到了帧的哪个位置。一开始处于“等待帧头”状态只有收到0x55才进入“等待类型”状态收到合法的类型字节0x51/0x52/0x53后进入“接收数据”状态连续接收8个数据字节后进入“等待校验”状态收到校验字节后判断是否正确然后无论对错都回到“等待帧头”状态。这样做的好处是严格的同步机制即使中间某一帧坏了下一帧的帧头也能重新对齐不会导致后续所有数据全部错位。这也是工业串口协议解析的标准做法。4.3 Arduino读取代码示例下面给出一段独立的JY61P读取代码使用ESP32的UART2GPIO16接收把解析出的角度通过USB串口打印到Arduino IDE的串口监视器上。先跑通这一步再上WiFi。// ESP32 JY61P 串口读取和解析 // 使用 UART2: RXGPIO16, TXGPIO17 #define RXD2 16 #define TXD2 17 // 解析状态机 enum State { WAIT_HEAD, WAIT_TYPE, WAIT_DATA, WAIT_CHECK }; State state WAIT_HEAD; uint8_t frameBuf[11]; int frameIndex 0; uint8_t frameType 0; uint8_t checkSum 0; void handleData(uint8_t *buf) { // 0x53 角度包 if (buf[1] 0x53) { int16_t rollRaw (buf[3] 8) | buf[2]; int16_t pitchRaw (buf[5] 8) | buf[4]; int16_t yawRaw (buf[7] 8) | buf[6]; float roll rollRaw / 32768.0 * 180.0; float pitch pitchRaw / 32768.0 * 180.0; float yaw yawRaw / 32768.0 * 180.0; Serial.printf(roll%.2f pitch%.2f yaw%.2f\n, roll, pitch, yaw); } } void parseByte(uint8_t c) { switch (state) { case WAIT_HEAD: if (c 0x55) { frameBuf[0] c; checkSum c; state WAIT_TYPE; } break; case WAIT_TYPE: if (c 0x51 || c 0x52 || c 0x53) { frameBuf[1] c; checkSum c; frameType c; frameIndex 2; state WAIT_DATA; } else { state WAIT_HEAD; // 类型不合法重新找帧头 } break; case WAIT_DATA: frameBuf[frameIndex] c; checkSum c; frameIndex; if (frameIndex 10) { state WAIT_CHECK; } break; case WAIT_CHECK: if (c (checkSum 0xFF)) { handleData(frameBuf); } state WAIT_HEAD; break; } } void setup() { Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); Serial.println(JY61P Test Start); } void loop() { while (Serial2.available()) { parseByte(Serial2.read()); } }烧录到ESP32后打开串口监视器波特率选115200如果接线没问题可以看到不断滚动的roll、pitch、yaw数据。这时候转动JY61P对应的角度值应该跟着变化。如果这里能跑通说明整个链路的一半已经完成了。4.4 备选方案使用WitMotion官方库有朋友嫌自己写状态机麻烦其实维特智能官方也提供了Arduino库名字叫“WitMotion”在Arduino库管理器里可以直接搜到。使用官方库的代码如下#include WitMotion.h WitMotion jy61p; void setup() { Serial.begin(115200); jy61p.begin(Serial2); } void loop() { if (jy61p.update()) { Serial.printf(roll%.2f pitch%.2f yaw%.2f\n, jy61p.roll, jy61p.pitch, jy61p.yaw); } delay(10); }官方库把协议解析封装好了配置也简单适合不想深入了解协议的人。不过我依然建议自己写一遍解析代码因为工业场景里串口传感器种类很多帧格式各有不同掌握了状态机拆帧的技能换任何传感器都能应对。官方库是一个黑盒一旦出了问题不好排查。5. 连接WiFi并通过UDP发送数据到电脑5.1 WiFi连接流程串口数据解析通了接下来就是给ESP32联网。ESP32连接WiFi的代码很固定无非是这几步设置工作模式为STA、调用begin传入SSID和密码、循环等待连接成功。#include WiFi.h const char* ssid your_wifi_name; const char* password your_wifi_password; void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print(Connecting to WiFi); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(); Serial.print(Connected, IP: ); Serial.println(WiFi.localIP()); }唯一需要特别注意的是频段问题。ESP32只支持2.4GHz频段的WiFi如果路由器开了5GHz或者“双频合一”模式ESP32很可能连不上或者连上后频繁掉线。解决办法是登录路由器后台把WiFi频段固定为2.4GHz或者给ESP32单独开一个访客网络。这个坑我踩过折腾了半天最后发现是路由器把2.4G和5G合并了。为了方便调试建议在路由器里给ESP32分配一个固定IP或者在代码里手动配置静态IP。这样电脑端监听程序不用每次去查IP变化。但项目初步阶段动态IP也没问题ESP32上电后打印一下自己的IP就行。5.2 为什么推荐UDP而不是TCP前面提过UDP的优势这里再展开说一下。姿态数据的典型特征是高频率、小数据包、允许少量丢失。JY61P默认输出频率是100Hz也就是每秒100帧数据。如果每帧都用TCP发送每包都要经过三次握手建立的连接通道虽然连接是长连接但TCP的确认机制和拥塞控制还是会引入额外延迟尤其是WiFi环境本身就不稳定TCP重传会造成数据包的排队和乱序。UDP则完全没有这些负担。数据包发出去就结束1对1也好1对多也好代码实现都非常简单。在局域网这种低延迟、低丢包的环境下UDP的可靠性其实相当高。实测下来100Hz的数据流丢包率远低于千分之一对姿态显示没有任何影响。当然了如果后续要做的是指令下发、参数配置这类要求可靠传输的功能那就老老实实用TCP或者HTTP。UDP适合的是传感器数据上行这种场景要区分清楚。5.3 UDP发送代码与电脑端监听UDP发送用Arduino的WiFiUDP库核心就三个方法beginPacket、print/printf、endPacket。示例代码如下#include WiFiUdp.h WiFiUDP udp; const IPAddress pcIP(192, 168, 1, 100); // 改成你电脑的IP const unsigned int pcPort 8888; void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); } udp.begin(pcPort); // 本机绑定端口可选 } void loop() { udp.beginPacket(pcIP, pcPort); udp.printf(hello from esp32\n); udp.endPacket(); delay(100); }电脑端的IP地址查看方法Windows在命令行里输入ipconfig找“无线局域网适配器”里的IPv4地址macOS或Linux在终端里输入ifconfig找en0或wlan0的inet地址。电脑和ESP32必须在同一个网段下比如路由器分配的IP都是192.168.1.x。电脑端用Python写一个最简单的UDP监听脚本import socket sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((0.0.0.0, 8888)) print(Listening on UDP port 8888...) while True: data, addr sock.recvfrom(1024) print(data.decode().strip())运行这个脚本后如果ESP32的WiFi连上了电脑端的防火墙也没拦UDP包终端里应该能不断打印出ESP32发来的“hello”字符串。这一步通了说明“传感器数据无线回传”的核心链路已经打通。6. 整体联调JY61P数据经WiFi回传电脑6.1 完整代码整合把前几节的代码整合起来就是一个完整的ESP32JY61PWiFi无线姿态采集程序。代码里已经包含了SSID、密码、电脑IP和端口按自己的环境修改即可。#include WiFi.h #include WiFiUdp.h // WiFi配置 const char* ssid your_wifi_name; const char* password your_wifi_password; // 电脑端配置 const IPAddress pcIP(192, 168, 1, 100); const unsigned int pcPort 8888; WiFiUDP udp; // JY61P 串口引脚 #define RXD2 16 #define TXD2 17 // 解析状态机 enum State { WAIT_HEAD, WAIT_TYPE, WAIT_DATA, WAIT_CHECK }; State state WAIT_HEAD; uint8_t frameBuf[11]; int frameIndex 0; uint8_t frameType 0; uint8_t checkSum 0; void sendAngleByUDP(uint8_t *buf) { int16_t rollRaw (buf[3] 8) | buf[2]; int16_t pitchRaw (buf[5] 8) | buf[4]; int16_t yawRaw (buf[7] 8) | buf[6]; float roll rollRaw / 32768.0 * 180.0; float pitch pitchRaw / 32768.0 * 180.0; float yaw yawRaw / 32768.0 * 180.0; // 数据格式: roll,pitch,yaw udp.beginPacket(pcIP, pcPort); udp.printf(%.2f,%.2f,%.2f\n, roll, pitch, yaw); udp.endPacket(); } void parseByte(uint8_t c) { switch (state) { case WAIT_HEAD: if (c 0x55) { frameBuf[0] c; checkSum c; state WAIT_TYPE; } break; case WAIT_TYPE: if (c 0x51 || c 0x52 || c 0x53) { frameBuf[1] c; checkSum c; frameType c; frameIndex 2; state WAIT_DATA; } else { state WAIT_HEAD; } break; case WAIT_DATA: frameBuf[frameIndex] c; checkSum c; frameIndex; if (frameIndex 10) { state WAIT_CHECK; } break; case WAIT_CHECK: if (c (checkSum 0xFF)) { if (frameType 0x53) { sendAngleByUDP(frameBuf); } } state WAIT_HEAD; break; } } void setup() { Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); // 连接WiFi WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print(Connecting to WiFi); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(); Serial.print(ESP32 IP: ); Serial.println(WiFi.localIP()); udp.begin(pcPort); } void loop() { while (Serial2.available()) { parseByte(Serial2.read()); } }代码逻辑并不复杂setup里完成串口、WiFi和UDP的初始化loop里持续从Serial2读取JY61P发来的字节交给状态机解析解析到合法的0x53角度包后计算三个欧拉角通过UDP发送到电脑端。Serial.printf打印调试信息依旧走USB串口完全不影响WiFi发送。6.2 电脑端接收与可视化测试电脑端运行前面那个Python监听脚本接收波特率匹配那次我们已经确认了。如果一切正常终端里会出现类似下面的输出12.34,5.67,-89.01 12.35,5.68,-89.02 12.36,5.69,-89.03三列数据分别对应roll、pitch、yaw。物理上转动JY61P对应数值会实时变化响应延迟在毫秒级肉眼几乎感觉不到延迟。想看可视化的曲线可以用Python的matplotlib库做一个简单的实时绘图窗口。这个属于扩展内容网上有很多现成的例子关键词搜“matplotlib 实时绘图 UDP”就能找到。如果想做更专业的上位机可以用pyqtgraph或Processing效果会好很多。6.3 发送频率与数据包格式设计JY61P默认输出频率是100Hz但实际上并不是每个0x53角度包都干净利落地被发送。串口中断和WiFi发送都需要时间如果每收到一帧就立刻UDP发送可能会出现微小的节奏抖动。实测下来100Hz完全能扛住但如果电脑端的接收缓冲区不够大长时间运行有掉包风险。我建议根据实际需求控制发送频率。如果只是简单监控可以加一个简单的节流判断比如每50ms发送一次最新角度也就是20Hz。如果做机械臂姿态反馈或者自动控制那100Hz是底线建议保持全速发送。UDP包本身很小一个包不到30字节100包/秒也就是每秒3KB流量对WiFi来说九牛一毛。数据包格式建议用CSV也就是纯文本加逗号分隔。因为UDP本身没有规定格式用CSV最直观电脑端一行split(,)就能解析成三个浮点数。如果以后要传输更多字段比如加速度、角速度、温度可以继续往后面追加格式保持兼容即可。7. 常见问题与排查技巧实录做一个项目不踩坑是不可能的。我把实际过程中遇到的典型问题整理成了速查表方便大家对照排查。现象可能原因解决办法串口监视器没有任何输出JY61P供电没接好检查VCC和GND确认共地串口输出全是乱码波特率不匹配确认JY61P是115200串口监视器也选115200数据偶发跳变干扰或接线过长杜邦线尽量短避开电机等强干扰源校验和频繁错误供电不足导致模块异常换优质电源不要用劣质USB口供电WiFi连不上路由器开了5GHz或双频合一固定到2.4GHz频段或开访客网络WiFi连上但收不到UDPWindows防火墙拦截在防火墙入站规则里放行UDP 8888端口烧录程序失败GPIO引脚冲突下载时按住BOOT键检查外设是否占用GPIO0程序烧录后反复重启供电电流不够换5V/2A电源避免电脑USB口供电不足7.1 串口调试通了再上WiFi这里分享一个我自己的实战习惯永远先串口后WiFi。也就是先把JY61P的数据通过USB串口打印在电脑上看确认硬件接线和解析逻辑完全正确再去连WiFi、写UDP。这样一旦出了问题排查范围能缩小一半。很多新手一上来就把WiFi和UDP代码全写上结果收不到数据根本分不清到底是传感器没接好还是解析代码有bug还是WiFi配置有问题。分层验证是最稳的方案虽然多花几分钟但能省下一个晚上的排查时间。7.2 供电不足引起的诡异问题ESP32的开发板在WiFi发射的时候瞬时电流可能到几百毫安如果电源质量不好电压会被拉低导致JY61P也工作不稳定。症状很典型上电时一切正常一旦WiFi连上开始发送数据板子就重启或者数据开始出现校验错误。解决办法很简单给ESP32用一个靠谱的5V电源比如手机充电头或者大容量充电宝尽量不要用电脑前置USB口的供电。JY61P的VCC接在ESP32的3.3V引脚上所以ESP32的电源质量直接决定JY61P的稳定性。如果单独给JY61P供3.3V记得GND还是要和ESP32连在一起。7.3 防火墙与端口设置电脑端收不到UDP数据排除WiFi问题后十有八九是防火墙拦截了入站UDP包。Windows的防火墙默认情况下会拦截陌生程序的入站流量尤其Python解释器或者Java虚拟机这类没有在允许列表里的程序。临时解决办法是关闭防火墙测试注意生产环境不建议这么干或者更规范的做法是在“Windows Defender防火墙”的“高级设置”里添加入站规则放行UDP协议、指定本地端口8888、允许所有程序。这样既安全又能正常接收数据。8. 项目扩展思路8.1 数据记录与回放如果要做数据分析或实验复盘可以在电脑端把接收到的数据实时写入CSV文件。Python监听脚本里加几行文件写入代码就行每收到一行数据就追加到文件末尾。这样跑完一次实验就能拿到一份完整的姿态数据导入Excel或者Matlab分析都很方便。8.2 多传感器接入与多轴可视化一个ESP32的UART2只能接一个JY61P但ESP32其实有多个UART。比如UART1、UART2都可以接只是注意不要和Flash芯片占用的引脚冲突GPIO6~GPIO11默认给Flash用了尽量避开。如果你需要监测多个姿态点比如人体四肢可以买多个JY61P模块分别接到不同的UART上然后在ESP32上按端口区分数据来源统一通过UDP发到电脑。电脑端接收时可以根据数据包里的设备标识来区分不同的传感器节点。这样一套系统就能同时监控多个姿态点做人体姿态捕捉的基础原型完全够用。8.3 与ROS 2/micro-ROS结合如果你做机器人开发可以把这套无线姿态采集方案接入ROS 2生态。ESP32上运行micro-ROS节点把roll、pitch、yaw发布为sensor_msgs/Imu或者自定义的Float32MultiArray话题上位机直接用ROS 2工具链订阅数据。这个方向适合已经接触过ROS 2的朋友初期不建议直接上手先把基础链路跑通再说。8.4 增加自动校准与交互功能JY61P出厂前已经做了标定零点漂移很小直接可用。但如果你追求更高的精度可以加上电自校准逻辑在模块静止状态下采集100帧数据求平均作为零偏然后在后续数据中扣除。这个校准逻辑放在ESP32解析代码里实现即可不需要改模块配置。另外如果想让系统具备交互能力可以把ESP32的蓝牙也打开通过手机App直接看角度。有了WiFi和蓝牙双重通道这套系统的应用范围会宽很多。这个项目看着简单但真正动手做一遍串口协议解析、状态机设计、WiFi通信这几块基本功都能得到实打实的锻炼。我做完之后的体会是任何一个环节不扎实都会出问题尤其是串口字节处理写代码时觉得思路很清晰一上板子各种边角情况全冒出来了。建议你从串口读数据开始一步一步往上加功能不要一口吃成胖子。无线数据传输这条链路打通之后后面想接什么传感器、做什么应用都只是换个协议解析的事。
返回列表