通过串行连接进行双向C++通信

lea*_*vst 12 c++ linux serial-port arduino

我正在尝试编写一个非常简单的C++应用程序来与Arduino进行通信.我想向Arduino发送一个它立即发回的角色.我从教程中获取的Arduino代码如下所示:

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    //Have the Arduino wait to receive input
    while (Serial.available()==0);

    //Read the input
    char val = Serial.read();

    //Echo
    Serial.println(val);
}
Run Code Online (Sandbox Code Playgroud)

我可以使用GNU屏幕轻松地与Arduino进行通信,因此我知道基本通信一切正常:

$ screen /dev/tty.usbmodem641 9600

我看到的(破碎的)C++代码如下所示:

#include <fstream>
#include <iostream>
int main()
{
    std::cout << "Opening fstream" << std::endl;
    std::fstream file("/dev/tty.usbmodem641");
    std::cout << "Sending integer" << std::endl;
    file << 5 << std::endl; // endl does flush, which may be important
    std::cout << "Data Sent" << std::endl;
    std::cout << "Awaiting response" << std::endl;
    std::string response;
    file >> response;
    std::cout << "Response: " << response << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它编译得很好,但在运行时,Arduino上有一些指示灯闪烁,终端只挂在:

打开fstream

我哪里错了?

A.H*_*.H. 10

有三点:

第一:您没有初始化Linux端的串行端口(TTY).没有人知道它处于什么状态.

在您的程序中执行此操作,您必须使用tcgetattr(3)tcsetattr(3).您可以在此站点,Arduino站点或Google上使用这些关键字找到所需的参数.但是为了快速测试,我建议在调用自己的命令之前发出此命令:

stty -F /dev/tty.usbmodem641 sane raw pass8 -echo -hupcl clocal 9600
Run Code Online (Sandbox Code Playgroud)

特别是失踪clocal可能会阻止你打开TTY.

第二:当设备打开时,你应该等一会儿才发送任何东西.默认情况下,Arduino会在串行线路打开或关闭时重置.你必须考虑到这一点.

-hupcl部件将在大多数时间阻止此重置.但是至少需要一次复位,因为-hupcl只有当TTY已经打开并且Arduino已经收到复位信号时才能设置.所以-hupcl"只会"阻止未来的重置.

第三:错误代码处理.请在TTY上的每次IO操作之后添加代码以检查错误,并且 - 最重要的部分 - 使用perror(3)或类似功能打印有用的错误消息.


BЈо*_*вић 1

您应该检查您是否有权访问/dev/tty.usbmodem641. Linux 中通常的方法是将用户添加到正确的组中adduser

顺便说一句,我知道要访问串行端口,需要打开/dev/ttyS0(对于 COM1),直到/dev/ttyS3. 例如,请参阅C 中的此示例