Linux C++ write string to COM port, read back response? - c++

I am trying to write to the /dev/ttyACM0 port. In the command line shell I can write the string ":35\n" to the sensor I have plugged in to that port, and via putty listening on the port I can see it responds and gives me the data I am asking for (compass data).
I want to write a driver in C++ that writes this string to that port and reads in the response returned. I have looked online but have been unsuccessful in writing this. I feel like it should be an easy task. I wouldn't think writing to the ttyACM port would be any different than writing to a ttyCOM or ttyS port. Can anyone give me an example of this? I wouldn't think it'd be more than 5 lines of code.
Thank you for any help.

As requested, five lines of code:
#include <fstream>
std::fstream file("/dev/ttyACM0");
file << ":35" << std::endl; // endl does flush, which may be important
std::string response;
file >> response;

Related

multi sockets in boost asio?

I wanted to make a chat server using boost::asio and as the program gets more complicated and difficult for myself to read, I was wondering if it is possible to use several sockets in the same client and on server side?
If I can't make myself quite clear to you, for example, in my server side I have int and string variables and I want to send them in different sockets NOT effecting to each other.
Well... int variable is sent through socket1 and string is through socket2. The same thing with a client side that it should "know" from which socket int is "coming" and from which string. If this is possible I would be very glad to see some examples :)
Thank you in advance!
the program gets more complicated and difficult for myself to read
You might want to refactor a bit. Even large code should be easy to read and understand.
I have int and string variables and I want to send them in different sockets NOT effecting to each other.
You don't create a new socket for each data-type you want to send. Add a proper header to your message and parse the received data-type with error checking.
For instance (simplified case):
std::string tx = "12345678Test";
std::stringstream ss(tx);
int num;
ss >> num;
std::string s;
ss >> s;

Fixing Communications between Arduino and C++ Mac OS X

I am having trouble communicating from C++ to Arduino using Serial. I have used the method discussed by Salil Kapur here: https://salilkapur.wordpress.com/2013/03/08/communicating-with-arduino-using-c/. I have adapted his strategy of writing directly to the Arduino's file using c++.For my specific task , I need to send a string of char’s (which are commands for the arduino to process) to the Arduino. I have already read the chars from a file in the C++ program, but for some reason, I am getting nothing from my Arduino Serial monitor when I send it over. I think that the baud rate might be the problem, but I am not positive. I will give you my code for specific help. If someone can advise me how to get the C++ to write the chars to the Serial monitor to be read:
C++:
#include
#include //For sleep()
#include //For FILE
#include //For ifstream
#include //For assert()
#include //For string
using namespace std;
int main()
{
//Setting up the output to the Arduino
FILE *arduino;
arduino = fopen(“/dev/tty.usbmodem1411″,”w”); //Declare the file in write mode
if (arduino == NULL) perror (“Error opening file”);
//Setting up the file input stream
ifstream inFile (“input.txt”);
assert(inFile.is_open());
char input = '\0'; //Starts out as NULL
while (input!= EOF) {
fprintf(arduino,”%c “, input); //Writing to the file
inFile >> input; //Getting the file input to make sure it isn’t the EOF
sleep(1);
}
fclose(arduino);
}
Arduino Code:
void setup()
{
Serial.begin(9600);
}
void loop()
{
char input;
if(Serial.available()) //If anything is in the Serial
{
input=Serial.read();
Serial.println(input); //Print out any input
}
}
Sample input from input.txt:
w a d s w d a a s d w
That string of characters will provide a direction (up, down, left, right) as per WASD.
It's possible to use the file handle to write data to a serial device, but it might be helpful to first try using the native Unix serial communication API as a sanity check.
Take a look at this post on todbot.com: Arduino-serial: C code to talk to Arduino
The todbot.com post describes a general purpose program for talking to an Arduino over its serial connection. The source has a lot of code for getting settings from the command line, and is a bit intimidating because it's robust, but the business end of the serial communication is fairly straightforward if you want to see how he does it.
I wrote my own series of posts on the topic, with some light-weight code (in parts 3 and 4) that demonstrates how to do almost exactly what you're trying to do.
How to read serial data from an Arduino in Linux with C: Part 1
I hope something in those links help! Serial communication is hard, so don't beat yourself up too much if it's not going your way.

Extra Characters Reading from Serial Port Using libserial on Linux

