Pharo: read byte from Arduino serial port - serial-port

I have an Arduino hanging off /dev/ttyUSB1, communicating at 115kbaud. The statements below work fine up to the 's next' method call, where Pharo hangs. The Arduino responds to the '99' command by sending a single character $1 back to the computer. If I pull out the cable, the program continues and s contains the character $1 just like it should, but not until I pull out the cable. So it's my impression that 's next' does not return after it reads just a single byte (ok, sure, there's nothing that says it should return after reading a single byte). How do I read a single byte from a stream in Pharo? Or how do I open a read/write byte stream? I haven't found anything in the source classes that seem to do this. I've tried setting the stream to ascii, to binary, to text, and it doesn't change the behavior.
s := FileStream oldFileNamed: '/dev/ttyUSB1'.
s readWrite.
s nextPutAll: '99'. "'99' is successfully received by Arduino"
s next. "hangs here"
s close.
Thanks for your help.

Take a look at the class side of FileStream. There you'll notice that you are getting a MultiByteStream (the concreteStream) when asking Filestream for an oldFileNamed:.
There can be a TextConverter or buffer involved. open:forWrite: of MultiByteStream is called, and that calls super. StandardFileStream>open:forWrite: calls enableReadBuffering.
You probably want to call disableReadBuffering on your stream.

There is an Arduino package that has all these issues solved, take a look at this repo:
http://ss3.gemstone.com/ss/Arduino.html

Related

QTextBrowser display issue in Qt 4.8.6 - always displayed wrongly

I hope to read some characters or strings and display them with QTextBrowse from serial port by Qt 4.8.6 and called the following functions( textBrowser is a object of QTextBrowser):
connect(com, SIGNAL(readyRead()), this, SLOT(readSerialPort()));
connect(textBrowser, SIGNAL(textChanged()), SimApplianceQtClass, SLOT(on_textBrowser_textChanged()));
void SimApplianceQt::on_textBrower_textChanged()
{
ui.textBrowser->moveCursor(QTextCursor::End);
}
void SimApplianceQt::readSerialPort()
{
QByteArray temp = com->readAll();
ui.textBrowser->insertPlainText(temp);
}
However, every time I cannot display characters or strings in the textBrowser rightly. Those input strings are always cut into smaller strings to be displayed in multiple lines in the textBrowser. For example, a string "0123456789" may be displayed as (in multiple lines):
01
2345
6789
How to deal with this issue? Many thanks.
What happens is that the readyRead signal is fired not after everything has been received, but after something has been received and is ready to read.
There is no guarantee that everything will have arrived or is readable by the time you receive the first readyRead.
This is a common "problem" for almost any kind of IO, especially if the data is larger than very few bytes. There is usually no automatic way to know when all the data has been received.
There are a few possible solutions:
All of them will require you to put the data in a buffer in readSerialPort() instead of adding it directly to the text browser. Maybe a simple QByteArray member variable in SimApplianceQt would already do the trick in your case.
The rest depends on the exact solution.
If you have access to the sender of the data, you could send the
number of bytes that will be sent before sending the actual string.
This must always be in an integer type of the same size (for
example, always a quint32). Then, in readSerialPort(), you would
first read that size, and then continue to read bytes to your buffer
in readSerialPort() until everything has been received. And then,
you could finally print it. I'd recommend that one. It is also what is used in almost all cases where this problem arises.
If you have access to the sender of the data, you could send some
kind of "ending sequence" at the end of the string. In your
readSerialPort(), you would then continue to read bytes into your
buffer until you receive that ending sequence. Once the ending
sequence has been received, you can print everything that came in
prior to it. Note that the ending sequence itself could be interrupted,
so you'd have to take care of that, too.
If you do not have access to the sender, the best idea I could come
up with would be to work with a timer. You put everything into a
buffer and re-start that timer each time you readSerialPort() is
called. When the timer runs out, that means no new data has been
sent for a while and you can probably print what you have so far.
This is... risky and I wouldn't recommend it if there is any other way.

How to get raw (un-decoded) byte arrays from a TCPSocket in Ruby

I've been using ruby to setup a TCPSocket with a server and I've hit a snag. When receiving data from the socket (with either a socket.gets or a socket.recv) I get something like this:
x00\x03!\xB2\x00\x00*\xCF
What I get when I capture the packets in Wireshark is
x00\x03\x21\xB2\x00\x00\x2a\xCF
As you can see, the \x21 is decoded into the ASCII equivalent ! and the \x2a is decoded into the ASCII equivalent *.
I've checked and googled a ton of times and have not yet found a solution to get the raw, un-decoded information. I have a parser built that will search for the relevant data from the stream and grab what I need, but I don't want to have to waste time re-encoding it before I have to decode it. Or, I incorporate ASCII into my parser, but that would be a huge pain. There is a lot of bytes in this stream and to re-encode them all would be time consuming. I also see that netcat returns the same output from the TCP stream that ruby does. I could not figure out how to get netcat to output the un-decoded byte arrays either.
Code:
require 'socket'
s = TCPSocket.new "10.0.0.3", 27000
while true do
item = s.recv(5000)
puts item
puts item.inspect
end
This is my first foray into socket programming, so I apologize if I missed something very obvious.
I kind of invented the problem in my head, I am dumb.
To solve this, all you need to do is take the string of TCP information and call unpack("H*") on it like this:
"x00\x03!\xB2\x00\x00*\xCF".unpack("H*")
=> ["7830300321b200002acf"]
Which is exactly like x00\x03\x21\xB2\x00\x00\x2a\xCF
Now I just need to adjust my parser to split it or deal with the big clump of byte arrays
More info on unpack

