RS485 faster than Modbus

Status
Not open for further replies.

wjgoodrich

New member
Hi all,

I have a system of 36 sensor assemblies that I'd like to quickly poll the state of several times per second. Each one of these assemblies includes a Teensy 3.1 board connected to an analog sensor and a half-duplex TI ISO3088 RS-485 chip. The entire system is connected by way of bus using CAT5e Ethernet cables between each assembly, and connected similarly to a Master board/assembly (essentially the same thing). I have no previous experience with the Modbus protocol, but had intended to implement with it. ...until I found that it's likely too slow.

The ISO3088 chips are theoretically able to communicate at 2.5 Mbps, and accordingly the hypothesis was that I would have some headroom to poll all 36 of the sensors (~2-byte payload each) several times per second with no problem, even accounting for start bits, checksums, and all that extra packet stuff.

It seems I'm able to do some pretty fast broadcasting to all the slaves, and even sequential addressing to each slave (~1.8 Mbps). BUT... the second I try to implement a sequential call and response system, I'm back down to 115200 max.

Am I in for a rude awakening, not knowing all the details of Modbus? It seems there is some significant delay in polling each slave, waiting for the response, and then polling the next slave. Is this to be expected? I read this delay could be up to the range of 100ms - 200ms.

Perhaps I can use RS485 without Modbus. Does anyone have experience developing their own simple protocol to poll a bunch of RS485 slaves?

Thanks in advance!
 
I'm going down this path as we type. FWIW, I am developing a host/client protocol based on easytransfer. Not there yet though.

There are libraries out there that allow somewhat easier RS485 communications but the ones I found were too restrictive re usage.

If I had to do it again, I'd seriously consider going full duplex. The chips are the same size and the reduction in complexity re the timing of transmissions (i.e. Host sends out a query, client responds, etc) is welcome.
 
Does anyone have experience developing their own simple protocol to poll a bunch of RS485 slaves?

Yes, I've done quite a lot of this.

Two things limit your speed. The baud rate is the most obvious issue.

The other big, perhaps less obvious issue is the half duplex turnaround time. This is the delay required to allow the RS485 transmitter to turn off. Normally it's implemented as a simple delay before you write data to transmit. That allows the other side which just sent data to stop driving the line. On the master or controller, this lets the slave device that just answered your last query turn off its transmitter. If you don't delay, you might start sending the next query while it's still driving the line. Likewise at the slave devices, when they hear a query with their address, a brief delay is needed before sending the reply, to make sure the controller has been able to turn off its transmitter.

Fortunately, if you're using Teensy and you don't have any extra repeaters or amplifiers between all the devices, Teensy can let you shave this delay pretty low with Serial1.transmitEnable() controlling the transmit pins. A delay of 2 or 3 bit times would be safest. You might be able to get away with less, but that's risky.

The required turnaround delay depends on the worst case for all other devices to turn off their transmitter after the last stop bit. When RS485 is implemented with other boards like regular Arduino, the timing between the stop bit and shutting off the transmitter can be quite a bit longer.
 
Well if you need to shave cycles, it occurs to me that you can break the sensors into 3 groups, each one is controlled by a separate Serial device (Serial1, Serial2, Serial3). In theory, you could send bits down each serial device in parallel, and wait for the response. You would have to use the normal 'blink without delay' style of coding to handle all 3 streams in parallel. Depending on how tight the timing is, you might need to do polling instead of interrupt handlers, and maybe DMA transfers. I don't know if you could also use the CAN and I2S buses (SPI as well), but that might complicate things where you have different types of I/O.
 
Last edited:
Or adjust the serial buffer sizes for the respective serial buses. Data grams do not have to be huge. However, a full duplex bus likely gives you he best opportunity for the awesome"fire and forget" approach to sending data using the enable pin function.

On a half duplex bus, I expect that a unsophisticated programmer like me would be better off using the serial flush function to enable precise timing from the time something left the MCU to the time that a response is expected. Better programmers would likely make use of interrupts /DMA to detect / process incoming data grams and hence make the MCU pretty versatile despite communicating on three serial buses at once.

Though this inspires me to think about ways to make the communications less pedantic than they currently are (i.e. Eliminate delay functions and consider interrupts instead). This would be particularly welcome on client devices like the power meter that is supposed to sample at 1.3ksps. It would be really nice to be able to slot serial communications into the time slices while the MCU is waiting for the external ADC to serve up a fresh sample.

I suppose one way to do that would be to lengthen the allowable timeouts such that each data gram can be set to ship in the ~250-500us that each sample period leaves in terms of idle MCU time. Then I could make use of the enable pin function, even on a half duplex bus. ...
 
Last edited:
Yes, I've done quite a lot of this.

Two things limit your speed. The baud rate is the most obvious issue.

The other big, perhaps less obvious issue is the half duplex turnaround time. This is the delay required to allow the RS485 transmitter to turn off. Normally it's implemented as a simple delay before you write data to transmit. That allows the other side which just sent data to stop driving the line. On the master or controller, this lets the slave device that just answered your last query turn off its transmitter. If you don't delay, you might start sending the next query while it's still driving the line. Likewise at the slave devices, when they hear a query with their address, a brief delay is needed before sending the reply, to make sure the controller has been able to turn off its transmitter.

Fortunately, if you're using Teensy and you don't have any extra repeaters or amplifiers between all the devices, Teensy can let you shave this delay pretty low with Serial1.transmitEnable() controlling the transmit pins. A delay of 2 or 3 bit times would be safest. You might be able to get away with less, but that's risky.

The required turnaround delay depends on the worst case for all other devices to turn off their transmitter after the last stop bit. When RS485 is implemented with other boards like regular Arduino, the timing between the stop bit and shutting off the transmitter can be quite a bit longer.

Hey Paul-

Thanks a lot for the help. 3 bit times + 1 microsecond to accommodate for float truncation at high speeds, plus a .flush() call after writes and we appear to be running without any issues at 2.4 Mbps.

This was in a system with a single master and two slaves. Do you anticipate needing to extend any delays as the RS485 network grows (up to say, 50 nodes)?


-Bill
 
As long as every device is able to turn its transmitter off quickly (eg, they're all Teensy with transmitEnable), and you don't have any other stuff like RS485 repreaters, then you shouldn't need to increase those delays.

If you're connecting more than 32, hopefully those RS485 chips are half or quarter load. You'll probably also need proper termination resistors.

It's always a good idea to check the waveform with a scope when running with the longest cable and the maximum number of devices. 2.4 Mbit/sec is pretty fast. RS485 without the slower slew rate limited chips should be able to manage that speed. There are issues with longer cables and fast baud rates. Here's an extremely detailed article:

https://www.maximintegrated.com/en/app-notes/index.mvp/id/3884

Figure 6 shows a recommendation of up to 750 feet with 2.5 MBit/sec speed with standard driver chips.
 
Hi PaulStoffregen,

I am developing a system that is consisted of multiple arduino UNO's (max 32) connected to a RS-485 bus. Each Arduino is connected to a sensor and reads data from the sensors every 5ms (e.g. 200Hz). Can you suggest some RS485 protocol that will allow all the Arduinos to write their data very fast one by one. I tried with Modbus but it seems to be very slow. Thanks
 
You could try making your own protocol. But ultimately the limiting factors are the baud rate and turnaround, as I mentioned in msg #3. To use faster baud rates and keep those turnaround times quick, you might need something faster than Arduino Uno.
 
Status
Not open for further replies.
Back
Top