Reputation: 1210
When communicating with a serial-over-USB device (a GNS FM9 receiver for getting road traffic alerts) by using libserial
's SerialStream
object, I found out that not all characters coming from the device are in fact being read. This is what I always get served:
3F 00 56 08 37 3F
When using the same device with the RDS Surveyor app (which is written in Java and uses a com.fazecast.jSerialComm.SerialPort
), the same response looks like this:
3F 00 00 56 08 0A 37 0C 0D 3F
After some research, I stumbled over this posting: Wrong newline character over the serial port (CR instead of LF). The poster does not use libserial
(but some ready-to-use serial port comm app), but his issue is exactly the same as mine.
This is the system-side config of the port in question:
pi@autoradio:~ $ stty -a
speed 38400 baud; rows 40; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U;
eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0; -parenb -parodd -cmspar
cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr
-igncr icrnl ixon ixoff -iuclc -ixany -imaxbel iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret
-ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh
-xcase -tostop -echoprt echoctl echoke -flusho -extproc
The system is a Raspbery Pi 3B with the latest production version of Raspbian running. On the system-side, the device looks like this:
pi@autoradio:~ $ ls -al /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Jun 7 17:11 /dev/ttyUSB0
Now, my question is: How can I make my SerialStream read all characters without any transformations, just as they come from the port? I don't really wanna use stty
in this context because its settings might get overwritten when removing and reattaching the device. Thank you.
Upvotes: 0
Views: 303
Reputation: 1210
OK, I opened an issue with the maintainers of libserial
and got the answer that the C++ std::iostream
(NOT even LibSerial::SerialStream
!) kicks out whitespace characters by default. CR, LF, and FF are regarded as such.
They proposed me this solution:
SerialStream tmc_receiver_handler ("/dev/ttyUSB0", ios::in | ios::out);
char c = 0x00;
tmc_receiver_handler.SetBaudRate (SerialStreamBuf::BAUD_38400);
tmc_receiver_handler.SetCharSize (SerialStreamBuf::CHAR_SIZE_8);
tmc_receiver_handler.SetFlowControl (SerialStreamBuf::FLOW_CONTROL_NONE);
tmc_receiver_handler.SetParity (SerialStreamBuf::PARITY_NONE);
tmc_receiver_handler.SetNumOfStopBits (SerialPort::STOP_BITS_1);
tmc_receiver_handler >> noskipws >> c;
noskipws
switches off whitespace suppression. After applying this, everything works fine.
Upvotes: 0
Reputation: 18349
You need to make sure the port is in "raw" mode.
From a quick look at the libserial documentation, it seems it doesn't have a parameter to set a raw mode. Some options:
The implementation of libserial seems quite basic; you are probably better off using something like Boost.asio.
Upvotes: 1