I have a very basic device with which I am trying to interact via a serial connection on Linux. I am on the steep part of the learning curve here, still, so please be gentle!
Anyhow, I am able to control the device via Hyperterminal in Windows, or via cu, screen, or minicom in Linux. I am connected via a built-in serial port on a PC at 19200, 8N1. The interface for the device is very simple:
Type "H", and the device echoes back "H".
Type "V", and the device echoes back a string containing its software version, "ADD111C".
Type "S", and the device returns "0", "1", or "?", depending on its printer status.
Type "Q", and it returns a five-line response with details on the last transaction processed.
Each response is followed by a new-line, perhaps a CR, too, I am not certain.
There's more, but that's a good start. When I connect to the device using screen, it works fine:
root#dc5000:~# screen /dev/ttyS0 19200,cs8,-ixon,-ixoff
V
ADD111C
Once I had that working manually, I tried to write a simple program using C++ and libserial to interact with the device. It looks like this:
#include <SerialStream.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
using namespace LibSerial;
int main(){
char next_char[100];
int i;
SerialStream my_serial_stream;
my_serial_stream.Open("/dev/ttyS0") ;
my_serial_stream.SetBaudRate( SerialStreamBuf::BAUD_19200 ) ;
my_serial_stream.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ;
my_serial_stream.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ;
my_serial_stream.SetParity( SerialStreamBuf::PARITY_NONE ) ;
my_serial_stream.SetNumOfStopBits(1) ;
my_serial_stream.SetVTime(1);
my_serial_stream.SetVMin(100);
cout<<"Sending Command:\n";
my_serial_stream << "V";
my_serial_stream.read(next_char,100);
cout<<"Result: "<<next_char<<"\n";
my_serial_stream.Close();
return 0;
}
This is successfully able to send the "V" to the serial port, but when I read it back, I get a number of non-printing characters back after the valid data:
root#dc5000:~# g++ -o serialtest serialtest.cpp -lserial
root#dc5000:~# ./serialtest
Sending Command:
Result:
V
ADD111C
��se�Xw��AN��ƿ,�
root#dc5000:~#
What am I missing to only grab the response to my query? I'm guessing that I need to flush a buffer on the port or something, but I have reached the end of my limited knowledge here.
Ideally I would like to just get the "ADD111C", but I don't want to paint myself into a corner by grabbing a specific length of data (in case it changes in the future), and the garbage at the end of the read does not always seem to be the same length, or the same data.
Many thanks for taking a look,
Tom
Zack & keshlam: Thank you for the help. Zack's suggestion to write a NULL to the end of the string resolved the problem, but I actually stumbled across a simpler method while working with another string (trying to grab a substring of the output).
Rather than define the C string like this:
char next_char[100];
I did it like this:
char next_char[100] = "";
It seems that assigning a value to the char before reading from the serial port properly null terminated it. I can now remove the memset command from my code and it now works fine:
root#dc5000:~# ./serialtest
Sending Command:
Result:
V
ADD111C
Thanks for the help!

Send Hex data to a serial port?

I have a GPS connected to USB0 and I can read everything perfectly but now I am trying to write data to it. It works with sending and receiving Hexadecimal data. I tried to send data to the GPS. Let's say I want to send 0xB6 0x62 to the port how could I do it in C++. I used this but I don't know weatehr I am right or wrong could someone help me
int main()
{
unsigned char bytestosend[2] = {0xB5, 0x62};
write(fd,&bytestosend,2);
}
of course I open the port to the file descriptor fd.
basically, what you're doing is right given your GPS reads actually hexadecimal bytes. But it may as well read string encoded hexadecimal values, so be sure of that. So from what you tell, I'd say you're writing to it correctly.
And you don't say how you open the serial port, but be careful to use termios and set the connection up correctly, or you may get issues. You shall not just open the port like a standard file. If you haven't done it yet, have a good read of this!

printing to a network printer using fstream c++ in mac

I wish to print some text directly to a network printer from my c++ code (I am coding with xcode 4). I do know that everything on unix is a file and believe that it would not be impossible to redirect the text using fstream method in c++ to the printer device file. The only problem is I don't know the device file in /dev associated with my network printer.
Is it possible to achieve printing using fstream method? Something like
std::fstream printFile;
printFile.open("//PATH/TO/PRINTER/DEV", std::ios::out);
printFile << "This must go to printer" << std::endl;
printFile.close();
And, if so
How to obtain the file in /dev corresponding to a particular printer?
Thanks in advance,
Nikhil
Opening and writing directly to a file used to be possible back in the days of serial printers; however, this is not the approach available today.
The CUPS daemon provides print queuing, scheduling, and administrative interfaces on OS X and many other Unix systems. You can use the lp(1) or lpr(1) commands to print files. (The different commands come from different versions of print spoolers available in Unix systems over the years; one was derived from the BSD-sources and the other derived from the AT&T sources. For compatibility, CUPS provides both programs.)
You can probably achieve something like you were after with popen(3). In shell, it'd be something like:
echo hello | lp -
The - says to print from standard input.
I haven't tested this, but the popen(3) equivalent would probably look like this:
FILE *f = popen("lp -", "w");
if (!f)
exit(1);
fprintf(f, "output to the printer");
I recommend testing some inputs at the shell first to make sure that CUPS is prepared to handle the formatting of the content you intend to send. You might need to terminate lines with CRLF rather than just \n, otherwise the printer may "stair-step" the output. Or, if you're sending PDF or PS or PCL data, it'd be worthwhile testing that in the cheapest possible manner to make sure the print system works as you expect.