USB -> ch341 -> RS485? #276

Closed
snakesandstuff opened this Issue Jul 22, 2015 · 9 comments

Comments

Projects
None yet
3 participants
@snakesandstuff
  1. Version: 3.1.2 downloaded and compiled and installed from https://github.com/stephane/libmodbus/archive/master.zip
  2. Run on a raspberry pi (4 core ARMv7)
  3. RTU backend
  4. Debug output:
    pi@modbus ~ $ ./modbus2
    Connected to /dev/ttyUSB0
    Slave set to 0x01
    [01][03][00][00][00][01][84][0A]
    ERROR Bad file descriptor
    Bad file descriptor

The code that is not working and giving the output listed above:
Code being used at: http://pastebin.com/HvUyHcUv

Unit tests in test directory for TCP functions work properly

The following was used to compile the code:
gcc -I/usr/local/include/modbus -L/usr/local/lib -lmodbus modbus2.c -o modbus2

The USB->RS485 adapter works properly when tested by sniffing serial port as well as using modpoll on a Win7 machine.

Additional Information:

dmesg output when adapter is plugged into USB port:
[ 1296.027230] usb 1-1.3: new full-speed USB device number 4 using dwc_otg
[ 1296.130334] usb 1-1.3: New USB device found, idVendor=1a86, idProduct=7523
[ 1296.130359] usb 1-1.3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 1296.130377] usb 1-1.3: Product: USB2.0-Serial
[ 1296.156478] usbcore: registered new interface driver usbserial
[ 1296.156621] usbcore: registered new interface driver usbserial_generic
[ 1296.156740] usbserial: USB Serial support registered for generic
[ 1296.160359] usbcore: registered new interface driver ch341
[ 1296.160514] usbserial: USB Serial support registered for ch341-uart
[ 1296.160620] ch341 1-1.3:1.0: ch341-uart converter detected
[ 1296.164736] usb 1-1.3: ch341-uart converter now attached to ttyUSB0

gcc -v output:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.3-14+rpi1' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.6.3 (Debian 4.6.3-14+rpi1)

Any help/insight is greatly appreciated.

Thank you

@karlp

This comment has been minimized.

Show comment
Hide comment
@karlp

karlp Jul 22, 2015

Contributor

If you really want function code 3, You probably don't actually want register 30005, you probably want read_input_register(4). but that's your world, and maybe it's correct. Either way, that's not what's causing your bad file descriptor problems :)

the ch341 linux driver is wayyyyy buggy. You will continue to have odd pain with it. It "normally" works with no parity and a fixed baud rate, but any opening/closing of ports can leave it in undefined states. You can try hacking around with the vendor driver, and I started some work to clean it up, https://github.com/karlp/linux/commits/ch341-3.18.6 but it's a long road.

Contributor

karlp commented Jul 22, 2015

If you really want function code 3, You probably don't actually want register 30005, you probably want read_input_register(4). but that's your world, and maybe it's correct. Either way, that's not what's causing your bad file descriptor problems :)

the ch341 linux driver is wayyyyy buggy. You will continue to have odd pain with it. It "normally" works with no parity and a fixed baud rate, but any opening/closing of ports can leave it in undefined states. You can try hacking around with the vendor driver, and I started some work to clean it up, https://github.com/karlp/linux/commits/ch341-3.18.6 but it's a long road.

@snakesandstuff

This comment has been minimized.

Show comment
Hide comment
@snakesandstuff

snakesandstuff Jul 22, 2015

Thank you for the response. I did notice that error after I posted, and you
are correct about the addressing.

Have you tested and used libmodbus with a USB->RS485 adapter of any type?
Are the FTDI type better?

Thank you again

On Wed, Jul 22, 2015 at 4:48 AM, Karl Palsson notifications@github.com
wrote:

If you really want function code 3, You probably don't actually want
register 30005, you probably want read_input_register(4). but that's your
world, and maybe it's correct. Either way, that's not what's causing your
bad file descriptor problems :)

the ch341 linux driver is wayyyyy buggy. You will continue to have odd
pain with it. It "normally" works with no parity and a fixed baud rate, but
any opening/closing of ports can leave it in undefined states. You can
try hacking around with the vendor driver, and I started some work to clean
it up, https://github.com/karlp/linux/commits/ch341-3.18.6 but it's a
long road.


Reply to this email directly or view it on GitHub
#276 (comment).

Thank you for the response. I did notice that error after I posted, and you
are correct about the addressing.

Have you tested and used libmodbus with a USB->RS485 adapter of any type?
Are the FTDI type better?

Thank you again

On Wed, Jul 22, 2015 at 4:48 AM, Karl Palsson notifications@github.com
wrote:

If you really want function code 3, You probably don't actually want
register 30005, you probably want read_input_register(4). but that's your
world, and maybe it's correct. Either way, that's not what's causing your
bad file descriptor problems :)

