Sending command and waiting for reply to a USB device - c++

I have a device (rotary measuring table) connected over USB to /dev/ttyACM0, and need to write a simple cpp controller to send the commands to the device and listen for response.
I have no experience with this kind of stuff. I understand I can open the USB device using fstream and send the command using write(). That works.
Question is how can I send the command and start listening for response?
The code below just hangs. I am guessing because it is synchronous and therefore the response is missed.
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::fstream f;
char command[256] = "?ASTAT\n\r";
char response[256];
std::string str;
f.open("/dev/ttyACM0");
if (f.is_open())
{
std::cout << "Port opened" << std::endl;
}
f.write(command, 256);
while(1)
{
while (f >> str)
{
std::cout << str;
}
}
return 0;
}
I have looked into asynchronious libusb-1.0 but have a problem finding my way around http://libusb.sourceforge.net/api-1.0/group__libusb__asyncio.html and figuring out where to start from.
EDIT:
I managed to get the device to respond as follows:
std::string response_value = "";
char response = 0;
std::cout << "response: ";
while(1)
{
f << command;
f.read(&response, 1);
if ((int)response == 13)
{
break;
}
std::cout << (response) << " ";
response_value += response;
}
After talking to the producer and trying out different commands and outputting the message, I figured out that the device should send variable length response which always ends with 0x0D or integer 13.
Currently if I send multiple commands after each other, nothing happens.
From other sources I understand I need to set the baud rate, however, fstream has no file descriptor, and `tcgetattr(2)1 reauires file descriptor to initialize the termios structure. Is there a way to retrieve it?

To answer the question the best I can. It is possible to read/write to usb device as a file because the os has drivers which are handling the communication (please correct me if I understood it wrong).
fstream is capable of reading and writing, however it is not possible to adjust the baud rate (frequency at which the device is communication) because the adjustment mus be done on terminal level and is therefore os dependent. For Linux, we must use fctl.h, termios.h and unistd.h. It allows us to set the rate, as well as a timeout in case there is no response from the device.
Therefore, implementing the reading and writing only using cpp functions is quite a bit more complex.
I am posting here my solution which works for me, but any comments on it are welcome.
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <string>
#include <iostream>
bool init_terminal_interface(struct termios& tty, const int file_descriptor)
{
memset(&tty, 0, sizeof tty); // Init the structure;
if (tcgetattr(file_descriptor, &tty) != 0)
{
std::cout << "Error" << errno << " from tcgetattr: " << strerror(errno) << std::endl;
return false;
}
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag &= ~ICANON;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 0; //
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Flush Port, then applies attributes */
tcflush(file_descriptor, TCIFLUSH);
if (tcsetattr(file_descriptor, TCSANOW, &tty) != 0) {
std::cout << "Error " << " from tcsetattr: " << strerror(errno) << std::endl;
return false;
}
return true;
}
void send_command(std::string command, const int file_descriptor)
{
write(file_descriptor, command.c_str(), command.size());
std::cout << "Command sent: " << command << std::endl;
}
std::string check_response(int file_descriptor)
{
std::string response_value = "";
char response = 0;
ssize_t n_read = 0;
do {
// In blocking mode, read() will return 0 after timeout.
n_read = read( file_descriptor, &response, 1 );
if (n_read > 0)
{
response_value += response;
}
} while( response != '\r' && (int)response != 13 && n_read != 0);
// In case of timeout it will return an empty string.
return response_value;
}
int open_serial(const std::string serial_path)
{
int file_descriptor = open(serial_path.c_str(), O_RDWR);
if (file_descriptor == -1)
{
std::cout << "Unable to access the turntable device." << std::endl;
return -1;
}
std::cout << "File opened: " << file_descriptor << std::endl;
struct termios tty;
init_terminal_interface(tty, file_descriptor);
return file_descriptor;
}
int main()
{
int file_descriptor = open_serial("/dev/ttyACM0");
if (file_descriptor == -1)
{
return 1;
}
// Good command.
std::string command = "?baudrate\r\n";
send_command(command, file_descriptor);
std::string response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
// Wrong command.
command = "?asasdtat\r\n";
send_command(command, file_descriptor);
response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
// Good command.
command = "init1\r\n";
send_command(command, file_descriptor);
response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
// Good command.
command = "ref1=4\r\n";
send_command(command, file_descriptor);
response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
return 0;
}

Related

How to manipulate libevent bufferevents outside of callbacks

I use libevent to write client-server application, on client side i want to continiusly wait for intput from console. I tried to run event_base_dispatch in thread, and in main thread ask for input string and add it to bufferevent.
std::thread libevthr(libev_start, base);
std::string s;
do
{
cin >> s;
bufferevent_write(bev, "Hello, world!", 13);
} while(s != "xxx");
libevthr.join();
For some reason this doesn't work, but if i put bufferevent_write inside one of callbacks, it works fine
void event_cb(struct bufferevent *bev, short events, void *ptr)
{
if (events & BEV_EVENT_CONNECTED) {
/* We're connected to 127.0.0.1 Ordinarily we'd do
something here, like start reading or writing. */
bufferevent_write(bev, "Hello, world!", 13);
std::cout << "Connected" << std::endl;
}
if (events & BEV_EVENT_ERROR) {
if (EVUTIL_SOCKET_ERROR() == 10054)
cout << "Server stopped working!" << endl;
else
cout << "Error has happened" << endl;
}
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR))
{
bufferevent_free(bev);
}
}
Can you explain how should i write this correctly?
Sorry if i have any mistakes in english.
Full code here:
#include "UClient.h"
#include <iostream>
#include "event2/event.h"
#include "event2/listener.h"
#include "event2/bufferevent.h"
#include "event2/buffer.h"
#include <thread>
using std::cout, std::cin, std::endl;
void event_cb(struct bufferevent *bev, short events, void *ptr)
{
if (events & BEV_EVENT_CONNECTED) {
/* We're connected to 127.0.0.1 Ordinarily we'd do
something here, like start reading or writing. */
bufferevent_write(bev, "Hello, world!", 13);
std::cout << "Connected" << std::endl;
}
if (events & BEV_EVENT_ERROR) {
if (EVUTIL_SOCKET_ERROR() == 10054)
cout << "Server stopped working!" << endl;
else
cout << "Error has happened" << endl;
}
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR))
{
bufferevent_free(bev);
}
}
void write_cb(struct bufferevent *bev, void *ctx)
{
cout << 'Data was written' << endl;
}
void libev_start(event_base *base)
{
event_base_dispatch(base);
}
int main()
{
int port = 9554;
struct event_base *base;
struct bufferevent *bev;
struct sockaddr_in cl_inf;
if (!initWinsock()) {
perror("Failed to initialize Winsock");
return 1;
}
base = event_base_new();
ZeroMemory(&cl_inf, sizeof(cl_inf));
in_addr serv_ip;
inet_pton(AF_INET, "127.0.0.1", &serv_ip);
cl_inf.sin_family = AF_INET;
cl_inf.sin_addr = serv_ip;
cl_inf.sin_port = htons(port);
bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, NULL, write_cb, event_cb, NULL);
if (bufferevent_socket_connect(bev,
(struct sockaddr *)&cl_inf, sizeof(cl_inf)) < 0) {
/* Error starting connection */
std::cout << "Can't connect to server!" << std::endl;
bufferevent_free(bev);
return -1;
}
bufferevent_enable(bev, EV_READ | EV_WRITE);
std::thread libevthr(libev_start, base);
std::string s;
do
{
cin >> s;
} while(s != "xxx");
libevthr.join();
std::cout << "client finished working";
return 0;
}

Serial port becomes unresponsive on Ubuntu 20.04, but works on Ubuntu 18.04

I wrote a C++ program to continuously read data from a device, via serial over USB. The program works flawlessly in UbuntuĀ 18.04 (Bionic Beaver). I have an identical system running UbuntuĀ 20.04 (Focal Fossa) and the same program does not work properly. It will read a few KB from the serial port, but then no more data is detected by read().
Here is the code:
#include <iostream>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
int receive_data(int fd, unsigned char read_buf[], int num_requested_bytes)
{
int total_received_bytes = 0;
int num_received_bytes = 0;
// Continue reading the serial port until the number of requested bytes have been read
while (total_received_bytes < num_requested_bytes)
{
num_received_bytes = read(fd, read_buf + total_received_bytes,
num_requested_bytes - total_received_bytes);
if (num_received_bytes < 0)
{
if (errno == EAGAIN)
{
num_received_bytes = 0;
}
else
{
std::cout << "Encountered error during read(): " << errno << std::endl;
exit(-1);
}
}
total_received_bytes += num_received_bytes;
if (total_received_bytes >= num_requested_bytes)
{
break;
}
}
return total_received_bytes;
}
int main()
{
// Open serial port
int fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NONBLOCK);
int flags = fcntl(fd, F_GETFL);
//fcntl(fd, F_SETFL, flags | O_ASYNC); // <------------------- SEE NOTE
// Read in existing settings, and handle any error
struct termios tty;
if(tcgetattr(fd, &tty) != 0)
{
close(fd);
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
exit(-1);
}
// Set flags
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 0;
// Raw input mode
cfmakeraw(&tty);
// Save tty settings, also checking for error
if (tcsetattr(fd, TCSANOW, &tty) != 0)
{
close(fd);
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
exit(1);
}
// Attempt to read from port
int received_bytes;
unsigned char read_buf[1024];
while (true)
{
received_bytes = receive_data(fd, read_buf, 1024);
std::cout << "Received " << received_bytes << " bytes. First 2 numbers in frame: "
<< ((unsigned int) (read_buf[1] << 8 | read_buf[0])) << ", "
<< ((unsigned int) (read_buf[3] << 8 | read_buf[2])) << std::endl;
}
}
Here is example output from the program in Ubuntu 20.04. After 0-3 frames, I no longer receive any data and the program endlessly loops on my read() call.
On Ubuntu 18.04, the program will continue endlessly.
$ ./main
Received 1024 bytes. First 2 numbers in frame: 65535, 2046
Received 1024 bytes. First 2 numbers in frame: 2046, 3338
Received 1024 bytes. First 2 numbers in frame: 2045, 2046
See note:
If I enable the O_ASYNC flag, the program will exit on the first read() with I/O Possible printed in the terminal. If I then comment out the line and recompile, the program runs and fetches frames continuously as expected.
What could be causing this?

Why poll() returns immediately on regular files and blocks on fifo?

I checked this code several times and cannot understand why does poll() return immediately?
Here file is opened for read and should wait for event. How to make it wait for input?
#include <iostream>
#include <poll.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;
ssize_t read_out_to_the_end(int fd){
char chunk[1024];
ssize_t ret = 0, n;
while((n = ::read(fd, chunk, sizeof chunk)) > 0){
ret += n;
cerr << "read chunk: " << n << " | ";
cerr.write(chunk, n);
cerr << endl;
}
if (n < 0) {
cerr << "err in read" << endl;
}
else if (ret == 0){
cerr << "nothing to read" << endl;
}
return ret;
}
int main() {
int bininfd = open("bin-in", O_RDONLY | O_CREAT);//, 0644/*S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH*/);
if (bininfd < 0) {
perror("err in open(binin)");
return -1;
}
struct pollfd pollfds[] = {
{bininfd, POLLIN, 0},
};
auto&[pfd] = pollfds;
while (1) {
pfd.revents = 0; // cleanup, shouldn't it be redundant
int pollret = poll(pollfds, 1, -1);
if (pollret > 0) {
if (pfd.revents & POLLIN) {
cerr << "(pfd.revents & POLLIN)" << endl;
read_out_to_the_end(pfd.fd);
}
} else if (pollret == 0) {
cerr << "poll timed out" << endl;
continue;
} else {
cerr << "check for error" << endl;
continue;
}
}
}
the output is
(pfd.revents & POLLIN)
nothing to read
(pfd.revents & POLLIN)
nothing to read
(pfd.revents & POLLIN)
nothing to read
(pfd.revents & POLLIN)
nothing to read
(pfd.revents & POLLIN)
............... etc ....................
live example
UPDATE:
read_out_to_the_end() fixed. Thanks to #RemyLebeau
it works (blocks) on fifos as I expect, but not on regular files. Why?
poll() or select() never block on regular files. They always return a regular file as "ready". If you want to use poll() to do what tail -f does, you're on the wrong track.
Quoting from the SUSv4 standard:
The poll() function shall support regular files, terminal and
pseudo-terminal devices, FIFOs, pipes, sockets and [OB XSR] STREAMS-based files. The behavior of poll() on
elements of fds that refer to other types of file is unspecified.
Regular files shall always poll TRUE for reading and writing.
Since using poll() or select() on regular files is pretty much useless, newer interfaces have tried to remedy that. On BSD, you could use kqueue(2) with EVFILT_READ, and on Linux inotify(2) with IN_MODIFY. The newer epoll(7) interface on Linux will simply error out with EPERM if you try to watch a regular file.
Unfortunately, neither of those is standard.
read_out_to_the_end() has several issues:
ret is uninitialized.
The while loop is incrementing n when it should be assigning it instead. But then if the while loop hits the EOF, if( n == 0) will be true even if data was actually read before hitting EOF.
chunk may be null-terminated, but it may also receive nulls too, depending on the input data. So it should not be written to cerr (why not cout?) using operator<<, use cerr.write() instead so that you can pass it the actual number of bytes read.
Try this instead:
ssize_t read_out_to_the_end(int fd){
char chunk[1024];
ssize_t ret = 0, n;
while((n = ::read(fd, chunk, sizeof chunk)) > 0){
ret += n;
cerr << "read chunk: " << n << " | ";
cerr.write(chunk, n);
cerr << endl;
}
if (n < 0) {
cerr << "err in read" << endl;
}
else if (ret == 0){
cerr << "nothing to read" << endl;
}
return ret;
}
int main() {
int bininfd = open("bin-in", O_RDONLY | O_CREAT);//, 0644/*S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH*/);
if (bininfd < 0) {
perror("err in open(binin)");
return -1;
}
pollfd pfd = {};
pfd.fd = bininfd;
pfd.events = POLLIN;
while (true) {
pfd.revents = 0; // cleanup, shouldn't it be redundant
int pollret = poll(&pfd, 1, -1);
if (pollret > 0) {
if (pfd.revents & POLLIN) {
cerr << "(pfd.revents & POLLIN)" << endl;
read_out_to_the_end(pfd.fd);
}
} else if (pollret == 0) {
cerr << "poll timed out" << endl;
continue;
} else {
cerr << "poll error " << errno << endl;
break;
}
}
}
Also, on a side note, the open() documentation says:
The mode argument specifies the file mode bits be applied when a new file is created. This argument must be supplied when O_CREAT or O_TMPFILE is specified in flags; if neither O_CREAT nor O_TMPFILE is specified, then mode is ignored. The effective mode is modified by the process's umask in the usual way: in the absence of a default ACL, the mode of the created file is (mode & ~umask). Note that this mode applies only to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.

Serial read() does not return a value without data receiving

I am trying to work with read() function with serial connection.
I initialize serial port with the following settings:
bool HardwareSerial::begin(speed_t speed) {
int USB = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (USB == 1) {
std::cout << "\n Error! in Opening ttyUSB0\n" << std::endl;
} else {
std::cout << "\n ttyUSB0 Opened Successfully\n" << std::endl;
}
struct termios tty;
struct termios tty_old;
memset(&tty, 0, sizeof tty);
// Error Handling
if (tcgetattr(USB, &tty) != 0) {
std::cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
}
//Save old tty parameters
tty_old = tty;
// Set Baud Rate
cfsetospeed(&tty, (speed_t) speed);
cfsetispeed(&tty, (speed_t) speed);
// Setting other Port Stuff
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 1; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
// Make raw
cfmakeraw(&tty);
//Flush Port, then applies attributes
tcflush(USB, TCIFLUSH);
if (tcsetattr(USB, TCSANOW, &tty) != 0) {
std::cout << "Error " << errno << " from tcsetattr" << std::endl;
}
_USB = USB;
return true;
}
Then I periodically call class member read() function that calls stream read:
int HardwareSerial::read() {
int n = 0;
char buf;
n = ::read(_USB, &buf, 1);
std::cout << std::hex << static_cast<int> (buf) << " n:";
std::cout << n << std::endl;
}
While the port receives data read() works as expected and prints incoming bytes. But if I stop sending bytes the program hangs until some bytes will have not received.
I expect that ::read will return 0, but it does not return anything and waits for incoming data. After new data is received the program continues work and ::read returns 1;
So what I missed in the configuration?
I tried different VMIN and VTIME but the result is the same.
You are reading from the USB in blocking manner, e.g. if no data available the call is blocked and process will not make any progress until data will arrive.
Than can be done, you can set descriptor to read in NON-BLOCKING mode, something along these lines:
int flags = fcntl(_USB, F_GETFL, 0);
fcntl(_USB, F_SETFL, flags | O_NONBLOCK)
Now than you will try to read you can do:
int count;
char buffer;
count = read(_USD, buf, 1);
// Check whenever you succeeded to read something
if(count >=0) {
// Data is arrived
} else if(count < 0 && errno == EAGAIN) {
// No Data, need to wait, continue, or something else.
}
You can also probably use select function to check whenever device descriptor is ready to read from.

Ubuntu C++ termios.h example program

I searched a lot and tried many different ways, but I cannot send data to gtkterm via virtual serial bridge (for testing!).
My idea is to communicate with an Atmega uC later on, but first I wanted to test the serial communication by setting up a virtual serial bridge with the help of soccat and controlling the output serial port with gtkterm. The problem is that I'm just receiving useless things in gtkterm... (see screenshots)
soccat command:
socat -d -d PTY: PTY:
The soccat virtual serial port bridge seems to be ok, because I can send data from one serial terminal to another...
gtkterm port preferences:
Port: /dev/pts/6
Baudrate: 9600
Parity: none
Bits: 8
Stopbits: 1
Flow control: none
My little GUI compiles and runs fine, with the input path "/dev/pts/6" and the input baudrate 9600. The program seems to run fine, but in gtkterm are just question marks and quadangles with symbols in every corner coming up. Let's say its not interpretable and independent by the signs as input, BUT the lengths of the output in gtkterm changes by the length of the input (the amount of signs I type in).
Finally here's my code:
main.cpp:
#include <iostream>
#include "serial/serial_communication.cpp"
std::string inputStringUser = "";
int inputIntUser = 0;
std::string pathSerial = "/dev/...";
int baudrate = 19200;
int main()
{
std::cout << "main() [communication_serial_uC] started..." << std::endl;
//GETTING STARTED
std::cout << "Use default port? " << pathSerial << " (Yes = y/ change port = insert the new path" << std::endl;
std::cin >> inputStringUser;
if(inputStringUser != "y" && inputStringUser != "Y")
pathSerial = inputStringUser;
std::cout << "Serial Port is set to: " + pathSerial << std::endl;
std::cout << "Use default baudrate? " << baudrate << "Yes = 0/ change baudrate = insert new baudrate" << std::endl;
std::cin >> inputIntUser;
if(inputIntUser > 0)
baudrate = inputIntUser;
std::cout << "Baudrate is set to: " << baudrate << std::endl;
Serial_communication myPort(pathSerial, baudrate);
//OPEN/ CONFIGURATE PORT
if(myPort.openPort(pathSerial, baudrate) < 0)
{
std::cout << "Error: opening" << std::endl;
return -1;
}
//WRITE PORT
std::cout << "Insert your 'message': (exit = 'exit')" << std::endl;
std::cin >> inputStringUser;
while(inputStringUser != "exit")
{
if(myPort.sendPort(inputStringUser) < 0)
{
std::cout << "Error: sending" << std::endl;
return -1;
}
std::cout << "Insert your 'message': (exit = 'exit')" << std::endl;
std::cin >> inputStringUser;
}
//CLOSE PORT
if(myPort.closePort() < 0)
{
std::cout << "Error: closing" << std::endl;
return -1;
}
std::cout << "main() [communication_serial_uC] beendet..." << std::endl;
return 0;
}
serial/serial_communication.hpp:
#include <iostream>
#include <string>
#include <cstring>
#include <fcntl.h>
#include <termios.h>
class Serial_communication{
public:
Serial_communication(std::string paramPathSerial, int paramBaudrate);
~Serial_communication();
int openPort(std::string pathSerial, int baudrate);
int sendPort(std::string testString);
int closePort();
private:
std::string pathSerial;
int baudrate;
//filedescriptors
int fd;
};
serial/serial_communcation.cpp
#include <iostream>
#include "serial_communication.h"
Serial_communication::Serial_communication(std::string paramPathSerial, int paramBaudrate)
{
fd = 0;
pathSerial = paramPathSerial;
baudrate = paramBaudrate;
}
Serial_communication::~Serial_communication()
{
}
int Serial_communication::openPort(std::string pathSerial, int baudrate)
{
std::cout << "openPort() [serial_communication] started with the following paramters... pathSerial = " << pathSerial << ", baudrate = " << baudrate << std::endl;
//OPENING PORT
//open serial port
fd = open(pathSerial.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if(fd < 0)
{
std::cout << "Error [serial_communcation]: opening Port: " << pathSerial << std::endl;
return -1;
}
//struct termios
struct termios serial, serial_old;
//get parameters associated with the terminal
if(tcgetattr(fd, &serial) < 0)
{
std::cout << "Error [serial_communication]: getting configuration" << std::endl;
return -1;
}
//safe old parameters
serial_old = serial;
std::cout << "[serial_communication]: Port opened" << std::endl;
//SERIAL CONFIGURATION
/* Set Baud Rate */
cfsetospeed (&serial, (speed_t)baudrate);
cfsetispeed (&serial, (speed_t)baudrate);
// Setting other Port Stuff
serial.c_cflag &= ~PARENB; // Make 8n1
serial.c_cflag &= ~CSTOPB;
serial.c_cflag &= ~CSIZE;
serial.c_cflag |= CS8;
serial.c_cflag &= ~CRTSCTS; // no flow control
serial.c_cc[VMIN] = 1; // read doesn't block
serial.c_cc[VTIME] = 5; // 0.5 seconds read timeout
serial.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Make raw */
cfmakeraw(&serial);
/* Flush Port, then applies attributes */
tcflush( fd, TCIFLUSH );
//set attributes to port
if(tcsetattr(fd, TCSANOW, &serial) < 0)
{
std::cout << "Error [serial_communication]: set attributes" << std::endl;
return -1;
}
//CONFIGURATION FINISHED
std::cout << "openPort() [serial_communication] finished..." << std::endl;
return 1;
}
int Serial_communication::sendPort(std::string textString)
{
std::cout << "write() [Serial_communication] started with the following parameter... textString = " << textString << std::endl;
//attempt to send
if(write(fd, &textString, std::strlen(textString.c_str())) < 0)
{
std::cout << "Error [serial_communcation]: write";
return -1;
}
//SENDING FINISHED
std::cout << "write() [serial_communcation] finished..." << std::endl;
return 1;
}
int Serial_communication::closePort()
{
close(fd);
return 1;
}
So... thats all I got. I tried my best and joined the information from many websites and tried a lots of example codes. My problem is that I dont even know where to search for, so I'm appreciate for any clue...
If there are any questions or information missing, pls let me know it!
Thanks in advance
Thorben
BTW: I'm not THAT experienced with C++ and I'm opened up for comments about my style, but that should not be the main problem...