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

问题描述 投票:4回答:1

我试图弄清楚如何使用Linux C ++中的串行通信读取/写入我的Arduino。目前我正在尝试阅读我的“触发”我的Arudino的回复

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

}

在几条“消息”之后,传输变得有些混乱。我的测试应用程序以随机​​顺序写入响应字符,而某些东西不正确。我尝试通过此命令配置/ 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进行通信吗?

c++ linux arduino
1个回答
8
投票

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

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

串行端口设备是可读写的。他们不可寻求。在串口上没有“寻找”这样的东西。这是没有意义的。

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

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

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

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

附:由于它们自己的内部缓冲算法,C风格的stdio和C ++风格的iostreams都不能很好地与字符设备配合使用。使用串口时,使用open(2)read(2)write(2)close(2)更好。但所有上述内容仍然适用。

© www.soinside.com 2019 - 2024. All rights reserved.