我正在编写一个简单的C程序,可以从连接到我的Arduino设备的USB端口读取数据。Arduino以9600的波特率输出4字节的数据块。
我希望从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文本还是二进制)
有关串行端口的正确设置,请参阅本串行编程指南。
从USB端口读取数据
USB是一种总线
程序读取的设备是连接到该USBus的串行端口。
第二个编码问题
原始代码可能会打印垃圾数据。
nbytes = sizeof(buf);
bytes_read = read(open_port(), buf, nbytes);
printf("%s ", buf);
buf[0]=0;
read()操作返回的字节不太可能被空字节终止,因此该读取缓冲区上的字符串操作可能会超出所分配数组的界限
不会出现不当行为的代码如下:
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循环之前执行,而不是在循环中执行。
我读了很多问题和答案,但没有找到任何解决方案。也许我的问题不对,但我需要一些指导。我在Linux中使用串行端口,从我的Arduino设备读取数据。每当我想从Arduino向Linux发送数据时,我首先发送两个字节,这表示将从Arduino发送的总字节数。我将这两个字节转换为整数值,并开始从串行端口读取数据。比如说,我想把300字节从Ardiuno发送到Linux,我只需要先写{1,44},然后用下
问题内容: 我研究了许多有用的线程和一些教程,但是仍然存在一些问题,这些问题应该非常简单。作为参考,这里是我细读的一些线程: 无论如何,我有一个问题。如果我收到数据,我的代码可以正常工作。如果不这样做,则read()函数将停顿,退出程序的唯一方法是使用kill -9(注意:我使用信号处理来发信号通知线程读取串行数据以终止。这不是罪魁祸首,即使我删除了信号处理,read()调用仍然停止。我正在尝试做
我做了一个python程序,从串行端口读取gps数据。GPS冰球流NMEA数据语句连续插入USB时。我的程序打开端口,然后尝试读取数据,解析它,然后将其与从Arduino提取的其他数据一起写入文本文件。 我遇到的问题是,当我第一次运行程序时,有时它无法读取数据。我放入了一些Try/Exception捕获,发现以某种方式无法从GPS串行端口读取数据 如果我点击Cntrl-C几次,这似乎可以解决它遇到
我正在开发一个WPF应用程序,它将读取串行端口上的数据,对其进行解析,并将其显示在UI上。 我必须使用串行端口Buad速率-115200,数据位-8,停止位-1。 我在串行端口上每秒发送10000字节,将由我的WPF应用程序读取。 但是,在这里我面临的问题与用户界面。当我开始阅读COM端口我的UI冻结。它不允许任何人做任何事情。根据我的调查,这是由于数据的高速度。 我在不同的线程上读取com端口,
问题内容: 我有一个Java程序,必须读取Arduino发送的信息。我从这里获取了Java代码。现在,我不太了解它是如何工作的,但是我尝试对其进行修改,并且得到了以下信息: 我创建一个对象串行COM口,我需要在主程序,然后我使用和当我需要它。 效果很好,Arduino获取数据并将其显示在LCD显示屏中。问题是。程序运行时,它会不断从串行端口读取数据(大约每40毫秒一次),但这并不意味着Arduin
问题内容: 我以下列方式从打开的串行端口读取某些数据时遇到麻烦。我已经多次使用此代码实例,并且一切正常,但是现在,由于某种原因,我无法弄清楚,我完全无法从串行端口读取任何内容。 我能够写,并且在另一端正确接收了所有消息,但是从未收到答复(正确发送)(不,电缆都还好;)) 我用来打开串行端口的代码如下: 端口初始化后,我通过简单的write命令向其中写入一些内容。 hCom是文件描述符(没关系),并