A20-OLinuXino & MOD-RS485 or MOD-RS485-ISO ... for Modbus via Python

Started by gebka, March 17, 2014, 12:27:12 PM

Previous topic - Next topic

gebka

Hi everybody,

I am looking for advice if the A20-OLinuXino-MICRO-4GB in combination with MOD-RS485 or MOD-RS485-ISO could be used for our project.

1. We need a embedded Linux Board with a RS-485 Interface that can be used for Modbus RTU with at least 115200 baud (bit/s)

2. Most part of our software is already writen in Python 2.7.6 and is built upon Twisted and has hooks for using pymodbus and modbus_tk for Mobus RTU (whereby Modbus TCP via pymodbus ist running fine already)

So my question is : is it possible to use the A20-OLinuXino-MICRO-4GB with one of the 2 MOD-RS485 to do Mobuds RTU over RS-485 and if so - are there any "special things" to know or todo ?

I already did a quick search in the forms and found a hint that some I2C Commands are in the game in order to set up the RS-486 Modules ... but that's all implicit - is there an explicit documentation, or example code how to use the UEXT MOD-RS485 or MOD-RS485-ISO from python 2.7
(?) what kind of I2C setup has to be done - which Byte-Constants / Commands do the right job ?
(?) after (the right ;)) setup : are the UEXT connected MOD-RS485 or MOD-RS485-ISO avialable on "UART6 - /dev/ttyS1 " or UART7 - /dev/ttyS2, so that I can use/access them easily with the serial-port class in Python ?

And last but not least I am a little bit confused that both modules are not listed in the A20 Wiki (https://www.olimex.com/wiki/A20-OLinuXino-MICRO) in the section "Linux -> Tested board peripherals with this image".

Thanking you in anticipation ... thanks for your time & help
gebka

dave-at-axon

I've not done Modbus on the A20 as yet, as I am still waiting for the PCB's to arrive that have the RS485 drivers on them. I'll be doing this under Android but there is an issue you should know about as I read about this looking at how to drive the RS485 bus from Android.

The MODS-RS485 is connected via the UART. There is no I2C requirement for it. You do need to use a GPIO pin to control the transmit of the RS485 IC. This is the bit you are going to have issues with unless Python gives you better access to the registers that Linux does not. This I have a feeling is not the case.

When you transmit on RS485, you need to enable the transmit driver via this GPIO pin, transmit your byte, wait for the last byte to go out and then switch the GPIO back to receive. If you switch back before the transmit is complete, your data will appear corrupted by the receiving device. If you switch back too late, the receiving device may have already started sending so you will have missed the start of the transmission.

The issue I read with Linux is that there is no access to the transmit empty buffer of the processor. There is a status for the next byte, but this only refers to the transmit holding buffer.

The way around this and this is how I have achieved this with my design, is to use one of the auto transmit enable devices from Maxim but they are 5V only devices. The issue for you is that to connect to the UEXT connector there is no 5V, only 3.3V and they won't work with that. I use 5V from the GPIO connector and level shifters from the 3.3V UART outputs.

I can't make out much from the ISO version, but it would appear to control the TX/RX via the PIC processor so this may be a better option for you if you need an off the shelf solution. As is the case with a lot of Olimex boards, the documentation on this board leaves a lot to be desired. For example, there is no reference in the manual what the I2C connection s used for. You have to dig around in the source to work it out :)


gebka

thanks for your info Dave

I also got a feedback from Olimex via email, as I asked the question first that way, and that what I took out of it was, that if I use the UEXT MOD-RS485 the "normal way" (under Linux) I have to use I2C for the data communication ... and that's a no-go for me as the Python Modbus RTU Libraries all use some kind of serial-port and I don't have the time and don't want to implemtent a I2C to Serial-Port bridge in Python - the effort I can spend on that project is "short in time". I have to focus on the application logic implementation and do not have the time to program some basic stuff ... maybe interesting but timely impossible ;)

But the "Maxim solution" you notice seems to be interessting for me ... to be honest for the company I work for and not me, because I am a "pure" software developer and my knowledged about electronics and circuits is curiosity but not professional know how or practical experience ;-) ... but we have an electronics engenieer at our hands who could design & build such a circuit. Do vou have some detail infos about that circuit and the Linux driver / configuration part that is need for "that way". It would be great if this could be a general solution in the sense of that if we need to apply this to another board it will work as well - as far as the linux / distribution has some kind of affinity.

The other thing that I think about : why not use one of the "USB to RS-485" Adpater that you can buy all over the internet and claim to have a Linux driver. I come from the "world of windows" (not warcraft ;-) and so my knowledge about the linux driver happiness is quite small. But at least I noticed that one must be aware of the Kernel Version and the conifguration of the hardware interface (even the UART) can be different from distribution to distribution (as I experienced with the Raspberry Pi and the BeagleBone Black).
By the way : there is a Extension Board with a RS-485 for the raspberry Pi that looks great, but I would like to use the A20 OlinuXino because of some extra feature is has, e.g. the Battery connetor + IC for loading + Linux integration and the SATA Interface.
Do you have some experience with a "USB to RS-485" Adapert ?

Thanks for you help
gebka

dave-at-axon

It's good to know that even Olimex don't know how their boards work  ;D

The MOD-RS485 DOES NOT USE I2C. It does use the GPIO pins that the I2C is connected to. These are default link selected to drive the TX and RX lines of the RS485 IC. You do not need to use I2C communications but you do need to be able to them to swap between transmit and receive. The standard off the shel configuration needs both to the used at the same time if you want to avoid seeing your own transmission. You could fit the missing R3 resistor and remove the link from SCL and only then use SDA as the source for transmit and receive.