Beep Sound when Decoding DSP TrueSpeech To PCM

I'm trying to decode array of bytes from DSP TrueSpeech to PCM.
When we convert this array as part of streaming (divide it to packets) we can hear some strange "Beep" tones after the decoding.
We tried to decode the entire WAV file in one piece and we didn't get those Beeps.
Currently we are using Alvas.net for it, but we tried also with NAudio and got the same reaults?
My questions:
1)Is anyone familiar with this kind of behavior?
2)Do you have an idea what can we do?
Thanks
Ziv
How are you performing the decode? Often codecs maintain internal state, so it's important that you don't keep closing and re-opening the codec for each block of audio that you receive. In NAudio, that means just one AcmStream/WaveFormatConversionStream that everything you receive is passed through.
Also, make sure it is only compressed audio that is being passed into the codec. Sometimes when you receive audio over the network it is contained within some kind of larger packet that contains timing or encoding metadata (e.g. RTP).
At the bottom line, we have the packet data(array of bytes) which we are sending to decode (return as PCM) and then we're writing the new decoded array of bytes in to the new WAV file.
We're defiantly going to try your suggestion regarding the stream with NAudio.
Regarding the bytes we're working on, they don't contain any garbage. We've wrote a tester that stream the file directly (without network) and got the same beep results.
Our solution is working so well with many other codecs (GSM and etc..) and only in true speech we're having this problem.
Therefore it seems to be like some behavior of True Speech codec, but we didn't find any documentation about it.
Thanks Again
Ziv

FileOutputStream: write to serial port

I'm trying to write single bytes to a serial port in Vala using a FileOutputStream:
var dev = File.new_for_path("/dev/ttyACM0");
var dev_io = dev.open_readwrite();
var dev_o = dev_io.output_stream as FileOutputStream;
dev_o.write({0x13});
dev_o.flush();
My aim is to do this similar to echo -en '\x13' > /dev/ttyACM0 but it just behaves weirdly. The Byte 0x13 seems to be written multiple times, sometimes /dev/ttyACM0 is blocked for a few seconds, sometimes it's even blocked after the Vala program exited and sometimes it's not blocked at all. If i write my FileOutputStream to a file and send this to the serial port via cat byte_file > /dev/ttyACM0 everything is fine.
It seems to me that GIO struggles with the fact that the file is a device. My problem is that I need GIO to monitor /dev/ttyACM0 if it's plugged in and for asynchronous reading.
The problem is most likely that you have to configure the serial port to set things like baud rate, flow control, and parity. If you don't get all those options right there is a good chance that you'll end up with garbage data like you describe.
Basically, you first need an integer descriptor for the file; the easiest way to get one is probably to just open the file using Posix.open, but you can also use GLib.FileStream.fileno to get the integer descriptor of a GLib.FileStream, etc. Next, use Posix.cfmakeraw and Posix.cfsetspeed to configure it. Then, to get your nice GIO streams, just pass the integer descriptor to the default GLib.UnixInputStream/GLib.UnixOutputStream constructors.
I wrote a class to handle serial communication in Vala many years ago. As an example it is a bit horrible—it's convoluted (I had plans to use it as an abstraction layer), doesn't use GIO or async (Vala didn't have the async keyword), uses char[] instead of uint8[] (we hadn't yet standardized on uint8[]), etc., but it should help you understand what you need to do. Between that example and what I wrote above, you should be able to get it working, but if you are still having trouble after you've played with it let me know and I can throw together a quick example.

MBed/Arduino RS-232 Serial communication issue

I am receiving messages from a CAN interface into my mBed device. The mBed device then parses the information to send out on serial to another device. The information is sent out in the following format.
"< msg>xxxxxxxxxxxxxxxxxxx< /msg>" where x = a hex number.
The other device receiving this message will receive the information split up in half (i've accounted for this in the code). The problem I'm having is, the messages will fall into the format ..... but there are times where the format is lost, for example:
[1]xxxx< /msg>< msg>xxxxx
[2]xxxxxxxx< msg>xxxxxxx
[3]< /msg>< msg>xxxxxxxxx
[4]xxx< /msg>< msg>xxxxxx
**Please ignore the space in the msg tag, it was necessary to show on StackOverflow'**
The baud rate set 38400bps on the mBed. I'm not using any parity, stop bit, start bit etc as I'm not too familiar with how they work. Can anyone help me how I might fix this loss in format, or am I going to have to include code in the receiving device to handle this?
Many thanks in advance!
This is entirely normal, serial ports are not smart enough to recognize XML. You will have to write the code yourself. A basic algorithm is a state machine. Declare a buffer that's large enough to store a complete message. Then:
throw everything away you receive until you get '<'
store bytes you receive in the buffer until you get '>'
check that you got <msg>, back to state 1 if you did not
store bytes you receive in the buffer until you get '>'
check that you got <msg/>, back to state 1 if you did not
process the message, back to state 1
This ensures that you'll properly sync with the bus when you open the port and that you don't care how many bytes you receive in one read() call.

Resources