Welcome! Log In Create A New Profile


Suggestion: Interrupt line for RS-485

Posted by John Meacham 
Suggestion: Interrupt line for RS-485
April 17, 2009 02:00AM
Heh, I stop paying attention to the reprap project for a bit and come back to find a whole new generation of electronics. smiling smiley I am very pleased with the choice of RS485, I always thought something like that would be the right way to go. I just have one suggestion that I think will help us out in the long run and can be implemented in a fully backwards compatable way with the gen 3 boards that are already out there.

The main disadvantage of RS485 is that it is half-duplex, so generally requires a 'master' node to coordinate all communication, generally this means the master node must be constantly in a poll loop, asking each device if it has anything to say. This not only eats cycles of the master but also introduces a delay in servicing any device as it needs to wait around for the next time around the poll loop.

The solution is pretty straightforward, take one of the ground lines in the RS485 cable and turn it into a shared interrupt line. Basically, the interrupt line (that is shared across all devices on the bus) has a weak pull up resistor on it so it is normally high. Whenever a device needs servicing, it pulls the line low and keeps it there until the master gets around to it and it says whatever it needs to say. Since the line is level triggered (the master polls as long as it is low, and the devices keep the line low until they have nothing more to say) there is no problem with multiple devices interrupting at the same time or the possibility of lost interrupts. The master only polls when needed, and even better, it can attach a software interrupt to the pin so it can respond immediately, rather than waiting for the next polling cycle.

For the cost of a single resistor and an IO pin, this seems well worth it to implement in the hardware now, even if it takes the software a bit to catch up.

The change is backwards compatable because legacy devices all have the interrupt line connected to ground, so if any legacy device is plugged in, the master simply resorts to the old 'polling' behavior, likewise, if a legacy motherboard is used with a new device, then nothing bad happens because the motherboard will eventually get to it in its normal poll loop.

So, what do people think? When we start adding things to the RS485 bus, I can see this being a big help in the future. It also provides us with a really handy 'side-channel', which we can use for instance to assign modbus IDs to devices using something like the one-wire protocol or the ISA PNP trick on boot up.

The line is also helpful in a token passing situation, rather than constantly passing the token around when no one wants to say anything, whoever has the token just sits on it unless the interrupt line is pulled low. as long as the line is pulled low, the token is passed around like normal. When the line goes high, whomever has the token simply holds it until it has something to say or the line goes low in which case is passes it on.

Seems well worth it to make the hardware changes now, for a resistor and an IO pin and some trivial circuit changes we open up a lot of software possibilities in the future smiling smiley

John - [notanumber.net]
Re: Suggestion: Interrupt line for RS-485
April 20, 2009 01:20PM
Hi John,
While it's easy to add a pin, there are plenty of bus arbitration schemes already in place. The easiest of these is to simply receive what you transmit, compare it and check for collisions. A more robust solution is to assume that all transmissions go either to the master or come from the master. This makes the master a bus arbitrator. In this case, the bus master will detect collisions. Collisions will be detected by the use of CRCs on control packets.

Here's how I would do it:
Control packets are sent immediately. This allows timing, alerts, etc. to be sent without waiting for the master to select a device.
Large data must request clearance from the master.
To send a large data packet, a device will request bus time from the master. The master will either respond with "every one else be quiet, go ahead" or "wait."
When the device is allowed to go ahead, it has guaranteed free bus time.
When the data packet is complete, the master will allow the rest of the bus to talk again. (maybe a quick poll would be in order after a large data packet).

If two control packets are sent simultaneously, the master will detect a collision and begin arbitration Each device should recognize that there is a collision as well, and wait for the master to select it.

This way, the master only polls the bus when there is a collision. Assuming a fairly free bus, which I expect reprap's bus to be, this should result in a minimum of used cycles on the master, while not requiring another pin in the cable.

I'm not sure CRC is the best solution because it does take significant cycles to implement. CRC8 can be done with a 256-byte look-up table, and a few cycles per byte, so that might be as viable as a plain XOR checksum (LRC).

I've been thinking about drawing up a protocol spec for RS485 reprap for a while now. I've got some pretty solid ideas on how to implement a full communication spec so that the majority of hardware connected on the bus could be supported easily.

Re: Suggestion: Interrupt line for RS-485
April 20, 2009 01:37PM
You know, that previous scheme isn't necessarily the best solution.

A beacon system could be a lot better. The master provides a beacon pulse. The beacon contains a timestamp, followed by a list of device addresses. The device addresses correspond to a timeslot. Each device can send a control packet in its timeslot. There's a data window following the timeslots. The master can grant access to the data window for one device each beacon period. Any device can request a data window using its control timeslot.

Because the beacon arrives at a fixed interval and contains a timestamp, it automatically synchronizes all of the devices.
Because the master is only required to transmit a beacon at a fixed interval, it is still polling, but the polling frequency is much lower.
There is no possibility of bus contention because devices are assigned timeslots.

Re: Suggestion: Interrupt line for RS-485
May 14, 2009 10:13PM
I am afraid this won't work because you cannot detect collisions on a RS-485 bus, even if you could, collision detection is quite tricky, requiring things like sending jam signals and minimum packet sizes that depend intimately on the length of your cables and your bus speed. The reason is that RS-485 is a differential bus, it is driven in both directions (high and low) if two different things are driving it at the same time, what the devices see could be aribtrary, even different things between different devices. The reason Collision detection works on Ethernet is that there is a sinusoidal carrier wave that is broadcast when you want the bus, it is this that is actually detected and checked for for collisions, not the data itself. I2C can also do collision detection due to the fact the lines are never driven high, they are allowed to float high and devices only pull it low. the result being the signal you see being the logical or of the signals sent out. This is equivalant to how the interrupt line should work.
Re: Suggestion: Interrupt line for RS-485
May 16, 2009 05:16AM
I don't agree about collisions.

UARTS have been implemented with framing error detection for over a decade, and on all the microcontrollers I've dealt with, over more time than that.

If you want to bit bang, it's a different matter, but again, most micros come with UARTs these days, and the larger ones with more than one.

Parity also comes as a standard option, and can be implemented when bit banging too, with minimal finesse required.

Sorry, only registered users may post in this forum.

Click here to login