I have a BeagleBone Black with a “Serial Cape” (http://www.logicsupply.com/eu-en/cbb-serial/). This cape supports RS-485 which i’m interested in. Before i had this cape, i used a RS-485-to-USB-converter.
I try to read some data from an external device. It’s very simple: The request is just “/?!\r\n” and then i get the data.
With the RS485-to-USB-Stick i used this serial port configuration (with ser2net):
/dev/ttyUSB0 9600 7DATABITS EVEN 1STOPBIT
With the cape i tried this configuration:
/dev/ttyO4 9600 7DATABITS EVEN 1STOPBIT
Unfortunately this first try didn’t work. I didn’t get any response. I also tried this configuration:
/dev/ttyO4 9600 7DATABITS EVEN 1STOPBIT RTSCTS
I set the jumpers on the cape like this:
J7: UART4 RTS
The RS485+ wire is connected to the RS485B port, and the RS485- wire is connected to the RS485A port.
To get a better overview i made a photo:
At the bottom of the picture there is the RS485-to-USB converter. It just has two ports which i used to connect the RS485 wires.
I think the board itself should work, because if i execute “cat /sys/devices/bone_capemgr.*/slots” i can see it.
Do i do something wrong? Maybe someone else has used this cape with RS485? I thought it should be almost as easy as with the USB converter?
Thank you for any help
The BeagleBone’s omap-serial driver doesn’t support RS-485 DE/RE control with the RTS flow control signal. Instead it has an RS-485 mode using a GPIO pin for DE/RE control, and has a modified serial_rs485 struct from the standard serial driver. You have to use ioctl on the corresponding /dev/ttyOx file to put the serial driver in RS-485 mode and tell it which pin to use, and you also have to take care of muxing the pin to GPIO mode.
So with the jumper in the RTS position that would be the GPIO signal that shares the pin with the UART4 RTS signal, so that’s GPIO0_9 on P8.33. Or you can put it to the GPIO1_16 position and use GPIO1_16 instead. (I believe GPIO1_16
There’s a tutorial here: http://inspire.logicsupply.com/2014/09/beaglebone-rs-485-communication.html
Also, I believe RS485B is the inverting output, so you have your +/- swapped.
Thank you very much for the input. Now it works:)
I switched the wires and i played around with the tutorial.
I use now this script:
import serial, fcntl, struct, time
ser = serial.Serial(
Standard Linux RS485 ioctl:
TIOCSRS485 = 0x542F
define serial_rs485 struct per Michael Musset’s patch that adds gpio RE/DE
SER_RS485_ENABLED = (1 << 0)
SER_RS485_RTS_ON_SEND = (1 << 1)
SER_RS485_RTS_AFTER_SEND = (1 << 2)
SER_RS485_RTS_BEFORE_SEND = (1 << 3)
SER_RS485_USE_GPIO = (1 << 5)
Enable RS485 mode using a GPIO pin to control RE/DE:
RS485_FLAGS = SER_RS485_ENABLED | SER_RS485_USE_GPIO
With this configuration the GPIO pin will be high when transmitting and low
If SER_RS485_RTS_ON_SEND and SER_RS485_RTS_AFTER_SEND flags are included the
RE/DE signal will be inverted, i.e. low while transmitting
The GPIO pin to use, using the Kernel numbering:
RS485_RTS_GPIO_PIN = 48 # GPIO1_16 → GPIO(1)_(16) = (1)*32+(16) = 48
Pack the config into 8 consecutive unsigned 32-bit values:
(per struct serial_rs485 in patched serial.h)
serial_rs485 = struct.pack(‘IIIIIIII’,
RS485_FLAGS, # config flags
0, # delay in us before send
0, # delay in us after send
RS485_RTS_GPIO_PIN, # the pin number used for DE/RE
0, 0, 0, 0 # padding - space for more values
Apply the ioctl to the open ttyO4 file descriptor:
fcntl.ioctl(fd, TIOCSRS485, serial_rs485)
Send some bytes:
GPIO1_16 should be low here
GPIO1_16 should be high while this is being transmitted:
line = ser.readline();
print("Received: " + line)
count = count + 1
for line in ser.readline():
print(str(count) + str(’: ') + chr(line) )
count = count+1
GPIO1_16 should be low again after transmitting
I have a new problem. I use now a script to read the data from the external device (see my post before: http://beagleboard.org/Community/Forums?place=msg%2Fbeagleboard%2FpfRLpoOEv9M%2Fj4LJHPGOJgAJ ). This script is just a copy of the script in the linked tutorial. I just changed the baudrate, data bits and the input/output strings.
This script works, but only sometimes. Unfortunately it doesn’t work always. I think it works with a success rate of 20%. In the other 80% there is just no output from the external device, which means it didn’t receive the request string “/?!\r\n”.
Has anyone an idea why? I also did a dirty-patch for ser2net to use this GPIO-thing, but also with ser2net i only have a success rate of +/- 20%.
The externel device works without any problems, because if i use the RS485<->USB-converter every data readout is successful.
Is there another trick with this GPIO-thing? In the tutorial i did not find any other problem sources.
Thank you &