我正在编写一个简单的C程序,该程序可以从连接到Arduino设备的USB端口读取数据。Arduino以4600字节的块以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;
}
您的程序未正确打开()串行端口以进行读取。
实际上,它在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);
您的程序太“简单”了。它仅设置了一些属性,并且无需检查系统调用的返回码。
这应该是规范模式还是非规范(aka原始)模式(即数据ASCII文本还是二进制)?有关串行端口的正确设置,
请参阅本《串行编程指南》。
从USB端口读取数据
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的“完整”缓冲区时,有一个可用字节来存储字符串终止符字节。
为了提高效率,应在进入for循环之前而不是在循环内执行nbytes的分配。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句