gpt4 book ai didi

c++ - 使用terminos进行规范的串行读取失败?

转载 作者:行者123 更新时间:2023-12-03 07:21:57 25 4
gpt4 key购买 nike

我正在尝试使用串行读取来自arduino的数据行。
我的arduino代码如下所示:Serial3.print(Z, 2);Serial3.print(F(";"));Serial3.println(F("END\n")); 这是我的代码,用于读取ubuntu上的数据:

void setup(){  
//set up serial
tcgetattr(dueSerial, &port_options); // Get the current attributes of the Serial port
dueSerial = open("/dev/ttyUSB0", O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY);
if (dueSerial == -1) {
reportFailure("Could not open Arduino");
} else {
port_options.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB),So No Parity
port_options.c_cflag &= ~CSTOPB; // CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit
port_options.c_cflag &= ~CSIZE; // Clears the mask for setting the data size
port_options.c_cflag |= CS8; // Set the data bits = 8
port_options.c_cflag &= ~CRTSCTS; // No Hardware flow Control
port_options.c_cflag |= (CREAD | CLOCAL); // Enable receiver,Ignore Modem Control lines
port_options.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable XON/XOFF flow control both input & output
port_options.c_lflag &= ~(ECHO | ECHONL | IEXTEN | ISIG); // no echo
port_options.c_iflag |= ICANON; //Enable canonical
port_options.c_iflag |= ICRNL; //map CR to NL
//port_options.c_oflag &= ~OPOST; // No Output Processing
//port_options.c_lflag = 0; // enable raw input instead of canonical,
/*
initialize all control characters
default values can be found in /usr/include/termios.h, and are given
in the comments, but we don't need them here
*/
port_options.c_cc[VINTR] = 0; /* Ctrl-c */
port_options.c_cc[VQUIT] = 0; /* Ctrl-\ */
port_options.c_cc[VERASE] = 0; /* del */
port_options.c_cc[VKILL] = 0; /* @ */
port_options.c_cc[VEOF] = 4; /* Ctrl-d */
port_options.c_cc[VTIME] = 0; /* inter-character timer unused */
port_options.c_cc[VMIN] = 0; /* blocking read until 1 character arrives */
port_options.c_cc[VSWTC] = 0; /* '\0' */
port_options.c_cc[VSTART] = 0; /* Ctrl-q */
port_options.c_cc[VSTOP] = 0; /* Ctrl-s */
port_options.c_cc[VSUSP] = 0; /* Ctrl-z */
port_options.c_cc[VEOL] = 0; /* '\0' */
port_options.c_cc[VREPRINT] = 0; /* Ctrl-r */
port_options.c_cc[VDISCARD] = 0; /* Ctrl-u */
port_options.c_cc[VWERASE] = 0; /* Ctrl-w */
port_options.c_cc[VLNEXT] = 0; /* Ctrl-v */
port_options.c_cc[VEOL2] = 0; /* '\0' */

cfsetispeed( & port_options, BAUDRATE); // Set Read Speed
cfsetospeed( & port_options, BAUDRATE); // Set Write Speed
tcflush(dueSerial, TCIFLUSH);
tcflush(dueSerial, TCIOFLUSH);
int att = tcsetattr(dueSerial, TCSANOW, & port_options);
if (att != 0) {
reportFailure("ERROR in Setting Arduino port attributes");
} else {
LOG_INFO("SERIAL DUE Port Good to Go");
}

}
}

void UART::tick() {
//Arduino msg = "IMU;LAX;LAY;LAZ;AVX;AVY;AVZ;AY;AP;AR;END"
// rx_buffer[0] = '0';
memset(&rx_buffer, '\0', sizeof(rx_buffer));
// tcflush(dueSerial, TCIOFLUSH);

rx_length = read(dueSerial, &rx_buffer,255);
if (rx_length < 0) {
LOG_INFO("Error reading");
}else{
LOG_INFO("Read %i bytes. Received message: %s", rx_length, rx_buffer);
}
}

