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.
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).
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).
Related
I am searching all day for an example c++ program which will use ready .exe file which has as an output strings and then waits for standart input and again prints outputs and so on and so forth.
For example my c++ program will use standard output to write "uci" to a .exe program, the .exe program will reply with a string again which I will be able to read in my c++ program and again I will send a new string and will wait for a reply by the .exe.
I found something about pipes but I thought they were really difficult to understand.Is there any ready library/interface I could use? Or any example you can give me with pipes?
If you just know basics of c++ may be you should follow this as it does not require any external libs, though some say system is evil, its okay if it doesn't go to production level programs
int main()
{
std::string in;
while(std::cin >> in)
{
std::string cmd = std::string("/full/path/to/second.exe <") + in + " >outfile.txt";
system(cmd.c_str());
std::ifstream fin("outfile.txt");
std::cout << fin;
}
}
If you open to use bigger frameworks, there is an easy to use class in Qt to handle processes: http://doc.qt.io/qt-5/qprocess.html.
QProcess exe;
exe.start("foo.exe");
exe.write("uci");
exe.waitForReadyRead();
auto result = exe.readAll();
On windows you can use CreateProcess/CreatePipe, but the code will be a lot more verbose. Example:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx
I have seen cout.rdbuf() in for example here. This implies, the stream cout have a stream buffer associated with it, which is non empty before we flush it.
But, how can I ever peek into cout's stream buffer for cout before it's flushed?
Ie
cout << "I want to read this before this get flushed";
cout.UnknownFunction(); //this would save the buffer into a string variable
cout << flush;
But in current form of the code, everything will be flushed onto the screen after the first line..
So, what kind of construct allows me to peek inside the cout buffer?
PS. im running VC++ 2010 on windows7
I think that this doesn't flush after the first line, but I'm absolutely NOT sure.
I experienced that endl flushes, but the others don't, it's possible that too much character automatically flushes, but I don't know.
I created (accidentally) a program like this (in short):
cout << "x";
while (true) {}
The program ran this, and the output would be debug, but it haven't written anything for me, so I thought the program doesn't get there...
Following link is closely related to this topic
C++ buffered stream IO
(But I'm still not sure how/when to get cout.rdbuf() onto a string.)
Imagine you have the following in C++:
ofstream myfile;
myfile.open (argv[1]);
if (myfile.is_open()){
for(int n=0;n<=10;n++){
myfile << "index="<<n<<endl;
sleep(1);
}
}else{
cerr << "Unable to open file";
}
myfile.close();
And while writing, the disk or medium you are writing to becomes unavailable but comes back on for the close() so that you have missing data in between. Or imagine you write to a USB flash drive and the device is withdrawn and re-inserted during the writing process.
How can you detect that ? I tried checking putting the write in try {} catch, flags(), rdstate(), you name it, but none thus far seem to work.
I don't think that is something you can detect at the stdio level. Typically when a hard drive temporarily stops responding, the operating system will automatically retry the commands either until they succeed or a timeout is reached, at which point your system call may receive an error. (OTOH it may not, because your call may have returned already, after the data was written into the in-memory filesystem cache but before any commands were sent to the actual disk)
If you really want to detect flakey hard drive, you'll probably need to code to a much lower level, e.g. write your own hardware driver.
IMHO you can try to:
Use ios:exceptions
Use low-level OS interactions
Verify that IO was successful (if 1 and 2 doesn't work)
I'm not sure if this will cover your scenario (removing a USB drive mid-write), but you can try enabling exceptions on the stream:
myfile.exceptions(ios::failbit | ios::badbit);
In my experience, iostreams do a "great" job of making it hard to detect errors and the type of error.
for(int n=0;n<=10;n++){
if (!(myfile << "index="<<n<<endl))
throw std::runtime_error("WRITE FAILED")
sleep(1);
}
If the std::ostream fails for any reason, it sets it's state bit, which is checked then the std::stream is in a boolean context. This is the same way you check if an std::istream read in data to a variable correctly.
However, this is the same as rdstate(), which you say you tried. If that's the case, the write has gotten to a buffer. endl, which flushes the programs buffer, shows that it's in the Operating System's buffer. From there, you'll have to use OS-specific calls to force it to flush the buffer.
[Edit] According to http://msdn.microsoft.com/en-us/library/17618685(v=VS.100).aspx, you can force a flush with _commit if you have a file descriptor. I can't find such a guarantee for std::ostreams.
I'm wondering how to accept keyboard and mouse input in C++, using Visual Studio 2010, for Windows 7 32-bit.
--EDIT: I forgot to mention that I need keyboard / mouse input without interrupting the flow of the program. Something like a listener. I don't want to have to pause the program and ask for input, and then have the user type it out and press enter. What I'm looking for is more like:
If user presses W, S, A, D -> something happens.
Or: If user presses leftmousebutton in -> something happens.
I have to mention that I'm still very new to programming as a whole. I know basic OOP programming but that's about it. I'm definitely sure that this will involve things I don't know about yet, and I don't mind, I just ask that you explain it thoroughly, and possibly give an example so I know how to use it.
Thanks.
keyboard / mouse input without interrupting the flow
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HANDLE hIn;
HANDLE hOut;
COORD KeyWhere;
COORD MouseWhere;
COORD EndWhere;
bool Continue = TRUE;
int KeyEvents = 0;
int MouseEvents = 0;
INPUT_RECORD InRec;
DWORD NumRead;
hIn = GetStdHandle(STD_INPUT_HANDLE);
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
cout << "Key Events : " << endl;
cout << "Mouse Events : " << flush;
KeyWhere.X = 15;
KeyWhere.Y = 0;
MouseWhere.X = 15;
MouseWhere.Y = 1;
EndWhere.X = 0;
EndWhere.Y = 3;
while (Continue)
{
ReadConsoleInput(hIn,
&InRec,
1,
&NumRead);
switch (InRec.EventType)
{
case KEY_EVENT:
++KeyEvents;
SetConsoleCursorPosition(hOut,
KeyWhere);
cout << KeyEvents << flush;
if (InRec.Event.KeyEvent.uChar.AsciiChar == 'x')
{
SetConsoleCursorPosition(hOut,
EndWhere);
cout << "Exiting..." << endl;
Continue = FALSE;
}
break;
case MOUSE_EVENT:
++MouseEvents;
SetConsoleCursorPosition(hOut,
MouseWhere);
cout << MouseEvents << flush;
break;
}
}
return 0;
}
There are a number of related concepts behind this.
At the very low level, the keyboard and the mouse are hardware devices that generates some "interrupts" (in the form of electric signals) to the CPU.
The operating system provides some drivers that handle such interrupts by decoding the device communication specific protocol, and "standardizing" (at OS level) those signals in the form of events.
With "console applications", the operating system handles those events (the keyboard in particular) by filling up an input buffer (essentially a char[]) that is made accessible as a "virtually infinite sequence of characters" (complicated name for "file") named "CON", thus mimicking the "infinite teletype model" of the early days computers.
In a C++ program, the standard library -at program startup- associates to that "file" the std::cin and std::cout stream objects, so you can read the input character sequence using the std::istream functions and operators.
With "graphical applications", unfortunately, there is no "early days model" to mimic, and "events" are left available as the operating system native structure.
Different operating system differs in the way such events are represented and handled, but certain similitude can be seen.
For Windows (since your question is about), a typical program retrieves those events in sequence with a "message loop" in which calling certain OS APIs.
In that loop, the typical program will also give call another OS API to dispatch those event to appropriate "call-back" procedure, associated to a previously created "window".
That callback procedure has to detect the event code, cast the parameter as appropriate and manage them doing the action required.
A more precise detail can be seen with a WIN32 programming tutorial like http://www.winprog.org/tutorial/.
The most of the code is essentially C, since C is the language the API are formalized.
For C++, a number of libraries have then been written to represent OS objects is the form of C++ classes, and mapping the OS APIs to those classes members.
These libraries can be either OS specific (like MFC, WTL ...) or "multi-platform" (they exist in different version, mapping the API of various OSs into a same C++ interface) like WxWidget, Qt, Gtk, Fltk ...
Hope this can give you more hints to think about.
If you're writing a console application, you can use scanf or cin to get keyboard input. Console applications don't have any support for the mouse.
If you're writing a GUI application, you'll build the app out of standard windows controls that have built-in behaviors for mouse and keyboard input. You can use these re-usable controls as is, or you can augment them to make them behave exactly how you want for your application.
For example, in a GUI application, there's a standard edit control you can use that the user can type into. Your program receives messages when the user enters text into it, and based on those messages, or on other events, you can retrieve the text and do things with it as required by your program.
Windows or Console?
If console, use:
std::cin >> myVar;
I want to pass a value of an input variable in my program lets say#1 to another program #2 and i want #2 to print the data it got to screen, both are needed to be written in c++. The this will be on Linux.
Depending on the platform there are a number of options available. What you are trying to do is typically called inter-process communication (IPC).
Some options include:
Sockets
Pipes
Queues
Shared Memory
What is easiest is probably dependent on the platform youa are using.
As always, there is a Boost library for that (God, I like Boost).
Nic has covered all the 4 that I wanted to mention (on the same machine):
Sockets
Pipes
Queues
Shared Memory
If writing system calls is troublesome for you, you may want to use the following libraries:
Boost http://www.boost.org/
Poco http://pocoproject.org/blog/
Nokia Qt http://qt.nokia.com/
Something you can read from Qt portable IPC: only QSharedMemory?
If effeciency is not prime concern then use normal file i/o.
else go for IPC to do so.
As far as Windows is concern you have following options :
Clipboard ,
COM ,
Data Copy ,
DDE ,
File Mapping ,
Mailslots ,
Pipes ,
RPC ,
Windows Sockets
For Linux , use can use Name Pipes(efficient) or sockets.
If you're on Windows, you can use Microsoft Message Queueing. This is an example of queue mentioned previously.
If the data to be passed is just a variable, then one of the option is to set it as Environment Variable [ Var1 ] by program #1 and access it, in Program #2 [ if both are running on same env/machine ]. Guess this will be the easiest one, instead of making it complex, by using IPC/socket etc.
I think most of the answers have address the common IPC mechanisms. I'd just like to add that I would probably go for sockets because it's fairly most standard across several platforms. I decided to go for that when I needed to implement IPC that worked both on Symbian Series 60 and Windows Mobile.
The paradigm is straightforward and apart from a few platform glitches, the model worked the same for both platforms. I would also suggest using Protocol Buffers to format the data you send through. Google uses this a lot in its infrastructure. http://code.google.com/p/protobuf/
DBUS
QtDbus
DBus-mm
In response to your comment to Roopesh Majeti's answer, here's a very simple example using environment variables:
First program:
// p1.cpp - set the variable
#include <cstdlib>
using namespace std;;
int main() {
_putenv( "MYVAR=foobar" );
system( "p2.exe" );
}
Second program:
// p2.cpp - read the variable
#include <cstdlib>
#include <iostream>
using namespace std;;
int main() {
char * p = getenv( "MYVAR" );
if ( p == 0 ) {
cout << "Not set" << endl;
}
else {
cout << "Value: " << p << endl;
}
}
Note:
there is no standard way of setting an environment variable
you will need to construct the name=value string from the variable contents
For a very dirt and completely nonprofessional solution you can do it like me.
Save the variable in to a file and then read it (in an infinite loop every x time) with the other program.
fsexample.open("F:/etc etc ...");
fsexample >> data1 >> data2; // etc etc
and on the other side
fsexample.open("F:/etc etc ...");
fsexample << data1 << data2; // etc etc
The trick is that F is a virtual drive created with ramdisk so it is fast
and heavy-duty proof.
You could have problem of simultaneous access but you can check it with
if (!fsexample.is_open()) {
fsexample_error = 1;
}
and retry on failure.