C++ ifstream from linux to arduino

2019-02-19 13:23发布

问题:

original code

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

Here is the problem:

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

but if I do this instead it works:

        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"

So how do I make my fast computer able to read the slow output from the arduino? (Without using for-loops to waste time)

Here it says some things about callback http://www.cplusplus.com/reference/ios/ios_base/register_callback/ but I could never get it to work. It says it supports 3 events, and none of them are: "If input buffer is not empty, call this function".

Because the ultimate solution would be a callback function for whenever the input buffer is not empty.

An acceptable solution would be a c++ equivalent version of the arduino version "Serial.available()".

Another acceptable solution would be anything that forces me to not rely on two for-loops. 3 for-loops is not acceptable if that's what you're thinking.

EDIT1: Showed the original code
EDIT2: I am using linux(lubuntu)
EDIT3: Someone got confused where the code was written. Strange.

回答1:

Your problem is weird. In general, the problem is that the slower party can't read what the faster party sends. So, it seems you have a more fundamental problem here.

If arduino_output is a representation of a serial port (UART), I suggest to use a platform specific way of accessing it. On Windows, there are UART functions, and on Linux there's termios (probably on most other POSIX-like, too). This will give you a way to control the parameters of communication, and get information and/or notification about events (including parity/framing errors).



回答2:

If your arduino board is connected -e.g. by some cable- to a Linux laptop and your C++ program is on the Linux side (so not running on the Arduino microcontroller, which you did program in free-standing C), you'll better use directly syscalls(2) and low-level IO (not C++ ifstream which adds some buffering) such as open(2) & read(2) & write(2) & close(2).

Read Advanced Linux Programming. Consider using termios(3) to perhaps set your tty (demystified here) in raw mode. Use poll(2) to multiplex (and wait for) input (or ability to output), e.g. like Serial.available() does inside the Arduino.

Some event loop libraries (e.g. libevent or libev) provide callbacks, but you can make your own event loop around poll.

To make some delay, use perhaps usleep(3) (but very probably, you need to poll instead).

PS. If your Linux application is a graphical one using some GUI toolkit like Qt or GTK, you should use the event loop provided by that toolkit (that loop is calling poll or select, etc...). BTW, your question is not really Arduino related, but serial port related (any other device plugged on the same serial port would give the same issues).