【问题标题】:Read arduino from serial in C从C中的串行读取arduino
【发布时间】:2016-12-22 18:43:15
【问题描述】:

我有以下程序尝试使用串行端口从 arduino 读取数据,问题是它几乎不读取任何内容,除了有时它会读取我发送的一部分内容。 arduino 代码只是在循环中写一个字母。

#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: ⏎                

【问题讨论】:

标签: c serial-port


【解决方案1】:

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

在这里我将解释如何设置波特率,但您可以使用我在答案下方进一步设置的 wikibooks 链接来设置其他设置,同时确保检查缓冲区。

简单地放在我喜欢使用 115200 作为波特率的 arduino 上。 There are a few more that are usually supported 在其他设备上,但这个值很好,所以我将在我的示例中使用它。

在 arduino 上,这很可能是您唯一需要配置的东西(事实上,当我想使用串行端口与我的计算机通信时,这是我唯一设置的东西)。

Serial.begin(115200);

然后根据this wikibook,您可以通过termios结构中的设置来设置您的波特率,就像在wikibook示例中一样,我将其命名为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,所以你需要在计算机上将两者设置为相同的值。

【讨论】:

  • 这根本没有解决它我得到的结果与我没有设置波特率一样。
  • 你检查过缓冲区的内容,看看它是否被 NULL 终止了?
  • 是的,我刚刚读取了 10 个字节,所以第 11 个字节为空终止。现在它'有点工作'。它大部分时间都在阅读,但有时我仍然会收到垃圾。你知道为什么会这样吗?在一个紧密的循环中,我正确地阅读了 A。如果我多次执行该程序,有时我会得到随机字符。
  • 如果在执行任何操作之前刷新缓冲区会怎样?如果在您快速循环时它可以正确读取,那么还有一个理由相信问题出在缓冲区
【解决方案2】:

如果您只需要在 PC 端接收二进制数据,可能会对某些特定值做出反应,然后将某些内容发送回 Arduino 并记录数据,例如,

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

它确实有更多的选项和脚本来基本上进行 ant 数据处理,但我还没有在它上面使用脚本。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多