It's also link selectable to use SCK and #SS from the SPI port, which is more likely to be unused.

As I said, the issue in Linux is knowing when the transmit buffer is empty.

If your electronics guys can get 5V and do the level shifting, get them to look at the MAX13487. With this, all you need to worry about it sending and receiving half duplex RS485.

oskaratk

Dave,

hey you are throwing quite a monkey wrench my way ..
I wanted to use the A20 and RS485 to interface a Morningstar Tristar ... :-(

dave-at-axon

:)

I looked at the Morningstare website and the Tristar is RS232 as standard, according to the data I could find.

You'd really only need RS485 if the cable run was long and you needed to support multiple devices on the same bus.

Which model are you using?

oskaratk

Dave,

initially I wanted to use 1 Tristar (TS-45) as charge controller and another one as load controller. However,design has changed .. just using a solid state relay to drop load if necessary ( battery bank low). I am just dealing with 24V/10A max here ..
Means I can get away with 1 Tristar and RS232.. wire is maybe 10 feet.
OTOH, I have the RS485-ISO as well to play with

Oskar

gebka

@Dave - thanks for the info !

... but what about the easiest way? Has someone experiences with a USB to RS-485 Adpater, maybe woth a FTDI Chipset, as their driver support is broad?

For example with a FT232R Chipset as seen here : http://www.ftdichip.com/Products/Cables/USBRS485.htm

In their datasheet they claim to support Linux 2.4 or greater ... but as I am new on planet Linux, is the Kernel version really everything to take into account and how reliable is "greater than 2.4"? As I rember the OLinuXino is based on the 3.4+ Kernel ... things might be chagned with a major version?

have a great day
gebka

dave-at-axon

If you want something that just works and your project is of a commercial nature, I would suggest using an RS232 port with a KK Systems K2-ADE as this will handle the auto transmit so you simple write your code to send and receive. No need for RTS or GPIO control.

If you are designing a custom board for the Olinuxino then I would use one of the Maxim auto transmit devices.

Trying to control GPIO under Linux or Android and trying to monitor the transmit buffer is just now worth the hassle.

mikenycz

Hi Dave,
    I was looking at the datasheet for the MAX13487 and it looks like the min. input up level is 2v. So shouldn't the 3.3v uart be able to drive the MAX13487 chip? This assumes that you have a 5V supply for the chip itself. I am running into the direction control issues that are being discussed. When I drive the /RE and DE pins high I can send data from the Olimex board with no problems. When I try to set the pins low to receive it seems to lock up the uart. I was running the minicom program and that just locked up hard (i.e. kill the window) and after that I get a message of "ttyS0 locked" when I try to do anything with the uart. If I want the uart to receive, setting the direction of the MOD-RS485 should be all I need to do, correct? I am not trying to go fast here. I just want to see data transfer in both directions (at the moment).

Mike Nycz

dave-at-axon

Hi Mike,

How are you controlling the GPIO? I am wondering if you have any delay when switching them both that this could cause the receive line to go LOW before any data is received.

I normally have pullups on the RXD line because when there is no connection on the RS485 bus, the line goes LOW and the UART interprets this as a receive. On most UARTS they go nuts with this sort of situation.

Try setting it so that you enable the receiver first, then switch the transmitter off.

The other option is to use only 1 GPIO to control them both at the same time. This is normally what I do for RS485 as I normally don't need to see the transmission unless you are looking for bus collisions but as you should really only have 1 master this should not be the issue.

Put a wire link across R3 and this will join #RE and DE together. Cut the link for either #SS or SCK depending on which one you want to use.

See if this configuration now works.

MAX13487
The issue you pointed out is not the drive input to the device as it will work with 3.3V into the transmit line, it is the receive output that is the issue. You CANNOT connect anything with 5V output to the A20 or any of the Olinuxino boards as the GPIO pins are not 5V tolerant. This is why I have level shifting fitted here.

mikenycz

Hi Dave,
     I am echoing values to the gpios to control them. The first thing I tried was to set /RE low first before bringing down DE. This had no effect.
     I then tried what you suggested and put a pull up on the RX line. This sort of worked! I am now able to send data to the A13 through the UART receive. The only thing that is still quirky is that it took awhile (seconds) before it started to work. When I set it up I started typing on the terminal and no data was transferring. After about 10 or so characters the data started to come through. Once it started sending data it just keeps going. But this delay should not be happening (at least I assume so). I am using a 1k resistor as a pull up. If you can suggest a better value then maybe that might make a difference with the delay that I am seeing.
     Another thing that I noticed was that the A/B lines on the RS485 buss are switching above ground. The swing is good (3+ volts) and the signals are complement of each other. One of my colleagues said that he thought the RS485 A/B lines should be switching around ground. I don't know if this is a problem or not but if you know for sure please post here.

Thank you,
Mike Nycz

OK, I was playing a little with this... If I type one character at a time in the terminal the receive does not work. If I quickly type 3 characters in a row (3 in 1 second or so) and do this repeatedly for 2 or three times, the receive starts to work and then will work at any speed. I did this using cat /dev/ttyS0 and inside of a C program. In each case the behavior is the same. It's like the port needs to be woken up and then it will receive data. Does this behavior make sense to anyone? I have not tried sending data from the remote PC in an automated fashion. I am going to try that next. But it just seems weird that typing speed is affecting whether or not the port will receive. Send... no problems.

I tried sending a data stream from a program. The behavior is the same. I need to send the data several times before the UART goes into receive mode and once it goes into receive mode it stays good until I break out of the receive program.