但是当我尝试这段代码时,我一次得到很多行,所以我的输出看起来像这样:
2020-11-15 09:13:09.491 INFO  packages/skeleton_pose_estimation/apps/usb/UART.cpp@87: Read 0 bytes. Received message: 
2020-11-15 09:13:09.496 INFO packages/skeleton_pose_estimation/apps/usb/UART.cpp@87: Read 255 bytes. Received message: 0.01;0.00;0.00;0.00;0.00;0.00;0.00;END

IMU;-0.00;0.02;0.03;0.00;0.00;0.00;0.00;0.00;0.00;END

IMU;-0.00;0.02;0.03;0.00;-0.00;0.00;0.00;0.00;0.00;END

IMU;-0.00;0.02;-0.02;0.00;-0.00;0.00;0.00;0.00;0.00;END

IMU;-0.00;0.02;-0.02;-0.00;0.00;0.00;0.00;0.00;
2020-11-15 09:13:09.501 INFO packages/skeleton_pose_estimation/apps/usb/UART.cpp@87: Read 241 bytes. Received message: 0.00;END

IMU;-0.01;-0.02;-0.01;-0.00;0.00;0.00;0.00;0.00;0.00;END

IMU;-0.01;-0.02;-0.01;-0.00;-0.00;0.00;0.00;0.00;0.00;END

IMU;-0.01;-0.02;0.03;-0.00;-0.00;0.00;0.00;0.00;0.00;END

IMU;-0.01;-0.02;0.03;0.00;0.00;0.00;0.00;0.00;0.00;END


2020-11-15 09:13:09.506 INFO packages/skeleton_pose_estimation/apps/usb/UART.cpp@87: Read 0 bytes. Received message:
2020-11-15 09:13:09.511 INFO packages/skeleton_pose_estimation/apps/usb/UART.cpp@87: Read 0 bytes. Received message:

但是我希望每个read()函数调用只读取一行。
我相信我设置了错误的参数以使圆锥模式不使用,或者它忽略了我的\ n和\ r,但是不知道为什么...。
请帮助我找到原因。
谢谢你一吨!

最佳答案

But I want it to read only one line per read() function call. I believe that I either set a wrong parameter making the conanical mode unused ...


您的程序无法正常运行,因为从未实际设置规范模式。
该声明
 port_options.c_iflag |= ICANON; //Enable canonical
是不正确的。 ICANONc_lflag成员中,而不在 c_iflag中。

您的代码还有其他问题。
(1)变量 dueSerial未初始化使用:
void setup(){  
//set up serial
tcgetattr(dueSerial, &port_options); // Get the current attributes of the Serial port
dueSerial = open(...);
...
必须先获取并验证文件描述符,然后才能在 tcgetattr()调用中使用该文件描述符。
语句的正确顺序是:
void setup(){  
//set up serial
dueSerial = open(...);
if (dueSerial == -1) {
/* abort */
}
tcgetattr(dueSerial, &port_options);
...
(2)在termios初始化中未指定许多输入转换。
规范模式启用了各种选项来转换某些输入字符,并且其中的大多数选项都需要禁用才能由程序读取(相对于交互式终端)。
通常,禁用 INPCK(启用输入奇偶校验), IUCLC(将大写字母映射为小写字母)和 IMAXBEL(输入队列已满时响铃)。
您需要检查是否还希望禁用 IGNCR(保留或忽略回车), INLCR(将换行转换为回车)和 ICRNL(除非将 IGNCR设置为回车,否则将回车转换为换行)。
(3)使用非阻塞模式值得怀疑。
由于您希望“每个read()函数调用仅读取一行”,因此阻塞模式是获得该结果的正确方法。
如果您坚持使用非阻塞模式,那么 read()系统调用将始终“立即”返回,并且可能根本不返回任何数据。

关于c++ - 使用terminos进行规范的串行读取失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64842470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com