B4J Question Serial port at 3MBauds

Didier9

Well-Known Member
Licensed User
Longtime User
I am trying to use a CAN adapter that has a built-in FTDI chip running the serial port at 3,000,000 Bauds.
That is a weird Baud rate but apparently, the FTDI chip supports it. The CAN adapter came with a piece of software to apparently "enable" the 3,000,000 Baud rate in the driver.
When I open the port in putty and set the Baud Rate to 3000000, it decodes the messages just fine.
When I try to do the same thing in B4J (using the Oracle JDK), setting the Baud Rate to 3000000, I get garbage characters. It looks as if the Baud rate was wrong.
Interestingly, in order to receive anything, the CAN adapter has to be enabled, and that's done through serial commands, so since I get stuff from the adapter, it has to receive the "open" command. Therefore it would appear the transmission (from the PC to the device) actually occurs at the specified baud rate but the reception (device to PC) is corrupted or at the wrong rate.

The SetParms method of the SerialPort object takes an Int as a parameter, so I am not even sure how that could possibly work, but I get no error when feeding it a parameter of 3000000...

An alternative would be to use a dll they provide and which I tested under VB 6.0. It alleviates the problem because the dll communicates with the COM port "directly".
I am not sure if I can use a dll from B4J.

Looks like it's going to be a long road...
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

Didier9

Well-Known Member
Licensed User
Longtime User
Thank you Erel, how about the data type?
The speed parameter is defined as an Int, which implies a max value of 32767, or 65535 if unsigned. How does it work even when passing a value of 115200?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
The speed parameter is defined as an Int, which implies a max value of 32767, or 65535 if unsigned.
??
In C, the integer (for 32 bit machine) is 32 bits, and it ranges from -32,768 to +32,767.

In Java, the integer(long) is also 32 bits, but ranges from -2,147,483,648 to +2,147,483,647.

 
Upvote 0

Didier9

Well-Known Member
Licensed User
Longtime User
Don,
I was referring to this post about data types, but I realize it is for B4R. I assumed they were the same with B4J:

The following data types are available in B4R:

Numeric types:

Byte: 0 - 255
Int (2 bytes): -32768 - 32768. Similar to Short type in other B4X tools.
UInt (2 bytes): 0 - 65535.
Long (4 bytes): -2,147,483,648 - 2,147,483,647. Similar to Int type in other B4X tools.
ULong (4 bytes): 0 - 4,294,967,295
Double (4 bytes): 4 bytes floating point. Similar to Float in other B4X tools.
Float is the same as Double. Short is the same as Int.

Note that signed 16 bit variables range from -32768 to +32767, not 32 bit variables.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The list of supported baud rates: https://github.com/java-native/jssc/blob/master/src/main/java/jssc/SerialPort.java (same as the constants in the wrapper).
The behavior of any other library is undefined. The Java code just calls the underlying native (C++) code. You will need to do some digging to understand whether it can be modified to support such high rate
If we're talking Windows, those are just some of the pre-defined baud rates. The documentation (https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb) states:
The baud rate at which the communications device operates. This member can be an actual baud rate value, or one of the following indexes.
So I don't think that is the issue.
In C, the integer (for 32 bit machine) is 32 bits, and it ranges from -32,768 to +32,767.

In Java, the integer(long) is also 32 bits, but ranges from -2,147,483,648 to +2,147,483,647.
The library actually uses a typedef of jint
B4X:
typedef int32_t  jint;     /* signed 32 bits */
and the underlying Windows definition for the baud rate is
B4X:
DWORD BaudRate;
So we're in 32bit territory all the way down.
Interestingly, in order to receive anything, the CAN adapter has to be enabled, and that's done through serial commands, so since I get stuff from the adapter, it has to receive the "open" command. Therefore it would appear the transmission (from the PC to the device) actually occurs at the specified baud rate but the reception (device to PC) is corrupted or at the wrong rate.
Are you sure you are getting garbage? Could it just be an encoding issue (maybe ASCII is being incorrectly converted to UTF or something like that).
 
Upvote 0

Didier9

Well-Known Member
Licensed User
Longtime User
If we're talking Windows, those are just some of the pre-defined baud rates. The documentation (https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb) states: So I don't think that is the issue.

The library actually uses a typedef of jint
B4X:
typedef int32_t  jint;     /* signed 32 bits */
and the underlying Windows definition for the baud rate is
B4X:
DWORD BaudRate;
So we're in 32bit territory all the way down.
Good, thanks!

Are you sure you are getting garbage? Could it just be an encoding issue (maybe ASCII is being incorrectly converted to UTF or something like that).
It's possible, but the data is straight ASCII. Putty has no issue and I am using the same B4J code that works with a different version of the CAN Adapter running essentially the same firmware internally, but at a "normal" baud rate. It is also weird that the device actually receives the commands that sets the CAN bit rate and turns the CAN transceiver on, so whatever the issue is, it does not seem to affect the data from the PC to the device.

I have a couple more things I want to check so I will report when I am done with those.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Looking at the source of jSerial, it has a ReadingThreadInterval variable that is set to read the COM port every 10 milliseconds. Is this too long of a wait for such a high baud rate?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
You can use JavaObject to modify ReadingThreadInterval
B4X:
Dim js As Serial
js.Initialize("COM1")
Dim jo As JavaObject = js
jo.SetField("ReadingThreadInterval", 1)
Leaving the above for prosperity. ReadingThreadInterval is exposed in the Serial library. Mea Culpa
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
This may be more constructive than the previous post:

At this high baud rate, at 10 bits/baud you are looking at 3000 bytes per 10 milliseconds and at 12 bits/baud you are looking at 2500 bytes per 10 milliseconds. If your buffer used for your InputStream is not big enough, then you will lose information (which may look like corruption). In the jSerial source, the amount of data returned is the lesser of the actual amount of data returned by the serial port or the amount of data requested (the MaxCount of an InputStream's ReadBytes method).
 
Upvote 0

Didier9

Well-Known Member
Licensed User
Longtime User
Looking at the source of jSerial, it has a ReadingThreadInterval variable that is set to read the COM port every 10 milliseconds. Is this too long of a wait for such a high baud rate?
There is not a lot of data at the moment, a message every 125mS, each message is 20 characters long. At least at the moment, obviously under other circumstances there could be much more data.
 
Upvote 0
Top