the ch341 linux driver is wayyyyy buggy. You will continue to have odd
pain with it. It "normally" works with no parity and a fixed baud rate, but
any opening/closing of ports can leave it in undefined states. You can
try hacking around with the vendor driver, and I started some work to clean
it up, https://github.com/karlp/linux/commits/ch341-3.18.6 but it's a
long road.


Reply to this email directly or view it on GitHub
#276 (comment).

@karlp

This comment has been minimized.

Show comment
Hide comment
@karlp

karlp Jul 22, 2015

Contributor

Well, these ones work pretty well http://www.ftdichip.com/Products/Cables/USBRS485.htm and come cabled up. I'm sure you can get others in different form factors. cp210x devices would work fine too, and probably pl2303, but ftdi and cp210x are the ones I know will work.

Contributor

karlp commented Jul 22, 2015

Well, these ones work pretty well http://www.ftdichip.com/Products/Cables/USBRS485.htm and come cabled up. I'm sure you can get others in different form factors. cp210x devices would work fine too, and probably pl2303, but ftdi and cp210x are the ones I know will work.

@karlp

This comment has been minimized.

Show comment
Hide comment
@snakesandstuff

This comment has been minimized.

Show comment
Hide comment
@snakesandstuff

snakesandstuff Jul 22, 2015

You are correct. I have one of the ftdi's on order now. I think in the mean time (while waiting on delivery) I will play around and see exactly where in the code the error is coming from and see if it is perhaps with trying to set RTS or something else using ioctl that the ch341 doesn't understand.

I have tested the ch341 under this environment with simple send and receive using echo "Test" > /dev/ttyUSB0 and listening for test messages from another device with cat /dev/ttyUSB0

You are correct. I have one of the ftdi's on order now. I think in the mean time (while waiting on delivery) I will play around and see exactly where in the code the error is coming from and see if it is perhaps with trying to set RTS or something else using ioctl that the ch341 doesn't understand.

I have tested the ch341 under this environment with simple send and receive using echo "Test" > /dev/ttyUSB0 and listening for test messages from another device with cat /dev/ttyUSB0

@karlp

This comment has been minimized.

Show comment
Hide comment
@karlp

karlp Jul 22, 2015

Contributor

Yeah, unless you realllly know that are using the RTS pin explicitly for rs485 driver enable, just don't use that part of libmodbus. Likewise for things like "set rs485 mode" that stuff only does what you want if you have a serial port that the kernel itself understands rs485 mode for. With transparent devices like the ftdi cables and those ch34x dongles, there's no rts signal being used. FTDI has a native DE pin, and the ch340 dongle I have uses nand gates to do an "auto" mode switch, based on an old circuit cellar article. In no case do you even tell libmodbus about any of that.

Contributor

karlp commented Jul 22, 2015

Yeah, unless you realllly know that are using the RTS pin explicitly for rs485 driver enable, just don't use that part of libmodbus. Likewise for things like "set rs485 mode" that stuff only does what you want if you have a serial port that the kernel itself understands rs485 mode for. With transparent devices like the ftdi cables and those ch34x dongles, there's no rts signal being used. FTDI has a native DE pin, and the ch340 dongle I have uses nand gates to do an "auto" mode switch, based on an old circuit cellar article. In no case do you even tell libmodbus about any of that.

@snakesandstuff

This comment has been minimized.

Show comment
Hide comment
@snakesandstuff

snakesandstuff Jul 22, 2015

I feel completely silly... In my code I never used a modbus_connect, so the file descriptor was never being set properly... Just posting in case someone else has a similar problem.

I feel completely silly... In my code I never used a modbus_connect, so the file descriptor was never being set properly... Just posting in case someone else has a similar problem.

@karlp

This comment has been minimized.

Show comment
Hide comment
@karlp

karlp Jul 22, 2015

Contributor

I didn't notice that either, and honestly, I feel that libmodbus should provide a better error message in that case. @stephane opinions?

Contributor

karlp commented Jul 22, 2015

I didn't notice that either, and honestly, I feel that libmodbus should provide a better error message in that case. @stephane opinions?

@stephane

This comment has been minimized.

Show comment
Hide comment
@stephane

stephane Aug 4, 2015

Owner

When I was reading the comments of the issue, I found funny you don't talk about the missing connect() call. Hopefully, you found it not too long after you open the issue ;)

I just looked at source code to help the user about this mistake but I don't find a good place to handle that so I edited the documentation to avoid this mistake.

Owner

stephane commented Aug 4, 2015

When I was reading the comments of the issue, I found funny you don't talk about the missing connect() call. Hopefully, you found it not too long after you open the issue ;)

I just looked at source code to help the user about this mistake but I don't find a good place to handle that so I edited the documentation to avoid this mistake.

@stephane stephane closed this Aug 4, 2015

georgidimov added a commit to georgidimov/libmodbus that referenced this issue Jul 24, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment