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

树莓派与ESP8266 D1 Mini串口通信延迟及大数值传输异常求助

树莓派与ESP8266串口通信问题解决

一、串口更新延迟问题

问题原因

ESP8266代码中使用的Serial.parseInt()函数默认有1秒超时机制:开始读取数字后,会等待1秒直到遇到非数字字符或超时才停止解析,这就是频率更新延迟1秒的核心原因。

解决方案

1. 树莓派端:添加数值终止符

在发送的数值末尾加上换行符(\n),让ESP8266能立刻识别数值结束,无需等待超时:

import serial
import time

SerialPort = serial.Serial('/dev/ttyUSB0', 500000, timeout=1)
cmd = 5000
# 追加换行符作为数值终止标记
cmd = (str(cmd) + '\n').encode()
SerialPort.write(cmd)

# 无需额外sleep,直接读取反馈
DataReceived = SerialPort.readline().decode().strip()
print(DataReceived)

2. ESP8266端:缩短超时时间(可选)

若不想修改树莓派代码,可通过Serial.setTimeout()缩短parseInt()的超时窗口,比如设置为10ms:

void setup()
{
 Serial.begin(500000);
 Serial.setTimeout(10); // 将超时时间改为10毫秒
 // ... 其他初始化代码
}

二、大数值接收错误问题

问题原因

ESP8266的int是32位有符号整数,最大值为2147483647,你发送的9582665835远超该范围,导致整数溢出,最终得到错误的截断值。

解决方案

1. 调整变量类型适配大数值

根据数值范围选择对应变量类型:

  • 若数值不超过4294967295(32位无符号整数最大值),将receivedRawValue改为unsigned long类型;
  • 若数值更大,使用unsigned long long类型。

同时注意:ESP8266的analogWriteFreq()接受unsigned long参数,若你的数值超过该范围,建议先验证硬件是否支持如此高的PWM频率(通常PWM频率不会达到10^9级别)。

修改后的ESP8266核心代码:

#include <SPI.h>
#include <HighPowerStepperDriver.h>
HighPowerStepperDriver Driver;

const uint8_t CSPin = 15;
const uint8_t PWMPIN = 0;

// 替换为unsigned long类型支持更大数值范围
unsigned long receivedRawValue = 0;

void setup()
{
 Serial.begin(500000);
 Serial.setTimeout(10); // 配合终止符优化响应速度
 SPI.begin();
 Driver.setChipSelectPin(CSPin);
 pinMode(PWMPIN, OUTPUT);
 analogWrite(PWMPIN, 128);

 delay(1);

 Driver.resetSettings();
 Driver.clearStatus();
 Driver.setCurrentMilliamps36v4(250);
 Driver.setStepMode(HPSDStepMode::MicroStep8);
 Driver.enableDriver();
 Driver.setDirection(0);
}

void loop()
{
 if (Serial.available() > 0) {
   receivedRawValue = Serial.parseULong(); // 使用parseULong读取无符号长整数
   analogWriteFreq(receivedRawValue);
   Serial.println(receivedRawValue);
 }
}

2. 字符串读取转换(可选,支持超大数值)

若需支持超过4294967295的数值,可先读取完整字符串再转换,避免解析函数的限制:

void loop()
{
 if (Serial.available() > 0) {
   String receivedStr = Serial.readStringUntil('\n'); // 读取到换行符为止
   receivedStr.trim(); // 去除首尾空白字符
   unsigned long long receivedValue = strtoull(receivedStr.c_str(), NULL, 10);
   // 若analogWriteFreq不支持unsigned long long,可根据需求截断为unsigned long
   analogWriteFreq((unsigned long)receivedValue);
   Serial.println(receivedValue);
 }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:10:19