RS485 via USB: "bad file descriptor"

580 views
Skip to first unread message

Denis Papathanasiou

unread,
Aug 13, 2014, 1:38:51 PM8/13/14
to libm...@googlegroups.com
I saw the prior thread about using libmodbus with RS485 over USB[1] and wanted to share my own experience. 

I'd also be happy to volunteer my help to resolve it, to the extent I can (but it seems related to low-level stuff beyond my experience/capability).

I have some smart meters which support modbus function code 0x03 (read holding registers) daisy-chained together using RS485 twisted pair wire.

I'm using an RS485 to USB adaptor to connect to my computer. The adaptor uses the FTDI driver for USB, which is already installed on my computer (I'm using the latest version of debian linux).

When I plug it in, it is automatically recognized, and maps to /dev/ttyUSB0:

root@debian-thinkpad-i7:~# dmesg | tail
[ 1975.854760] USB Serial support registered for FTDI USB Serial Device
[ 1975.854844] ftdi_sio 1-1:1.0: FTDI USB Serial Device converter detected
[ 1975.854882] usb 1-1: Detected FT232RL
[ 1975.854883] usb 1-1: Number of endpoints 2
[ 1975.854885] usb 1-1: Endpoint 1 MaxPacketSize 64
[ 1975.854886] usb 1-1: Endpoint 2 MaxPacketSize 64
[ 1975.854887] usb 1-1: Setting MaxPacketSize 64
[ 1975.855217] usb 1-1: FTDI USB Serial Device converter now attached to ttyUSB0
[ 1975.855247] usbcore: registered new interface driver ftdi_sio
[ 1975.855250] ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver

By default, the permissions look like this:

root@debian-thinkpad-i7:~# ls -ltr /dev/ttyUSB0
crw-rw---T 1 root dialout 188, 0 Aug 12 14:12 /dev/ttyUSB0

I wrote a simple program using libmodbus[2] to access two bytes of the first map address.

When it runs, I get this output:

Connected to /dev/ttyUSB0
Slave set to 0x01
[01][03][0B][D5][00][02][D7][D7]
ERROR Bad file descriptor
Bad file descriptor

Normally, the 'bad file descriptor' error means a permission problem, but even when I try all the usual remedies (i.e., add 'dialout' to my user groups, chmod 666/777 /dev/ttyUSB0, etc.) the error does not change.

Next, using the same exact hardware and computer, I wrote some homebrew code in Go[3] which worked, even when the default permissions on /dev/ttyUSB0 are *not* changed after plugging in the USB adaptor:

$ ./rtu-client -serial /dev/ttyUSB0 -start 3029 -bytes 2 -slave 1
2014/08/13 12:01:56 Tx: 01030bd50002d7d7
2014/08/13 12:01:56 Rx: 0103040000001a7bf8

The interesting thing is that even my homebrew code was failing with the 'bad file descriptor' error at first, when I tried reading and writing to /dev/ttyUSB0 as if it were like any other unix file[4].

But then I found the goserial library[5], and when I switched to using that instead[6], suddenly, it worked as it was supposed to.

I haven't looked deeply in what goserial is doing differently than my original USB access attempt, but it might hold the clue for what to do in general, and for libmodbus as well.

Stéphane Raimbault

unread,
Sep 25, 2014, 5:55:57 AM9/25/14
to libm...@googlegroups.com
Hi Denis,

Thank you for sharing this.

In your set up, it seems your PC is connected to an USB device (FTDI) not RS485.

Did you try to run your libmodbus code as root (to check permission issue)?

In your code:
ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
so it's identical to goserial defaults.

The setup of goserial is very light, I saw a few differences:

vs

- O_NONBLOCK (only in goserial)
- O_EXCL and 0_NDELAYflags on open (only libmodbus)
- VMIN is set to 1 in Go code whereas we use 0 because of NDELAY flag in libmodbus
- the way to disable parity is slightly different (IGNPAR in Go)

Could you apply all these changes to libmodbus by editing modbus-rtu.c and see if your connection works?
Then you could revert changes one by one to find the important ones?


Stéphane


--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "libmodbus".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse libmodbus+...@googlegroups.com.
Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages