gpt4 book ai didi

c - 读取 USB 串行端口时的冗余(C;Mac OSX;Arduino)

转载 作者:太空宇宙 更新时间:2023-11-04 08:41:16 26 4
gpt4 key购买 nike

我正在编写一个简单的 C 程序,它可以从连接到我的 Arduino 设备的 USB 端口读取数据。 Arduino 以 9600 的波特率以 4 个字节的 block 输出数据。

我希望从 Arduino 到我的电脑的输入看起来像这样:

136.134.132.130.129.127.126.124.121.119.117.115.113.111.

但是,我得到的是这样的:

271.274.281..2.4062.4022.40225.4021

问题:如何让我的 C 程序中的输入整齐地同步而不丢失数据/重新读取数据?当端口有新数据时,是否有某种标志可以告诉我的程序?

代码:

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/types.h>


int open_port(void)
{
int fd; /* File descriptor for the port */

fd = open("/dev/tty.usbmodemfd121", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("open_port: Unable to open /dev/tty");
}
else
fcntl(fd, F_SETFL, 0);

struct termios options;
tcgetattr(fd,&options);
cfsetospeed(&options,B9600);
options.c_cflag |=(CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);

return (fd);
}


int main (){

int i;
for(i=0; i<50; i++){

fcntl(open_port(), F_SETFL, FNDELAY);
char buf[5];
size_t nbytes;
ssize_t bytes_read;

nbytes = sizeof(buf);
bytes_read = read(open_port(), buf, nbytes);
printf("%s ", buf);
buf[0]=0;
}

return 0;

}

最佳答案

您的程序没有正确地打开()读取它的串口。
事实上,它会在 for 循环的每次迭代中重复打开它两次。
您的程序应该只打开一次设备。

代替

for (i=0; i<50; i++) {

fcntl(open_port(), F_SETFL, FNDELAY);

bytes_read = read(open_port(), buf, nbytes);

}

主程序的结构应该是这样的

fd = open_port();
if (fd < 0) {
/* handle error condition */
}
rc = fcntl(fd, F_SETFL, FNDELAY);
if (rc < 0) {
/* handle error condition */
}
for (i=0; i<50; i++) {


bytes_read = read(fd, buf, nbytes);
if (bytes_read < 0) {
/* handle error condition */
}

}
close(fd);

你的程序太“简单”了。它只设置了一些属性,并且不去检查系统调用的返回码。

这应该是规范的还是非规范的(又名原始)模式(即数据是 ASCII 文本还是二进制)?
引用这个Serial Programming Guide正确设置串口。

read data from a USB port

USB 是总线。
您的程序从中读取的设备是连接到该 USBus 的串行端口。

第二个编码问题

您的原始代码可能会打印垃圾数据。

nbytes = sizeof(buf);
bytes_read = read(open_port(), buf, nbytes);
printf("%s ", buf);
buf[0]=0;

read() 操作返回的字节不太可能被 NULL 字节终止,因此对该读取缓冲区的字符串操作可能会超出分配数组的范围。
不会行为不端的代码类似于:

nbytes = sizeof(buf) - 1;

bytes_read = read(fd, buf, nbytes);
if (bytes_read < 0) {
/* handle error condition */
} else {
buf[bytes_read] = 0; /* append terminator */
printf("%s ", buf);
}

请注意,nbytes 比分配的缓冲区大小小一。
这是为了确保当 read() 操作返回 nbytes 的“完整”缓冲区时,有可用字节来存储字符串终止符字节。
为了提高效率,nbytes 的分配应该在进入 for 循环之前执行,而不是在循环内执行。

关于c - 读取 USB 串行端口时的冗余(C;Mac OSX;Arduino),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23449197/

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