如何修复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 ---> Examp Dumping machine_data array. Examp Data available. Completed a read function. Number of bytes availaible: 8 ---> le Text. Dumping machine_data array. le Text. Data available. Completed a read function. Number of bytes availaible: 13 ---> Example Text. Dumping machine_data array. Example Text. Data available. Completed a read function. Number of bytes availaible: 10 ---> Example Te Dumping machine_data array. Example Text. Data available. Completed a read function. Number of bytes availaible: 3 ---> xt. Dumping machine_data array. xt.mple Text. Data available. Completed a read function. Number of bytes availaible: 4 ---> Exam Dumping machine_data array. Example Text. Data available. Completed a read function. Number of bytes availaible: 9 ---> ple Text. Dumping machine_data array. ple Text.ext. Data available. Completed a read function. Number of bytes availaible: 13 ---> Example Text. Dumping machine_data array. Example Text. Data available. Completed a read function. Number of bytes availaible: 8 ---> Example Dumping machine_data array. Example Text. Data available. Completed a read function. Number of bytes availaible: 5 ---> Text. Dumping machine_data array. Text.le Text. Data available. Completed a read function. Number of bytes availaible: 3 ---> Exa Dumping machine_data array. Exat.le Text.
内容的提问来源于stack exchange,提问作者BarelyDeveloper
相关产品推荐
相关产品推荐

