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

时间:2014-05-03 20:02:33

标签: c serial-port arduino

我正在编写一个简单的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;

}

1 个答案:

答案 0 :(得分:2)

您的程序没有正确打开()用于读取它的串口 事实上,它在 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);

您的计划过于简单&#34;。它只设置了几个属性,并且不用太多来检查系统调用的返回码。

这应该是规范的还是非规范的(也就是原始的)模式(即数据ASCII文本或二进制)? 有关正确设置串行端口的信息,请参阅此Serial Programming Guide

  

从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()操作返回&#34; full&#34;时,存在可用字节来存储字符串终止符字节。缓冲区 nbytes
为了提高效率,应在进入 for 循环之前执行 nbytes 的分配,而不是在循环内。