简体   繁体   English

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

[英]Redundancy when reading USB serial port (C;Mac OSX;Arduino)

I'm writing a simple C program that can read data from a USB port that is connected to my Arduino device. 我正在写一个简单的C程序,它可以从连接到我的Arduino设备的USB端口读取数据。 The Arduino outputs data at a baud rate of 9600 in chunks of 4 bytes. Arduino以4字节的块为单位以波特率9600输出数据。

I want the input from the Arduino to my computer to look something like this: 我想从Arduino到我的电脑的输入看起来像这样:

136.134.132.130.129.127.126.124.121.119.117.115.113.111. 136.134.132.130.129.127.126.124.121.119.117.115.113.111。

However, I'm getting something like this: 但是,我得到这样的东西:

271.274.281..2.4062.4022.40225.4021 271.274.281..2.4062.4022.40225.4021

Question: How do I get the input in my C program to neatly synchronize with out loosing data/ rereading data? 问题:如何在C程序中获取输入以与丢失数据/重读数据整齐地同步? Are there some kind of flags that could tell my program when the port has new data? 当端口有新数据时,是否有某种标志可以告诉我的程序?

Code: 码:

#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;

}

Your program does not properly open() the serial port for reading it. 您的程序未正确打开()串行端口以进行读取。
In fact it repeatedly opens it two times every iteration of the for loop. 实际上,它在for循环的每次迭代中重复打开两次。
The device should be opened only once by your program. 该程序只能打开一次该设备。

Instead of 代替

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

   fcntl(open_port(), F_SETFL, FNDELAY);

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

}

the main program should be structured like 主程序的结构应该像

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);

Your program is too "simple". 你的程序太“简单”了。 It sets only a few attributes, and doesn't bother to check the return codes of system calls. 它只设置了几个属性,并且无需检查系统调用的返回码。

Is this supposed to be canonical or non-canonical (aka raw) mode (ie is the data ASCII text or binary)? 这应该是规范的还是非规范的(又称原始的)模式(即数据ASCII文本还是二进制)?
Refer to this Serial Programming Guide for proper setup of the serial port. 有关正确设置串行端口的信息,请参阅本串行编程指南

read data from a USB port 从USB端口读取数据

USB is a bus. USB是一种总线。
The device your program reads from is a serial port attached to that USBus. 程序读取的设备是连接到该USBus的串行端口。

Second coding issue 第二个编码问题

Your original code may print garbage data. 您的原始代码可能会打印垃圾数据。

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

The bytes returned by the read() operation are not likely to be terminated by a NULL byte, so a string operation on that read buffer could exceed the bounds of the allocated array. read()操作返回的字节不太可能被NULL字节终止,因此该读取缓冲区上的字符串操作可能超出分配的数组的边界。
Code that would not misbehave would be something like: 不会行为不端的代码会是这样的:

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);
}

Note that nbytes is one less than the allocated size of the buffer. 请注意, nbytes比缓冲区的分配大小小1。
This is to ensure that there is an available byte to store the string terminator byte when the read() operation returns a "full" buffer of nbytes . 这是为了确保当read()操作返回nbytes的“完整”缓冲区时,有一个可用字节来存储字符串终止符字节。
For efficiency the assignment of nbytes should be performed before entering the for loop, rather than within the loop. 为了提高效率,应在进入for循环之前执行nbytes的赋值,而不是在循环内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM