New seroutils and JSSC problem
-
Hi, I used Modbus4J for many time, no problem with "old" version still on sourceforge (based on RXTX library), tested hundreds of devices at different speeds, all is ok.
Just tried to upgrade to 2.0.4 with JSSC and found some problems so I did some tests with a Seneca Z-4AI analog input module using Modbus RTU over RS485 and a Trycom TRP-C08 USB to serial converter (PL2303 chipset) with latest 1.10 prolific drivers in Windows 7 64 bit. This is a setup I used really hundreds of times.
Most of the time this device didn't answer to my requests, same with a Socomec Diris A10, so I turned on my oscilloscope and captured waveforms on serial line.9600 bps, original code (5 ms scale), no response from device:
[url=http://postimg.org/image/cuswdaplp/]
As you can see there's a lot of space between bits, consider that scale is 5x times than following image.9600 bps, StreamTransport insted of StreamTransportCharSpaced (1 ms scale), response OK:
[url=http://postimg.org/image/idee3p6dz/]
Spacing is ok and device answered to my request.Now testing at higher speeds begins.
38400 bps, original code (1 ms scale), no response from device:
[url=http://postimg.org/image/rzfmkyzjt/]
Still too much space between bits.38400 bps, StreamTransport insted of StreamTransportCharSpaced (1 ms scale), no response from device:
[url=http://postimg.org/image/75h96q8t9/]
Still too much space between bits.Looks like there's another problem.... I investigated and found that StreamTransport use write(byte[]) method of OutputStream but JsscSerialPortOutputStream doesn't override that method, so we are using OutputStream class method. Just created this method in JsscSerialPortOutputStream to be able to write complete buffer instead of one byte at a time (like StreamTransportCharSpaced do):
@Override public void write(byte[] b) throws IOException { try { if (LOG.isDebugEnabled()) { LOG.debug("Writing bytes: " + StreamUtils.dumpHex(b, 0, b.length)); } if ((port != null) && (port.isOpened())) { port.writeBytes(b); } } catch (jssc.SerialPortException e) { throw new IOException(e); } }
and result was OK ->
38400 bps, StreamTransport insted of StreamTransportCharSpaced, buffered write (200 us scale), response OK:
[url=http://postimg.org/image/91tx95dh5/]
Spacing is ok and device answered to my request.Maybe at higher speeds we need to use internal UART buffer and writing all data in the same request is needed instead of writing byte by byte..
What do you think about these tests? Have you found any problem communicating with devices with the new version of Modbus4J?
Edit: Same tests as above with a Moschip 7840 based USB to serial converter shows same results.
-
Just left out one last thing: at 38400bps I have many NPEs in JsscSerialPortInputStream:
byte[] buffer = this.port.readBytes(); for (byte element : buffer) { this.dataStream.put(element); }
Because buffer is null and, as stated in Javadoc for readBytes() method: If input buffer is empty null will be returned, else byte array with all data from port
So it would be better to check for null before cycling elements in buffer or early checking event.getEventValue() because in case of NPE is 0 (means 0 byte in buffer).At least this is what I have with my PL2303 converter!
Edit: Testing with a Moschip 7840 based USB to serial converter doesn't generate NPE. Buffer isn't empty when there's an RX char event.
-
pentavalle,
Thanks for your help. We have only heard of problems with the new version on lower baud rates, that is why the StreamTransportCharSpaced was created to ensure space between the Characters as they are written. From a Java code perspective we do not have control of the spacing between bits which leads me to believe this could be a platform/hardware issue. I would be interested to see some scope images from a Linux based system and find out if the problem exists there too.
All of your code changes make sense to me from the images you posted, I will take a closer look and do some testing as soon as I can get access to an oscilloscope. If you have any way of testing your changes with a Linux or OSX machine it would be greatly appreciated as it may be a few weeks before I can get an oscilloscope. I will also take a look into the native code for JSSC and try and determine how this bit-to-bit delay is possible.
As for your other comment:
Because buffer is null and, as stated in Javadoc for readBytes() method: If input buffer is empty null will be returned, else byte array with all data from port
So it would be better to check for null before cycling elements in buffer or early checking event.getEventValue() because in case of NPE is 0 (means 0 byte in buffer).I have not seen this happen but it also appears to be an oversight in our code. I will add this change to the library.
Thanks Again,
Terry -
Here they are!
Same device, same USB converter, Ubuntu 13.10.9600 bps, original code, response OK:
[url=http://postimg.org/image/537j754y7/]9600 bps, StreamTransport instead of StreamTransportCharSpaced, response OK:
[url=http://postimg.org/image/tpifzy34x/]9600 bps, StreamTransport insted of StreamTransportCharSpaced, buffered write, response OK:
[url=http://postimg.org/image/5yofzhjfr/]38400 bps, original code, no response from device:
[url=http://postimg.org/image/euz83fa1z/]38400 bps, StreamTransport insted of StreamTransportCharSpaced, response OK:
[url=http://postimg.org/image/oqfn1doaz/]38400 bps, StreamTransport insted of StreamTransportCharSpaced, buffered write, response OK:
[url=http://postimg.org/image/5t64gnlz7/]Edit: test machine was an Intel N2600, previous tests on Windows were on a Intel Core I5 3230M
For the NPE consider I had that only with PL2303 chip, that receives packets in chunks, not all in one.
Just a question: why did you decide to use JSSC insted of, for example, nrjavaserial? nrjavaserial is compatible with javax.comm, while JSSC is completely different, so a port was necessary.
-
Thanks for testing that!
I will make the changes and get them into the next release, I will be getting a scope soon to do my own testing.
We chose JSSC because it was different from RxTx and we had been having some issues with RxTx. We found no issues with JSSC so we choose to go with it. Thanks for the heads up on nrjavaserial, I wasn't aware of it. But since it is based on the RXTX core I am doubtful that we will go back to something like that.
Cheers,
Terry -
Hi Terrypacker,
I would like to introduce you to scm which is an alternative library to rxtx/javaxcom.
Wiki : http://www.embeddedunveiled.com/
Repository : https://github.com/RishiGupta12/serial-communication-manager
Video : https://www.youtube.com/watch?v=fYLQbelGunQIt supports RS-232 control signals handshaking, monitoring and has been ported to Linux, MAC, Solaris and Windows operating system. It is consistent, portable, efficient, reliable, testable, extensible, modifiable, scalable library.