C++ ifstream 从 linux 到 arduino

C++ ifstream from linux to arduino

原码

#include<iostream>
#include<fstream>
using namespace std;

int main()
{
    ofstream arduino_output("/dev/ttyACM0");
    ifstream arduino_input("/dev/ttyACM0");

    int value;
    string txt;

    while(cin >> value){
        arduino_output << value << endl;
        arduino_input >> txt;//I never recieve the "OK" (Which I should get)
        cout << txt;
    }

    arduino_input.close();
    arduino_output.close();
    return(0);
} 

这是问题所在:

        cin >> value;
        arduino_output << value << endl;
        arduino_input >> txt;//I never recieve the "OK" (Which I should get)
        cout << txt;

但如果我这样做,它会起作用:

        cin >> value;
        arduino_output << value << endl;

        for(int i=0;i<10000;++i)
        for(int j=0;j<10000;++j){ //Waste a lot of time
           ++value;
           --value;
        }

        arduino_input >> txt; //I always recieve the "OK"
        cout << txt; //I can see the "OK"

那么如何让我的快速计算机能够读取 arduino 的慢输出? (不使用 for-loops 浪费时间)

这里它说了一些关于回调的事情 http://www.cplusplus.com/reference/ios/ios_base/register_callback/ 但我永远无法让它工作。它说它支持 3 个事件,其中 none 个是:"If input buffer is not empty, call this function"。

因为最终的解决方案是在输入缓冲区不为空时使用回调函数。

可接受的解决方案是 arduino 版本的 c++ 等效版本 "Serial.available()"。

另一个可接受的解决方案是迫使我不依赖两个 for 循环的任何方法。如果你这么想,3 个 for 循环是不可接受的。

EDIT1:显示原始代码
EDIT2:我正在使用 linux(lubuntu)
EDIT3:有人对代码的编写位置感到困惑。奇怪。

你的问题很奇怪。一般来说,问题在于速度较慢的一方无法读取速度较快的一方发送的内容。所以,看来你这里有一个更根本的问题。

如果 arduino_output 表示串行端口 (UART),我建议使用特定于平台的方式访问它。在 Windows 上有 UART 功能,在 Linux 上有 termios(可能在大多数其他 POSIX-like 上也有)。这将为您提供一种控制通信参数的方法,并获取有关事件的信息 and/or 通知(包括 parity/framing 错误)。

如果您的 arduino 开发板已连接 - 例如通过一些电缆连接到 Linux 笔记本电脑和你的 C++ 程序在 Linux 一侧(所以在 Arduino 微控制器上 不是 运行,你在 free-standing C), 你最好直接使用syscalls(2) and low-level IO (not C++ ifstream which adds some buffering) such as open(2) & read(2) & write(2) & close(2).

读取Advanced Linux Programming. Consider using termios(3) to perhaps set your tty (demystified here) in raw mode. Use poll(2)以复用(并等待)输入(或输出能力),例如就像 Serial.available() 在 Arduino 中所做的那样。

一些事件循环库(例如 libevent or libev)提供回调,但您可以围绕 poll.

创建自己的事件循环

要延迟一些时间,可以使用 usleep(3)(但很有可能,您需要 poll)。

PS。如果您的 Linux 应用程序是一个图形应用程序,使用该工具包提供的一些 GUI 工具包,例如 Qt or GTK, you should use the event loop(该循环正在调用 pollselect,等等)。顺便说一句,你的问题实际上与 Arduino 无关,而是与串行端口相关(插入同一串行端口的任何其他设备都会出现相同的问题)。