EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Half-duplex RS485: simple auto-direction solution

Started by pozz March 3, 2023
I think you already know this trick: connect DE/RE signals of RS485 
half-duplex transceiver to TX *negated* signal from UART and connect TX 
input of transceiver to GND.

If the bus is not driven by anyone, A signal goes high and B signal goes 
low thanks to the pull-up/down resistors.

The trick uses the fact that the undriven bus and transmitting 1 is the 
same thing: A is high and B is low. So, when transmitting 1 the driver 
is disabled (DE=0), when transmitting 0 the driver is enabled (DE=1). 
Because TX is set to 0, A goes low and B goes high.

Of course this works in ideal and good conditions. When should I worry 
of this trick? I suspect the edges of 0 to 1 transitions are slowed down.

I don't use mega-baudrate, in this application I'm using 38400bps.

On 3/3/23 11:15 AM, pozz wrote:
> I think you already know this trick: connect DE/RE signals of RS485 > half-duplex transceiver to TX *negated* signal from UART and connect TX > input of transceiver to GND. > > If the bus is not driven by anyone, A signal goes high and B signal goes > low thanks to the pull-up/down resistors. > > The trick uses the fact that the undriven bus and transmitting 1 is the > same thing: A is high and B is low. So, when transmitting 1 the driver > is disabled (DE=0), when transmitting 0 the driver is enabled (DE=1). > Because TX is set to 0, A goes low and B goes high. > > Of course this works in ideal and good conditions. When should I worry > of this trick? I suspect the edges of 0 to 1 transitions are slowed down. > > I don't use mega-baudrate, in this application I'm using 38400bps. >
Yes, that trick "works" to the level that you can use an "open collector" signal with a pull up to act like a normal driven signal. The 0 to 1 transition is weak and the 1 is typically not full strength, so noise immunity is compromised. It isn't bad for an "in system" communication bus, but isn't really reliable for a system-to-system link due to the higher capacitance (and thus slower transition) that occurs.
On 03/03/2023 17:15, pozz wrote:
> I think you already know this trick: connect DE/RE signals of RS485 > half-duplex transceiver to TX *negated* signal from UART and connect TX > input of transceiver to GND. > > If the bus is not driven by anyone, A signal goes high and B signal goes > low thanks to the pull-up/down resistors. > > The trick uses the fact that the undriven bus and transmitting 1 is the > same thing: A is high and B is low. So, when transmitting 1 the driver > is disabled (DE=0), when transmitting 0 the driver is enabled (DE=1). > Because TX is set to 0, A goes low and B goes high. >
This arrangement is also known as a "CAN bus driver".
> Of course this works in ideal and good conditions. When should I worry > of this trick? I suspect the edges of 0 to 1 transitions are slowed down. > > I don't use mega-baudrate, in this application I'm using 38400bps. >
Il 04/03/2023 12:06, David Brown ha scritto:
> On 03/03/2023 17:15, pozz wrote: >> I think you already know this trick: connect DE/RE signals of RS485 >> half-duplex transceiver to TX *negated* signal from UART and connect >> TX input of transceiver to GND. >> >> If the bus is not driven by anyone, A signal goes high and B signal >> goes low thanks to the pull-up/down resistors. >> >> The trick uses the fact that the undriven bus and transmitting 1 is >> the same thing: A is high and B is low. So, when transmitting 1 the >> driver is disabled (DE=0), when transmitting 0 the driver is enabled >> (DE=1). Because TX is set to 0, A goes low and B goes high. >> > > This arrangement is also known as a "CAN bus driver".
CAN is a well-known and very reliable network. Does this mean I could use RS485 in "CAN bus driver" arrangement without critical problems?
>> Of course this works in ideal and good conditions. When should I worry >> of this trick? I suspect the edges of 0 to 1 transitions are slowed down. >> >> I don't use mega-baudrate, in this application I'm using 38400bps. >> >
On 06/03/2023 10:41, pozz wrote:
> Il 04/03/2023 12:06, David Brown ha scritto: >> On 03/03/2023 17:15, pozz wrote: >>> I think you already know this trick: connect DE/RE signals of RS485 >>> half-duplex transceiver to TX *negated* signal from UART and connect >>> TX input of transceiver to GND. >>> >>> If the bus is not driven by anyone, A signal goes high and B signal >>> goes low thanks to the pull-up/down resistors. >>> >>> The trick uses the fact that the undriven bus and transmitting 1 is >>> the same thing: A is high and B is low. So, when transmitting 1 the >>> driver is disabled (DE=0), when transmitting 0 the driver is enabled >>> (DE=1). Because TX is set to 0, A goes low and B goes high. >>> >> >> This arrangement is also known as a "CAN bus driver". > > CAN is a well-known and very reliable network. Does this mean I could > use RS485 in "CAN bus driver" arrangement without critical problems? >
Yes, you certainly can do so - within limitations. Since the return to idle (logic 1) level is by terminating resistors, you don't have such clean edges and the rate is highly dependent on the bus load, capacitance, and termination resistance. Normal RS-485 is sometimes run over kilometres of cable - CAN is rarely more than a few tens of metres. And while CAN bus drivers are derived from RS-485 drivers with the arrangement you describe, they are a bit more optimised for the task. So you might consider using real CAN drivers rather than RS-485 drivers, even if you have UART signalling rather than CAN controllers for the protocol. (I did this myself on a project, long ago.) Another alternative, of course, is to use full CAN - microcontrollers with CAN controllers are no longer the premium they used to be.
On Monday, March 6, 2023 at 4:41:20 AM UTC-5, pozz wrote:
> Il 04/03/2023 12:06, David Brown ha scritto: > > On 03/03/2023 17:15, pozz wrote: > >> I think you already know this trick: connect DE/RE signals of RS485 > >> half-duplex transceiver to TX *negated* signal from UART and connect > >> TX input of transceiver to GND. > >> > >> If the bus is not driven by anyone, A signal goes high and B signal > >> goes low thanks to the pull-up/down resistors. > >> > >> The trick uses the fact that the undriven bus and transmitting 1 is > >> the same thing: A is high and B is low. So, when transmitting 1 the > >> driver is disabled (DE=0), when transmitting 0 the driver is enabled > >> (DE=1). Because TX is set to 0, A goes low and B goes high. > >> > > > > This arrangement is also known as a "CAN bus driver". > CAN is a well-known and very reliable network. Does this mean I could > use RS485 in "CAN bus driver" arrangement without critical problems? > >> Of course this works in ideal and good conditions. When should I worry > >> of this trick? I suspect the edges of 0 to 1 transitions are slowed down. > >> > >> I don't use mega-baudrate, in this application I'm using 38400bps.
You have not explained why you would want to go to this trouble. Are you concerned about multiple drivers on the bus at the same time doing damage??? I can't see any reason for complicating the bus in this way. You may think 38400 bps is not fast, but have you done any calculations on the resulting rise time of the resistor pullup? That's the main disadvantage of resistor pullups with what amounts to open collector drivers, the slow rise time impacting the timing. The slow rise time also opens the door wider for noise to impact the reception of double edges. The method I've used is to use bias resistors on the bus to establish a level in the absence of drivers on the bus. Then, the driver is enabled at all times the UART is transmitting, including some portion of the final stop bit. That will force the bus to a '1' state with all due speed, and the bias resistors will maintain that state. This is the bit that can be tricky to assure. CPUs don't really respond all that fast, and the status bits from the UARTs are not always what you would like. The only other requirement is for the receivers to provide adequate time before driving the bus, to assure the previous driver has stopped driving the bus. Again, the hardware is not always optimal for knowing the timing of the end of the stop bit, but at least there's nothing to prevent adding sufficient padding to prevent collisions. -- Rick C. - Get 1,000 miles of free Supercharging - Tesla referral code - https://ts.la/richard11209
Il 06/03/2023 20:23, Rick C ha scritto:
> On Monday, March 6, 2023 at 4:41:20 AM UTC-5, pozz wrote: >> Il 04/03/2023 12:06, David Brown ha scritto: >>> On 03/03/2023 17:15, pozz wrote: >>>> I think you already know this trick: connect DE/RE signals of RS485 >>>> half-duplex transceiver to TX *negated* signal from UART and connect >>>> TX input of transceiver to GND. >>>> >>>> If the bus is not driven by anyone, A signal goes high and B signal >>>> goes low thanks to the pull-up/down resistors. >>>> >>>> The trick uses the fact that the undriven bus and transmitting 1 is >>>> the same thing: A is high and B is low. So, when transmitting 1 the >>>> driver is disabled (DE=0), when transmitting 0 the driver is enabled >>>> (DE=1). Because TX is set to 0, A goes low and B goes high. >>>> >>> >>> This arrangement is also known as a "CAN bus driver". >> CAN is a well-known and very reliable network. Does this mean I could >> use RS485 in "CAN bus driver" arrangement without critical problems? >>>> Of course this works in ideal and good conditions. When should I worry >>>> of this trick? I suspect the edges of 0 to 1 transitions are slowed down. >>>> >>>> I don't use mega-baudrate, in this application I'm using 38400bps. > > You have not explained why you would want to go to this trouble. Are you concerned about multiple drivers on the bus at the same time doing damage???
I'm using a Linux embedded module based on a MX6ULL that isn't capable of driving the direction in hw. There's a bit in one UART register that must be set/reset by software. I don't know any details (and I don't have knowledge to understand) about how the UART driver is implemented and what could be the worst case delay of disabling the driver after the stop bit of the last transmitted byte. I suppose there's a very big jitter on this time, but it could be impossible to calculate the worst case. I'd like to reduce this time at the minimum so the other transmitters on the bus shouldn't introduce big delays before starting the transmission to avoid conflicts with the Linux-box that delayed in freeing the bus.
> > I can't see any reason for complicating the bus in this way. You may think 38400 bps is not fast, but have you done any calculations on the resulting rise time of the resistor pullup? That's the main disadvantage of resistor pullups with what amounts to open collector drivers, the slow rise time impacting the timing. The slow rise time also opens the door wider for noise to impact the reception of double edges. > > The method I've used is to use bias resistors on the bus to establish a level in the absence of drivers on the bus. Then, the driver is enabled at all times the UART is transmitting, including some portion of the final stop bit. That will force the bus to a '1' state with all due speed, and the bias resistors will maintain that state. This is the bit that can be tricky to assure. CPUs don't really respond all that fast, and the status bits from the UARTs are not always what you would like. > > The only other requirement is for the receivers to provide adequate time before driving the bus, to assure the previous driver has stopped driving the bus. Again, the hardware is not always optimal for knowing the timing of the end of the stop bit, but at least there's nothing to prevent adding sufficient padding to prevent collisions. >
On 3/3/2023 9:15 AM, pozz wrote:
> I think you already know this trick: connect DE/RE signals of RS485 half-duplex > transceiver to TX *negated* signal from UART and connect TX input of > transceiver to GND. > > If the bus is not driven by anyone, A signal goes high and B signal goes low > thanks to the pull-up/down resistors. > > The trick uses the fact that the undriven bus and transmitting 1 is the same > thing: A is high and B is low. So, when transmitting 1 the driver is disabled > (DE=0), when transmitting 0 the driver is enabled (DE=1). Because TX is set to > 0, A goes low and B goes high. > > Of course this works in ideal and good conditions. When should I worry of this > trick? I suspect the edges of 0 to 1 transitions are slowed down. > > I don't use mega-baudrate, in this application I'm using 38400bps.
Do you completely control everything that is connected to the device, including the *wire*? Are you sure someone won't opt to lengthen a cable, add another "extension" to your existing cable, etc.? There's a reason you *actively* want to drive a line high and low (mark and space) instead of just letting it take its sweet time getting to that state. (Remember, what you see at one end of the line isn't the same as what you see at the other, at any given instant)
On Monday, March 6, 2023 at 4:20:13 PM UTC-5, pozz wrote:
> Il 06/03/2023 20:23, Rick C ha scritto: > > On Monday, March 6, 2023 at 4:41:20 AM UTC-5, pozz wrote: > >> Il 04/03/2023 12:06, David Brown ha scritto: > >>> On 03/03/2023 17:15, pozz wrote: > >>>> I think you already know this trick: connect DE/RE signals of RS485 > >>>> half-duplex transceiver to TX *negated* signal from UART and connect > >>>> TX input of transceiver to GND. > >>>> > >>>> If the bus is not driven by anyone, A signal goes high and B signal > >>>> goes low thanks to the pull-up/down resistors. > >>>> > >>>> The trick uses the fact that the undriven bus and transmitting 1 is > >>>> the same thing: A is high and B is low. So, when transmitting 1 the > >>>> driver is disabled (DE=0), when transmitting 0 the driver is enabled > >>>> (DE=1). Because TX is set to 0, A goes low and B goes high. > >>>> > >>> > >>> This arrangement is also known as a "CAN bus driver". > >> CAN is a well-known and very reliable network. Does this mean I could > >> use RS485 in "CAN bus driver" arrangement without critical problems? > >>>> Of course this works in ideal and good conditions. When should I worry > >>>> of this trick? I suspect the edges of 0 to 1 transitions are slowed down. > >>>> > >>>> I don't use mega-baudrate, in this application I'm using 38400bps. > > > > You have not explained why you would want to go to this trouble. Are you concerned about multiple drivers on the bus at the same time doing damage??? > I'm using a Linux embedded module based on a MX6ULL that isn't capable > of driving the direction in hw. There's a bit in one UART register that > must be set/reset by software. > > I don't know any details (and I don't have knowledge to understand) > about how the UART driver is implemented and what could be the worst > case delay of disabling the driver after the stop bit of the last > transmitted byte. I suppose there's a very big jitter on this time, but > it could be impossible to calculate the worst case. > > I'd like to reduce this time at the minimum so the other transmitters on > the bus shouldn't introduce big delays before starting the transmission > to avoid conflicts with the Linux-box that delayed in freeing the bus. > > > > I can't see any reason for complicating the bus in this way. You may think 38400 bps is not fast, but have you done any calculations on the resulting rise time of the resistor pullup? That's the main disadvantage of resistor pullups with what amounts to open collector drivers, the slow rise time impacting the timing. The slow rise time also opens the door wider for noise to impact the reception of double edges. > > > > The method I've used is to use bias resistors on the bus to establish a level in the absence of drivers on the bus. Then, the driver is enabled at all times the UART is transmitting, including some portion of the final stop bit. That will force the bus to a '1' state with all due speed, and the bias resistors will maintain that state. This is the bit that can be tricky to assure. CPUs don't really respond all that fast, and the status bits from the UARTs are not always what you would like. > > > > The only other requirement is for the receivers to provide adequate time before driving the bus, to assure the previous driver has stopped driving the bus. Again, the hardware is not always optimal for knowing the timing of the end of the stop bit, but at least there's nothing to prevent adding sufficient padding to prevent collisions. > >
You could use a simple interface device that drives the line low always, but only drives the line high, for say, 20% of a bit time. That will assure the solid rise time, then it will be off the bus before the end of the "1" bit. Such a device needs to know nothing about your protocol. It is a bit of hardware that does a simple task. The 20% will need to be tuned to your data rate, but it's not a critical number. It could be set at a few microseconds (a simple RC time constant) to work well at your bit rate and would also work for any slower rate. How short you can make this time out, depends on how long it takes a driver to drive the cable to the '1' level. This could be as simple as an RS-485 enabled driver. Drive the data input with the appropriate output from your existing driver. Drive the enable line through a resistor, with a cap to ground so it turns off after being in the '1' state after the RC time. A diode across the resistor will assure the driver turns on quickly when the driving signal is in the '0' state. Four parts and, Bob's your uncle! -- Rick C. + Get 1,000 miles of free Supercharging + Tesla referral code - https://ts.la/richard11209

Memfault Beyond the Launch