2016-12-22 197 views
0

我有下面的程序试图用串口读取arduino中的数据,事情大部分是不读取任何东西,除了有时它读取我发送的一块。 arduino代码只是在循环中写一个字母。从串口读取arduino C

#include <cstdio> 
#include <cstring> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <termios.h> 

int main() { 
    int serialfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 
    if (serialfd == -1) 
     perror("Error opening the serial port"); 
    else 
     fcntl(serialfd, F_SETFL, 0); 

    fprintf(stdout, "Device is open, attempting read \n"); 

    fcntl(serialfd, F_SETFL, 0); 
    char buf[11] = {0}; 
    read(serialfd, buf, 10); 
    fprintf(stdout, "Buffer: %s", buf); 
    close(serialfd); 
    return 0; 
} 

例如输出是这样

Device is open, attempting read 
Buffer: AAAAAAAAAAA⏎ 

如果我尝试再次运行它(多次),我刚刚得到的0'd缓冲

Device is open, attempting read 
Buffer: ⏎     
+0

你没有说*你重复发送哪个*单个字符。假设你有相应的波特率(没有提及),并且你发送了'A',那么在收到其中的11个之后,输入缓冲区已满并且没有''\ 0''的零终止,所以你将一个not_string传递给'fprintf',因此不可避免地会输出一些废话。但请[阅读此](http://stackoverflow.com/questions/34943745/why-fcntlfd-f-setfl-0-use-in-serial-port-programming)关于'F_SETFL'。 –

+0

@WeatherVane我在写arduino的'A',我不知道如何用文件描述符设置波特率。 – Aram

+1

打开串行终端设备后,您必须先配置终端属性,然后才能读取或写入。研究[设置终端模式来适当地(http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html#SEC237) 和[串行编程指南POSIX操作系统(HTTP: //www.cmrr.umn.edu/~strupp/serial.html)有关示例代码,请参阅http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port -in-C/38318768#38318768和http://stackoverflow.com/questions/12437593/how-to-read-a-binary-data-over-serial-terminal-in-c-program/12457195#12457195 – sawdust

回答

2

这听起来像配置问题,很可能波特率没有正确设置。另外,如问题评论中所述,您可能会得到一个完整的缓冲区,最后没有'\0'字符,因此fprintf的行为不正确。

这里我将解释如何设置波特率,但您可以使用wikibooks链接我已经放下了答案来设置其他设置,也请确保检查缓冲区。

简单地说就是arduino,我喜欢用115200作为我的波特率。 There are a few more that are usually supported在其他设备上,但这个值没有问题,所以我会用我的例子。

在arduino上,这很可能是你必须配置的唯一东西(如果事实上,这是我设置的唯一一个当我想使用串口与我的电脑交谈)。

Serial.begin(115200); 

然后根据this wikibook可以在termios结构通过设置中设置了波特率,如维基例子中,我把它叫做attribs

struct termios attribs; 

/* get the current settings */ 
tcgetattr(serialfd, &attribs); 

/* set the baudrate */ 
cfsetospeed(&attribs, B115200); /* outut baudrate */ 
cfsetispeed(&attribs, B115200); /* input baudrate */ 

/* if there is need for it, set other settings here */ 

/* eventually apply everything for your serialfd descriptor */ 
tcsetattr(serialfd, TCSANOW, &attribs); 

所以,是技术上你可以有不同的速度输入比输出,但Arduino的的UART只有一个这样的设置和does not support different speeds for input/ouput,所以你需要在电脑上设置了两个相同的值。

+0

这并没有解决它在所有我得到了相同的结果,如果我不是设置波特率。 – Aram

+0

您是否检查过缓冲区的内容,看它是否被终止? – saeleko

+0

是的,我只是读了10个字节,所以第11个空终止。现在它'有点作品'。它的大部分时间都在阅读,但有时候我仍然得到垃圾。你知道这是为什么吗?在一个紧密的循环中,我正确地阅读了A.如果我有时执行该程序几次,我会得到随机字符。 – Aram

0

如果你只需要接受对PC端的二进制数据,也许反应一定的值,并送东西回的Arduino和日志数据,例如,

那么你可以使用一些更高级的RS232终端程序,如 http://docklight.de/

它有更多的选项和脚本来基本上做蚂蚁数据处理,但我没有使用脚本。

但是在几分钟内,您就可以使用ASCII或二进制格式读取和应答数据。

当然,对于某些数据库连接或更多,您将需要自定义程序,但要在调试阶段测试操作docklight是一个伟大的工具。