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

如何修复Arduino Mega串口输出乱码问题(termios库应用)

串口读取乱码与数据分段问题(使用termios库读取Arduino串口)

我首次使用termios库编写代码读取Arduino Mega的串口数据,正在学习该库及串口通信原理,最终目标是收发类JSON格式的数据包。当前测试示例消息时,未得到预期的重复“Example Text.”输出,反而出现乱码:

Et.Example Text.Example Text.
Example Text.xt.Example Text.

且每秒接收多次数据(Arduino本应每秒发送一次),推测是缓冲区问题。

电脑端C++代码(serial.cpp)

// serial.cpp

#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <iostream>
#include <string>
#include <cstring>

int serial_port;
char machine_data[1024];
int max_fd;

int serial_setup(char conn[]) {

    serial_port = open(conn, O_RDWR); // 物理串口可替换为"/dev/ttyS0"

    // 串口默认配置的标准代码
    if (serial_port == -1) {
        std::cerr << "Error opening serial port." << std::endl;
        return 1;
    }

    std::cout << "Serial port is open." << std::endl;

    struct termios tty;
    memset(&tty, 0, sizeof(tty));

    if (tcgetattr(serial_port, &tty) != 0) {
        std::cerr << "Error getting serial port attributes." << std::endl;
        return 1;
    }

    cfsetospeed(&tty, B38400); // 设置波特率
    cfsetispeed(&tty, B38400);

    tty.c_cflag &= ~PARENB; // 禁用校验位
    tty.c_cflag &= ~CSTOPB; // 1个停止位
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8; // 8位数据位

    tty.c_cflag &= ~CRTSCTS; // 禁用硬件流控
    tty.c_cflag |= CREAD | CLOCAL; // 启用接收器,忽略调制解调器控制线

    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控

    tty.c_lflag = 0; // 非规范模式

    tty.c_oflag = 0; // 无输出处理

    tty.c_cc[VMIN] = 0; // 读取不阻塞
    tty.c_cc[VTIME] = 5; // 0.5秒读取超时

    if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
        std::cerr << "Error setting serial port attributes." << std::endl;
        return 1;
    }

    std::cout << "Finished the setup for the serial port." << std::endl;


    return 0;

}

std::string read_serial() {

    std::string return_string;
    // select函数的初始化配置
    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(serial_port, &rfds);
    max_fd = serial_port + 1;
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 10000;

    int ready = select(max_fd, &rfds, nullptr, nullptr, &timeout);
    if (ready > 0) {
        std::cout << "Data available." << std::endl;    
        int num_data = read(serial_port, machine_data, sizeof(machine_data));
        return_string = machine_data;
        std::cout << "Completed a read function." << std::endl;
    }

    else { 
        std::cout << "Did not complete." << std::endl;

    }

    return return_string;

}

int main() {
    char serial_port[] = "/dev/ttyACM0";

    int status = serial_setup(serial_port);

    while (true) {
        std::string text = read_serial(); 

        std::cout << text << std::endl;
    }
    return 0;

}

Arduino代码(exp_serial.ino)

// exp_serial.ino

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

void loop() {
    Serial.write("Example Text.");
    delay(1000);
}

编辑1:调整后的问题表现

调整后乱码消失,但出现数据分段:

e Text.
Exam
ple Text.

我添加了打印读取字节数和machine_data数组内容的调试代码,发现串口读取及数组覆盖存在问题,调试输出如下:

Serial port is open.
Finished the setup for the serial port.
Data available.
Completed a read function.
Number of bytes availaible: 5
---&gt; Examp
Dumping machine_data array.
Examp
Data available.
Completed a read function.
Number of bytes availaible: 8
---&gt; le Text.
Dumping machine_data array.
le Text.
Data available.
Completed a read function.
Number of bytes availaible: 13
---&gt; Example Text.
Dumping machine_data array.
Example Text.
Data available.
Completed a read function.
Number of bytes availaible: 10
---&gt; Example Te
Dumping machine_data array.
Example Text.
Data available.
Completed a read function.
Number of bytes availaible: 3
---&gt; xt.
Dumping machine_data array.
xt.mple Text.
Data available.
Completed a read function.
Number of bytes availaible: 4
---&gt; Exam
Dumping machine_data array.
Example Text.
Data available.
Completed a read function.
Number of bytes availaible: 9
---&gt; ple Text.
Dumping machine_data array.
ple Text.ext.
Data available.
Completed a read function.
Number of bytes availaible: 13
---&gt; Example Text.
Dumping machine_data array.
Example Text.
Data available.
Completed a read function.
Number of bytes availaible: 8
---&gt; Example 
Dumping machine_data array.
Example Text.
Data available.
Completed a read function.
Number of bytes availaible: 5
---&gt; Text.
Dumping machine_data array.
Text.le Text.
Data available.
Completed a read function.
Number of bytes availaible: 3
---&gt; Exa
Dumping machine_data array.
Exat.le Text.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:40:55