我正在写一个简单的C程序,它可以从连接到我的Arduino设备的USB端口读取数据 . Arduino以4字节的块为单位以波特率9600输出数据 .
我想从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;
}
1 回答
您的程序没有正确读取它的串行端口 open() .
事实上,它在 for 循环的每次迭代中重复打开两次 .
该程序只能打开一次该设备 .
代替
主程序的结构应该是这样的
你的程序太“简单”了 . 它只设置了几个属性,并且无需检查系统调用的返回码 .
这应该是规范的还是非规范的(又称原始的)模式(即数据ASCII文本还是二进制)?
请参阅此Serial Programming Guide以正确设置串行端口 .
USB是一种总线 .
程序读取的设备是连接到该USBus的串行端口 .
Second coding issue
您的原始代码可能会打印垃圾数据 .
read() 操作返回的字节不太可能被NULL字节终止,因此该读取缓冲区上的字符串操作可能超出分配的数组的边界 .
不会行为不端的代码会是这样的:
请注意 nbytes 比缓冲区的分配大小小一个 .
这是为了确保当 read() 操作返回 nbytes 的"full"缓冲区时,存在可用字节来存储字符串终止符字节 .
为了提高效率,应在进入 for 循环之前执行 nbytes 的赋值,而不是在循环内执行 .