Android Question Strange problem with FelUsbSerial library and 3D Printer controller running Marlin @ 250000 bps

Discussion in 'Android Questions' started by max123, Apr 28, 2018.

  1. max123

    max123 Active Member Licensed User

    Hi all,

    I would like to write a B4A application capable of connecting to USB controllers for 3D Printers, in this regard I did some tests with the FelUsbSerial library, but I have a problem that I can not solve in any way.

    My 3D Printer controller is equipped with a FTDI serial converter and Atmega2560 where the Marlin firmware runs, which by default is set with a baud rate of 250000 bps.

    Connecting to the controller with OTG cable @ 250000 bps, I get strange characters, as if the baud rate was not correct, so I tried to reprogram Arduino with Marlin firmware setting 115200 bps and this works, I tried 230400 and it works too, but 250000 does not want to work and returns always strange characters.

    Can anyone tell me why this happens? Is the 250000 baud rate missing in the library?

    Since in the future I must also use the MIDI protocol to interface with digital musical instruments, this protocol uses 31250 bps, but it is not a standard baud rate, can you tell me if this will work?

    I use B4A, B4J, B4R for many years, but I also use Jabaco to create applications that they run on Raspberry without JavaFX UI, just days ago I developed the same application for 3D printing on Jabaco, in this regard I created a class that use JSSC library and I added to the standard baudrates also 250000 (and others), this works very well and I can connect to the Atmega2560 and command the printer from my pc, even many other users have managed to make various prints.

    Also I added 31250 and I can successfully connect and command various digital MIDI musical instruments.

    I used JSSC because it's the one used in the B4J Serial library, so I like it because I love B4J.

    The JSSC porting I wrote for Jabaco uses the following baud rates:

    110, 150, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 31250, 38400, 57600, 115200,
    128000, 230400, 250000, 256000, 460800, 500000, 512000, 576000, 921600, 1000000, 1152000, 1500000,
    2000000, 2500000, 3000000, 3500000, 4000000.

    I have not tested all them, but all those tested work successfully, even non standard baud rates.

    I would like to convert this printing application to B4A using FelUsbSerial library, but I'm stuck for this problem that I can't solve in any way.

    I would like to ask if it is possible to add these specified above baud rates to the FelUsbSerial library.

    Many thanks.
     
    Last edited: Apr 28, 2018
  2. Erel

    Erel Administrator Staff Member Licensed User

  3. max123

    max123 Active Member Licensed User

    Many thanks Erel for your reply.
    So no way to add more baudrates? Require I compile myself the library?

    Many thanks.
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    I'm not familiar with FTDI protocol and I do not know whether there is a good reason for this baud rate not being supported.
     
  5. max123

    max123 Active Member Licensed User

    FTDI supports all baudrates, is the library that miss some.

    I can control from PC at any baudrate (with my application and all applications for 3D printers like Repetier Host and others).
    Same for all Android apps found on GooglePlay for 3D printing and even simple Serial-USB app loggers.

    I can control from B4J applications Serial library too, at any baudrate.

    It is the same for CH34x serial converter. I'm sure, tried even with ESP8266 NodeMCU and even with B4J on PC.
    I don't have others serial converters but I think works too.

    The B4A library code is opensource? You can send me? If yes I will try to fix the question and recompile it on Eclipse.

    Many thanks for your pecious time.
     
    Last edited: May 1, 2018
  6. Erel

    Erel Administrator Staff Member Licensed User

    You need to find the control command value for the relevant baud rate. If you know it then I can show you how to set it with reflection.
     
    max123 and Peter Simpson like this.
  7. max123

    max123 Active Member Licensed User

    Hi Erel,

    I've found a formula to calculate the control command value for FTDI, in the library code I see that others serial conversters use the same way, but maybe need to adapt.

    Can you show me how to change it with reflection library?

    I think need to bypass some code because in the library there is an Override method that select baudrates intervals, these lines:

    Code:
    @Override
        
    public void setBaudRate(int baudRate)
        {
            int value = 
    0;
            
    if(baudRate >= 0 && baudRate <= 300 )
                value = FTDI_BAUDRATE_300;
            
    else if(baudRate > 300 && baudRate <= 600)
                value = FTDI_BAUDRATE_600;
            
    else if(baudRate > 600 && baudRate <= 1200)
                value = FTDI_BAUDRATE_1200;
            
    else if(baudRate > 1200 && baudRate <= 2400)
                value = FTDI_BAUDRATE_2400;
            
    else if(baudRate > 2400 && baudRate <= 4800)
                value = FTDI_BAUDRATE_4800;
            
    else if(baudRate > 4800 && baudRate <= 9600)
                value = FTDI_BAUDRATE_9600;
            
    else if(baudRate > 9600 && baudRate <=19200)
                value = FTDI_BAUDRATE_19200;
            
    else if(baudRate > 19200 && baudRate <= 38400)
                value = FTDI_BAUDRATE_38400;
            
    else if(baudRate > 19200 && baudRate <= 57600)
                value = FTDI_BAUDRATE_57600;
            
    else if(baudRate > 57600 && baudRate <= 115200)
                value = FTDI_BAUDRATE_115200;
            
    else if(baudRate > 115200 && baudRate <= 230400)
                value = FTDI_BAUDRATE_230400;
            
    else if(baudRate > 230400 && baudRate <= 460800)
                value = FTDI_BAUDRATE_460800;
            
    else if(baudRate > 460800 && baudRate <= 921600)
                value = FTDI_BAUDRATE_921600;
            
    else if(baudRate > 921600)
                value = FTDI_BAUDRATE_921600;
            
    else
                value = FTDI_BAUDRATE_9600;
            setControlCommand(FTDI_SIO_SET_BAUD_RATE, value, 
    0null);
        
    }
     
        private int setControlCommand(int request, int value, int index, byte[] data)
        {
            int dataLength = 0;
            if(data != null)
            {
                dataLength = data.length;
            }   
            int response = connection.controlTransfer(FTDI_REQTYPE_HOST2DEVICE, request, value, mInterface.getId() + 1 + index, data, dataLength, USB_TIMEOUT);
            Log.i(CLASS_ID,"Control Transfer Response: " + String.valueOf(response));
            return response;
        }

    PS: If you need to change felUsbLibrary and add more baudrates, I've attached an explanation and If you want
    I've a PDF file that show it and all explanation related to set any baudrate.

    Many thanks.

    -------------------------------

    Baud Rate Calculation
    A Baud rate for the FT232R, FT2232 (UART mode) or FT232B is generated using the chips
    internal 48MHz clock. This is input to Baud rate generator circuitry where it is then divided by 16
    and fed into a prescaler as a 3MHz reference clock. This 3MHz reference clock is then divided
    down to provide the required Baud rate for the device's on chip UART. The value of the Baud rate
    divisor is an integer plus a sub-integer prescaler. The original FT8U232AM only allowed 3 sub-
    integer prescalers - 0.125, 0.25 or 0.5. The FT232R, FT2232 (UART mode) and FT232B support
    a further 4 additional sub-integer prescalers - 0.375, 0.625, 0.75, and 0.875. Thus, allowed values
    for the Baud rate divisor are:
    Divisor = n + 0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875; where n is an integer between 2 and
    16384 (2 14 ).
    Note: Divisor = 1 and Divisor = 0 are special cases. A divisor of 0 will give 3 MBaud, and a divisor
    of 1 will give 2 MBaud. Sub-integer divisors between 0 and 2 are not allowed.
    Therefore the value of the divisor needed for a given Baud rate is found by dividing 3000000 by the
    required Baud rate.
    The exact Baud rate may not be achievable - however as long as the actual Baud rate used is
    within +/-3% of the required Baud rate then the link should function without errors. When a Baud
    rate is passed to the driver where the exact divisor required is not achievable the closest possible
    Baud rate divisor will be used as long as that divisor gives a Baud rate which is within +/- 3% of the
    Baud rate originally set.
    For example:
    A non-standard Baud rate of 490000 Baud is required.
    Required divisor = 3000000 / 490000 = 6.122
    The closest achievable divisor is 6.125, which gives a baud rate of 489795.9, which is well within
    the allowed +/- 3% margin of error. Therefore 490000 can be passed to the driver and the device
    will communicate without errors.

    Aliasing Baud Rates
    The file FTDIPORT.INF contains entries that are used as the divisors for standard Baud rates. By
    changing these it is possible to alias standard Baud rates with non-standard values - for instance
    replacing 115kBaud with 512kBaud. Users would then set up the FT232R, FT2232 (UART mode)
    or FT232B to operate at 512kBaud by selecting 115kBaud for the appropriate serial port.
     
    Last edited: May 1, 2018
  8. Erel

    Erel Administrator Staff Member Licensed User

    You need to call setControlCommand. You can do it with this code:
    Code:
    Dim r As Reflector
    r.Target = serialdevice
    Dim value As Int = ...
    r.RunMethod4(
    "setControlCommand"Array(3, value, 0Null), _
       
    Array As String("java.lang.int""java.lang.int""java.lang.int""[B"))
     
  9. max123

    max123 Active Member Licensed User

    Many thanks Erel.

    I need to do this before or after I connect?

    If you or any user need reference to set more baudrates, I've attached the FTDI Application Note PDF file that explain how to calculate the "value" of internal clock divisor.

    As explained in the Application Note reference the FTDI driver has a function to pass just a baudrate and set automatically the divisor for any baudrate:
    When using FTDI's D2XX direct driver the function FT_SetBaudRate can be used to set both standard and non-standard baudrates.

    There is a possibility you change the library in future by adding this function (you can find on FTDI driver D2XX) so don't need to use Reflection?

    Many thanks another time for your great support.
     

    Attached Files:

    Last edited: May 2, 2018
  10. Erel

    Erel Administrator Staff Member Licensed User

    You need to call this code instead of setting the BaudRate property. After you initialize the object.

    There is nothing bad with this solution. It might be added in the future.
     
    max123 and Peter Simpson like this.
  11. max123

    max123 Active Member Licensed User

    Ok, very good. As I supposed.

    This is a great notice! I awaiting this!

    Many thanks Erel
     
    Last edited: May 2, 2018
  12. max123

    max123 Active Member Licensed User

    Hi Erel,

    I've tried it and works well on FTDI USB converter.;)

    My calculation for 250000 bps is 3000000/250000 = 12

    Now the problem is that only works on FTDI and no on others serial converters supported by the library.:(

    Tried with CH340 using the NodeMCU for test, but as I supposed the CH340 class do not have the setControlCommand
    method, the calculation for baud rate is not same, it has 2 divisors and because no setControlCommand return an error
    while I try to connect.

    This is a big problem because my app this way only support FTDI devices, no CH340, CP21xx etc...

    There is a solution to do this and work on any serial converter supported by the felUsbSerial library?

    Many thanks
     
    Last edited: May 3, 2018
  13. Erel

    Erel Administrator Staff Member Licensed User

    You will need to understand how each of the chips sets the baud rate and implement it.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice