如何实现ESP32以2kHz频率发送模拟信号并稳定传输至Python?
解决ESP32 2kHz ECG采样频率波动及数据格式异常问题
数据格式异常的原因与修复
- 串口波特率不匹配:ESP32代码设置的
74880与Python脚本的115200不一致,直接导致数据乱码(如128r/110这类异常格式),必须统一波特率。 - ESP32代码缺失引脚定义:原代码未声明
analogPin变量,编译后会导致采样错误,需根据实际硬件连接添加引脚定义(如const int analogPin = 34;)。 - Python脚本初始化问题:未导入
time模块、未初始化data列表,且首次读取时串口缓冲区可能残留旧数据,需清空缓冲区后再开始采样。
采样频率不稳定的原因与修复
- 字符串传输效率过低:原代码用
Serial.println()发送字符串,每个样本需传输多个字符(含换行符),2kHz采样率下会造成串口阻塞,打乱采样周期。改用二进制传输可大幅提升效率。 - 采样间隔控制逻辑缺陷:原代码的忙等延迟未考虑串口发送耗时,若发送时间超过
periodUs,实际采样间隔会被拉长。改用"绝对时间触发"方式,固定下一次采样的时间点,避免延迟累积。 - Python端读取逻辑缺陷:原代码依赖
readline()读取字符串,换行符解析开销大且易丢包,改为读取二进制数据可减少解析耗时,同时设置合理超时避免阻塞。
修改后的ESP32代码
const int sampleRate = 2000; const int analogPin = 34; // 根据实际连接的ADC引脚修改 unsigned long nextSampleTime = 0; void setup() { Serial.begin(115200); // 与Python端统一波特率 analogReadResolution(12); // ESP32默认12位ADC,可根据需求调整 } void loop() { // 采用绝对时间触发采样,保证间隔稳定 if (micros() >= nextSampleTime) { uint16_t adcValue = analogRead(analogPin); // 以二进制发送ADC值(2字节,比字符串快数倍) Serial.write((uint8_t*)&adcValue, sizeof(adcValue)); // 更新下一次采样时间 nextSampleTime += 1000000 / sampleRate; // 处理时间溢出(避免系统时间绕回后无法触发) if (nextSampleTime < micros()) { nextSampleTime = micros() + 1000000 / sampleRate; } } }
修改后的Python脚本
import serial import time # 初始化串口,设置短超时避免阻塞 ser = serial.Serial(port='COM7', baudrate=115200, timeout=0.001) ser.flushInput() # 清空缓冲区残留数据,避免首次读取乱码 data = [] sample_duration = 10 # 采样时长10秒 t0 = time.time() t_end = t0 + sample_duration while time.time() < t_end: # 读取2字节二进制数据(对应ESP32发送的uint16_t类型) byte_data = ser.read(2) if len(byte_data) == 2: # 解析二进制数据,匹配ESP32的小端字节序 adc_value = int.from_bytes(byte_data, byteorder='little') data.append(adc_value) t1 = time.time() actual_sample_count = len(data) actual_sample_rate = round(actual_sample_count / (t1 - t0)) print(f"实际采样频率: {actual_sample_rate} Hz") print(f"累计采样样本数: {actual_sample_count}")
进阶优化建议
- 使用定时器中断采样:若需要更高精度的采样间隔,可利用ESP32的定时器中断触发ADC采样和数据发送,彻底脱离
loop()函数的执行干扰。 - 启用硬件流控:若串口传输仍存在瓶颈,可在ESP32和Python端同时启用RTS/CTS硬件流控,避免数据丢失。
- Python端线程读取:将串口读取逻辑放在独立线程中,避免主线程阻塞导致漏读样本。
内容的提问来源于stack exchange,提问作者Raúl Nieto
相关产品推荐
相关产品推荐

