如何在C ++中读取串口设备

时间:2016-01-17 18:44:07

标签: c++ linux arduino

我试图弄清楚如何使用Linux C ++中的串行通信读取/写入我的Arduino。目前,我试图阅读我的Arudino的回复,我已经触发了#34;与

echo "g" > /dev/ttyACM0"

我尝试使用以下命令查看终端中Arduino的响应:

tail -f /dev/ttyACM0

这是应该的。现在我想在C ++应用程序中做同样的事情。所以我做了这个测试

void testSerialComm()
{

    std::string port = "/dev/ttyACM0";
    int device = open(port.c_str(), O_RDWR | O_NOCTTY | O_SYNC);

    std::string response;
    char buffer[64];

    do
    {
        int n = read(device, buffer, sizeof buffer);

        if (n > 0) {
            response += std::string(buffer);
            std::cout << buffer;
        }

    } while (buffer[0] != 'X'); // 'X' means end of transmission

    std::cout << "Response is: " << std::endl;
    std::cout << response << std::endl;

    close(device);

}

在一些&#34;消息&#34;之后,传输变得有些混乱。我的测试应用程序以随机​​顺序写入响应字符,而某些东西不对。我尝试通过此命令配置/ dev / ttyACM0设备:

stty -F /dev/ttyUSB0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

没有骰子。有人可以帮我理解如何用C ++与我的Arduino进行交流吗?

1 个答案:

答案 0 :(得分:8)

显示的代码打开/dev/ttyACM0,试图寻找文件&#34;的结尾,并根据生成的文件位置分配一个老式的C风格内存缓冲区,一些奇怪的原因,而不是使用std::vectorstd::string,尽管声称这可能是一个C ++程序,根据问题的标签。

这种方法的问题在于,您只能通过常规,普通,花园种类的文件进行搜索。 /dev/ttyACM0不是常规文件。它是一种设备。虽然有些设备是可以寻找的,但这个设备并非如此。根据评论,你已经独立发现了。

串行端口设备是可读写的。他们不可寻求。没有&#34;在串口上寻找&#34; s。这毫无意义。

要阅读您刚读过的串口,那就是全部。操作系统确实维护了一些大小的内部缓冲区,因此如果已经通过串行端口接收到某些字符,则初始读取将全部返回(假设read()缓冲区大小足够大)。例如,如果您传递1024个字符的缓冲区,并且已从串行端口read()读取了5个字符,则返回5,以相应地指示。

如果没有读取任何字符,并且您将串行端口作为阻塞设备打开,则read()将至少阻塞,直到从串行端口读取一个字符,然后返回。

因此,为了从串口读取,您只需从中读取所有内容,直到您确定已阅读所有内容即可阅读。你是如何决定的?这取决于你。在读取换行符之前,您可能决定只读取。或者您可以拒绝只读取已读取的固定#n个字符数。这完全取决于你。

当然,如果硬件配置合理,并且您使用串行端口设备进行必要的安排以遵守串行端口控制引脚,并且根据您的配置,DCD和/或DSR引脚会发出信号为了表明串口设备不再可用,您的read()将立即返回0,以指示串行端口设备上的伪文件状态。这也是您需要实现必要逻辑来处理的东西。

P.S。由于它们自己的内部缓冲算法,C风格的stdio和C ++风格的iostream都不能很好地与字符设备配合使用。使用串行端口时,使用open(2)read(2)write(2)close(2)会更好。但所有这些仍然适用。