You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Arduino IDE中通过ESP8266读取STM32的UART数据包?

ESP8266读取STM32串口数据的实现方案

基础字符串格式读取与拆分

你的STM32通过UART发送的是空格分隔的11个整数+1个浮点数,以分号结尾的字符串数据包。ESP8266端可以按以下步骤读取解析:

实现代码

void setup() {
  // 初始化串口,波特率必须和STM32的UART配置一致
  Serial.begin(115200);
  // 若使用非默认串口引脚,可改用SoftwareSerial:
  // #include <SoftwareSerial.h>
  // SoftwareSerial stm32Serial(D2, D3); // RX接STM32的TX,TX接STM32的RX
  // stm32Serial.begin(115200);
}

void loop() {
  // 检查串口是否有数据
  if (Serial.available() > 0) {
    // 读取到分号为止,获取完整数据包
    String receivedPacket = Serial.readStringUntil(';');
    
    if (receivedPacket.length() > 0) {
      // 定义对应变量存储解析结果
      int32_t ir_average, red_average, dcFilterIRresult, dcFilterRedresult;
      int32_t chebyshevResult2, elipticResult2, wyjscie, bpm_up;
      int32_t fftbmp, currentSaO2Value, spo2Calib;
      float temp;

      // 用sscanf按格式解析,格式需和STM32的sprintf完全匹配
      int parseCount = sscanf(receivedPacket.c_str(), "%d %d %d %d %d %d %d %d %d %d %d %f",
                              &ir_average, &red_average, &dcFilterIRresult, &dcFilterRedresult,
                              &chebyshevResult2, &elipticResult2, &wyjscie, &bpm_up,
                              &fftbmp, &currentSaO2Value, &spo2Calib, &temp);

      if (parseCount == 12) { // 成功解析全部12个数据
        // 这里处理解析后的数据,示例:打印
        Serial.print("IR平均: "); Serial.println(ir_average);
        Serial.print("实时血氧: "); Serial.println(currentSaO2Value);
        Serial.print("温度: "); Serial.println(temp);
        // 其他数据按需处理
      } else {
        // 解析失败,输出错误信息
        Serial.print("解析失败,原始数据包: "); Serial.println(receivedPacket);
      }
    }
  }
}

更优实现方案:二进制数据包传输

字符串格式虽然直观,但解析效率低且容易因字符传输错误导致解析失败。更可靠高效的方式是直接传输二进制数据,步骤如下:

1. STM32端修改发送逻辑

定义统一的结构体存储传感器数据,直接发送结构体的字节流:

// 定义数据结构体,确保字段顺序和类型与ESP8266端一致
typedef struct {
  int32_t ir_average;
  int32_t red_average;
  int32_t dcFilterIRresult;
  int32_t dcFilterRedresult;
  int32_t chebyshevResult2;
  int32_t elipticResult2;
  int32_t wyjscie;
  int32_t bpm_up;
  int32_t fftbmp;
  int32_t currentSaO2Value;
  int32_t spo2Calib;
  float temp;
} SensorData;

// 填充数据并发送
SensorData sensorData = {
  ir_average, red_average, dcFilterIRresult, dcFilterRedresult,
  chebyshevResult2, elipticResult2, wyjscie, bpm_up,
  fftbmp, currentSaO2Value, spo2Calib, temp
};
HAL_UART_Transmit(&huart4, (uint8_t*)&sensorData, sizeof(SensorData), 1000);

2. ESP8266端读取解析

同样定义相同的结构体,直接读取对应字节数并解析:

// 与STM32端完全一致的结构体定义
typedef struct {
  int32_t ir_average;
  int32_t red_average;
  int32_t dcFilterIRresult;
  int32_t dcFilterRedresult;
  int32_t chebyshevResult2;
  int32_t elipticResult2;
  int32_t wyjscie;
  int32_t bpm_up;
  int32_t fftbmp;
  int32_t currentSaO2Value;
  int32_t spo2Calib;
  float temp;
} SensorData;

void setup() {
  Serial.begin(115200);
}

void loop() {
  // 检查是否接收到完整的数据包(结构体大小)
  if (Serial.available() >= sizeof(SensorData)) {
    SensorData receivedData;
    // 读取全部字节到结构体
    Serial.readBytes((uint8_t*)&receivedData, sizeof(SensorData));
    
    // 直接使用结构体中的数据
    Serial.print("FFT心率: "); Serial.println(receivedData.fftbmp);
    Serial.print("校准血氧: "); Serial.println(receivedData.spo2Calib);
    Serial.print("温度: "); Serial.println(receivedData.temp);
  }
}

额外优化:添加数据校验

为避免传输过程中的数据损坏,可在结构体末尾添加校验字段(如CRC或校验和):

  • STM32端:计算所有字段的和或CRC值,添加到结构体最后一起发送
  • ESP8266端:接收后重新计算校验值,与收到的校验值对比,一致再使用数据

内容的提问来源于stack exchange,提问作者Jakub Beling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:05:31