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

ESP32 RS232桥接WiFi:如何解决串口随机数据异常问题?

RS232通信问题求助

感谢各位帮助,本人非专业人士,欢迎任何建议与批评。本次通信的目标硬件并非ESP32,而是一块带接口的外部板卡,程序预期通过Socket接收字符串并写入串口,同时打印返回结果。

使用器材

  • ESP32-E
  • 带MAX232芯片的商用RS232转TTL模块
  • 用于Putty和Python测试的USB-RS232适配器
  • 母对母Null Modem适配器

已执行测试

  • Putty连接测试
  • Python脚本连接测试
  • 逻辑分析仪观测通信流量

遇到的问题

  1. 使用USB适配器搭配Null Modem适配器,通过Putty或Python脚本连接时,一切符合预期。
  2. 使用ESP32脚本连接时,会收到发送内容的"回声",且串口会随机记录额外字符,经逻辑分析仪确认确实存在该现象,仅80%时间工作正常,可靠性不足。
  3. 若不逐字符写入并添加短延迟,外部硬件无法识别字符串。

观察结果

  • 未使用DSR或RTS信号,Python脚本中已设置为False且工作正常。
  • ESP32端使用Null Modem映射RX/Tx引脚,因未使用其他控制信号,认为无影响。
  • 最初将读写分离为不同任务并使用互斥锁,性能下降,合并任务后效率更高。

Putty配置

配置参数:波特率9600,数据位8,奇偶校验无,停止位1,流控选项全部关闭,本地回显禁用。

Python代码

import serial
import time
import threading
import sys

port = '/dev/ttyUSB0'
baudrate = 9600
byte_size = serial.EIGHTBITS
parity = serial.PARITY_NONE
stop_bits = serial.STOPBITS_ONE

ser = serial.Serial(port, baudrate, bytesize=byte_size, parity=parity, stopbits=stop_bits, timeout=2,dsrdtr=False,rtscts=False)

lock = threading.Lock() 
#write thread
def sendBytes():
    global lock
    
    
    
    with lock:
        ser.write(b'\x03')
        ser.flush()
    time.sleep(0.1)
    while True:
        user_input = input("\nInput the string to serial: \n")
        
        if user_input.lower() == 'exit':
            print("exit program.")
            sys.exit(0)
        
        with lock:
            if 'r'==user_input or user_input=='reset' :
                
                ser.write(b'\x03')
                ser.flush()
                
            else:
                ser.write((user_input + '\r').encode())
                ser.flush()
    
#read thread
def printData():
    global lock
            
    while True:
        
        data = ser.read_all()
        
        if data:
            cleaned_data = data.replace(b'\n', b'').replace(b'\r', b'')
            print(cleaned_data.decode('utf-8'))
        
        time.sleep(0.08)
        
        
taskRead = threading.Thread(target=printData)
taskWrite = threading.Thread(target=sendBytes)

taskRead.start()
taskWrite.start()

ESP32代码

// custom struct to manage messages to queue
typedef struct 
{
    char str[100];
    int length;
}fixed_string_t;
// initzialice the socketserver
esp_err_t initServer(void)
{
    ws.begin();
    ws.onEvent(webSocketEvent);
    return ESP_OK;
}

// task for websocket loop
void runWebSocketServer(void *pv)
{
    for (;;)
    {
        ws.loop();
        vTaskDelay(5 / portTICK_RATE_MS);
    }
}

esp_err_t pushToRs2Queue(fixed_string_t q)
{

    BaseType_t result = xQueueSend(rs232_queue, &q, portMAX_DELAY);
    return result == ESP_OK ? ESP_OK : -1;
}
// manage websocket incoming messages
void webSocketEvent(uint8_t client, WStype_t type, uint8_t *data, size_t len)
{
    if (type == WStype_TEXT)
    {
        std::string data_str(reinterpret_cast<const char *>(data), len);
        fixed_string_t item;
        strncpy(item.str, data_str.c_str(), sizeof(item.str) - 1);
        //ensure null termination
        item.str[sizeof(item.str) - 1] = '\0';
        item.length = data_str.length();
        pushToRs2Queue(item);
    }
}
// Start o reset the connection with HW
void resetConn(void)
{

    Serial2.write(0x03);
    vTaskDelay(200 / portTICK_PERIOD_MS);
    Serial2.flush();
}

// reader and writter task
void readRs232(void *pvp)
{
    QueueHandle_t rs232_queue = (QueueHandle_t)pvp;

    resetConn();
    Serial2.setTimeout(100);
    for (;;)
    {

        fixed_string_t arr;
        if (xQueueReceive(rs232_queue, &arr, pdMS_TO_TICKS(50)) == pdTRUE)
        {

            string toWrite = arr.str;
            if (!toWrite.empty() && toWrite[0] == 'c')
            {
                resetConn();
            }
            else
            {

                for (const char &c : toWrite)
                {
                    Serial2.write(c);
                    vTaskDelay(35 / portTICK_PERIOD_MS);
                }
                // line feeder
                Serial2.write(0x0D);
            }
        }

        int bufferLen = Serial2.available();
        if (bufferLen)
        {
            Serial.println(Serial2.readString());
        }
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
}

void setup()
{
    Serial.begin(115200);
    while (!Serial)
        ;
    ConnectWiFi_STA();
    if (initServer() == ESP_OK)
    {
        xTaskCreatePinnedToCore(&runWebSocketServer, "websocket_server", 5048, NULL, 5, NULL, 1);
    }
    Serial2.begin(9600, SERIAL_8N1, TXD2, RXD2);
    while (!Serial2);
    xTaskCreatePinnedToCore(&readRs232, "readRs2", 10048, rs232_queue, 10, &rs232ReadHandle, tskNO_AFFINITY);
}
void loop() {}

恳请各位帮忙解决该问题,谢谢!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:19:52