EmbeddedRelated.com
Forums
Memfault State of IoT Report

Two-wires RS485 and the driver enable problem

Started by pozzugno October 13, 2014
On 10/16/2014 3:01 AM, pozzugno wrote:
> > I was thinking about your suggestions, but it seems to me it doesn't > work well. > > Others suggested to send some dummy bytes, keeping the RS485 driver > *disabled*. Only after those bytes are really shifted out, the driver > could be enabled. In other words, you use the UART hardware also for > timing, without the need to use other peripherals (such as > timers/counters). > > Your suggestion seems better: send some sync bytes at the beginning, > with the RS485 driver *enabled*. My protocol can be used with this > approach, because it is inspired to HDLC. Every frame starts and ends > with a sync byte. If the sync byte appears in the payload data, it is > escaped (as in HDLC or SLIP protocols).
The block start and end bytes are important, but if they are not unique you have to escape them in your data which implies a message handling layer in your software. Or you can use a UART that recognizes the start characters. If you use sync data transmission rather than async this is common.
> The device could send N sync bytes without problems. The receiver will > see N empty frames and will discard them silently. In this way it's > even more simple to introduce a delay before the answer.
How is N sync bytes equivalent to a bunch of empty frames? Is your sync byte unique?
> But I think it doesn't work. Bytes are send asyncronously and the > receiver must syncronize to the start bit of each byte. If the slave > sends 2 sync bytes in the front of each frame, without a delay, and the > master toggles direction in the middle of the two sync bytes, the master > will receive one or two wrong bytes or detect frame errors, depending on > the precise time and transitions pattern. > > Moreover, if the payload is transmitted immediately after sync bytes, as > really happens, the overall frame could be corrupted. > > *Perhaps* this technique works well only if the preamble bytes are 0xFF, > because they appears on the wire just as a single start bit (all the > other bits, including stop bits, are at the idle level). > > --- ------------------ ------------------ -......... > | | PREAMBLE | | PREAMBLE | | START OF FRAME > | | 0xFF | | 0xFF | | > ---- ---- ---- > ^ ^ ^ > A B C > > If the master toggles direction at time A, it will receive the two > preamble bytes correctly and could discard them. The frame is received > correctly. > If it toggles direction at time C, it will receive only one preamble > byte correctly and could discard it. The frame is received correctly. > > What happens it the master toggles direction at time B, in the middle of > a start bit? I don't know if the UART detects a start bit on the > high-to-low edge or on the low level. In the first case, I think > there's no problem. In the second case, what happens?
I'm not sure I see a problem. UARTs typically see the falling edge as the start of the start bit, but check at least once in the middle of the bit to see if it was just noise. Too short a pulse and it is discarded. Long enough and it will be seen as a start bit. Since the UART starts looking for a new start bit in the middle of the stop bit (approximately) such a start bit timing discrepancy will not create a problem although this leaves no room for timing variation between the two ends. As long as point B is in the first preamble char and not the last it should be ok. But if you can be sure the driver disable will be at worst case no later than C, why can't the slave just hold of sending the start of frame for another char? Your approach will work, but it is no better than sending chars without enabling the slave's driver in the first place. In fact, if you know when the master driver will be off the bus, you can get your message out once character more quickly by not sending the last preamble byte. -- Rick
On 10/16/2014 2:36 AM, pozzugno wrote:
> Il 16/10/2014 07:17, rickman ha scritto: >> On 10/15/2014 10:24 AM, Grant Edwards wrote: >>> On 2014-10-15, rickman <gnuarm@gmail.com> wrote: >>>> >>>> Is all of this based on the idea that the transmitter empty >>>> interrupt is >>>> not valid in some way? >>> >>> We're talking about a 16550. There _is_no_ transmitter empty >>> interrupt. There is a transmit holding register empty interrupt, but >>> that happens _before_ transmission of the last byte has begun. >> >> I don't know who "we" is, but the OP never said what UART he is using. I >> had the impression it was a UART within an MCU from his initial post >> where he refers to "some microcontrollers" toggling an output. Did he >> say he is using a '550' type UART? > > Yes, I'm using a UART peripheral integrated in microcontrollers, like > PICs from Microchip or AVRs from Atmel.
Do you know if your transmitter empty interrupt works properly or is this what prompted the entire thread? I was looking at some of the USB dongles for RS-485 a while back and some of them make it clear that the driver is controlled directly by the transmitter empty and so the last char gets out of the module correctly. -- Rick
Il 16/10/2014 11:05, rickman ha scritto:
> On 10/16/2014 2:36 AM, pozzugno wrote:
> Do you know if your transmitter empty interrupt works properly or is > this what prompted the entire thread?
AVR micros have two transmitter interrupts: register empty and transmit complete. The transmit complete interrupt should disable the RS485 driver and it seems work well.
> I was looking at some of the USB dongles for RS-485 a while back and > some of them make it clear that the driver is controlled directly by the > transmitter empty and so the last char gets out of the module correctly.
No, AVRs (and many many micros smaller and bigger) can't directly control the RS485 driver/direction.
On 2014-10-16, rickman <gnuarm@gmail.com> wrote:
> On 10/15/2014 10:24 AM, Grant Edwards wrote: >> On 2014-10-15, rickman <gnuarm@gmail.com> wrote: >>> On 10/14/2014 5:35 PM, David Brown wrote: >>> >>>> It can often work fine - at worst, the receiver sees a brief noise at >>>> the end of the telegram itself, and that is easily ignored. >>>> >>>> However, if you are worried that the "transmission complete" interrupt >>>> might be delayed too long, then clearly the same thing will apply to the >>>> final "transmit character" interrupt for your extra character. So it is >>>> a useful trick if you don't have a "transmission complete" interrupt >>>> signal, but not for the problem at hand here. >>> >>> Is all of this based on the idea that the transmitter empty interrupt is >>> not valid in some way? >> >> We're talking about a 16550. There _is_no_ transmitter empty >> interrupt. There is a transmit holding register empty interrupt, but >> that happens _before_ transmission of the last byte has begun. > > I don't know who "we" is, but the OP never said what UART he is using. > I had the impression it was a UART within an MCU from his initial post > where he refers to "some microcontrollers" toggling an output. Did he > say he is using a '550' type UART?
Sorry, I must have gotten this confused with a different thread. -- Grant Edwards grant.b.edwards Yow! I'm ZIPPY the PINHEAD at and I'm totally committed gmail.com to the festive mode.
On 16/10/14 07:30, rickman wrote:

> > Personally I prefer to use hardware which is designed for the job and > will handle the driver enable properly. >
You'll get no arguments on that point. The trick of sending an extra byte is a way to make things work with non-ideal hardware - but better hardware is always nicer.
On Thursday, October 16, 2014 7:30:32 AM UTC+2, rickman wrote:
> Personally I prefer to use hardware which is designed for the job and > will handle the driver enable properly.
Me too. And I prefer datasheets that match the hardware, and so forth. Then, I wake up from that nice dream, and deal with reality ;-)

Memfault State of IoT Report