6
\$\begingroup\$

Does anyone know of a good circuit that would automatically enable the transmit on an RS-485 driver when characters are transmitted? In our designs we currently use RTS to drive the driver transmit pin, but then the RTS signalling has to be done in software.

Note the solution would have to be quite cheap as this will be a volume product (kind of excludes using a separate microcontroller to do the job). Also keeping the transmit enabled for any longer than necessary would be a problem, as the serial line may have to handle a lot of traffic.

\$\endgroup\$
3
\$\begingroup\$

If you're using an ordinary asynchronous (UART) protocol, with a start bit at the beginning of every byte, one simple method is to use a monostable multivibrator (even the dreaded 555) set to the duration of a byte plus the start bit and about half the stop bit, and use that to enable the transmit driver.

If the multivibrator is retriggerable, you need to allow up to one full byte time from the end of a transmission before anyone else can transmit, because the multivibrator may have been retriggered by the last data bit if it was a zero.

If not, then it should shut off in the middle of each stop bit, and then trigger again on the next start bit.

\$\endgroup\$
  • \$\begingroup\$ I would love to see this. \$\endgroup\$ – Hair_of_the_Dog Apr 17 '13 at 6:21
  • \$\begingroup\$ This sounds good. In the current circuit the hardware guys have designed the transmit drive of the RS-485 driver chip is tied to the TTL transmit pin, so on each bit the transmit is enabled. I can't see how this would work reliably however, but am going to test it out in the next few days... \$\endgroup\$ – fred basset Apr 25 '13 at 12:52
  • 1
    \$\begingroup\$ It's possible that the intent is to operate the bus as a pseudo-CAN bus, with a "dominant" state and a "recessive" state. Did the hardware guys put fairly stiff pullup/pulldown resistors on the bus lines? \$\endgroup\$ – Dave Tweed Apr 25 '13 at 12:57
  • \$\begingroup\$ I do see 750ohm resistors on the RX+ and RX- lines, not sure if that value is fairly stiff or not. How would the whole RS-485 work if like a CAN bus? I've only ever used RS-485 in basic two wire mode before. \$\endgroup\$ – fred basset Apr 26 '13 at 16:04
  • \$\begingroup\$ 750 Ohms would count as "fairly stiff" (6.67 mA @ 5V), so that's probably what's going on. As far as operating the RS-485, it should work as you expect; it's just that no physical damage can occur as a result of collisions with this hardware setup. \$\endgroup\$ – Dave Tweed Apr 26 '13 at 16:54
3
\$\begingroup\$

Well "good" is a vague term, but you did say "cheap"...

The simplest solution to this I've seen and tested myself is to use a PNP transistor and RC network. The following example is intended for 9600 baud, so a 22k resistor and 1n5 capacitor are used. These values would be modified for different baud rates.

This is by no means an elegant solution, but it's simple and can be build from the parts bin.

Here's the schematic:

schematic

simulate this circuit – Schematic created using CircuitLab

\$\endgroup\$
2
\$\begingroup\$

Your best bet would probably be to use a small microcontroller (probably with a UART, though software bit-banging might suffice) which takes a "data in" signal and generates both "data out" and "transmit enable". You should probably have an edge-triggered interrupt on the "data in" pin that asserts your "data out" signal even before a byte has been fully received, so that as soon as the complete byte is received you can start transmitting it (it's normally a good idea to assert transmit enable a little while before transmission actually begins). After a certain amount of time elapses without either a falling edge or a completely-received character, turn off the transmit enable pin.

The above approach would introduce a delay of a full character time between when the processor receives data and when it goes out the wire. In some cases, it may be desirable to reduce that time. Doing so would require using a software bit-bang UART instead of a hardware UART. Getting the timing correct at higher bit rates would be difficult, but one could have much finer control over the timing of the incoming and outgoing data.

\$\endgroup\$
  • \$\begingroup\$ This sounds good. In the current circuit the hardware guys have designed the transmit drive of the RS-485 driver chip is tied to the TTL transmit pin, so on each bit the transmit is enabled. I can't see how this would work reliably however, but am going to test it out in the next few days... \$\endgroup\$ – fred basset Apr 25 '13 at 12:50
  • \$\begingroup\$ They may be relying upon the fact that an idle RS-485 line will usually, hopefully, assume a marking state. At low baud rates, in relatively quiet environments, that might work. It could even work at moderate baud rates if the enable line were slower to respond than the data line (so that each space-to-mark transition would briefly output a proper spacing condition before going idle). Noise immunity would not be very good, however. \$\endgroup\$ – supercat Apr 25 '13 at 15:04
2
\$\begingroup\$

I saw a circuit that probably solved this issue. The CPU was a slave on the RS485 and therefore normally was in receive mode waiting for the correct ID message whereupon it would transmit its reply. The RS485 chip was transmit-enabled by the leading edge of the 1st bit in the data reply coming from the CPU when responding. A diode, a capacitor and a resistor contrived to quickly enable the chip into transmit mode, and successive data transitions kept it in transmit mode. When the transmission ended the cap would discharge through the resistor and after a few tens of milli seconds the chip would revert to receive mode.

There are two issues with this - the first bit transmitted was slightly short by about 10% and this may cause you problems. I'm sure a better circuit could be developed but there will always be a shortening of the 1st bit due to this being used to "detect" a transmit signal and enable the RS485 to transmit. The 2nd issue is that the transmit enable circuit kept active for some tens of milli secs after transmission from the slave had ceased and this of course prevents the master from polling another slave during that period in time.

If these "issues" are OK then no problem, it will work

\$\endgroup\$
  • \$\begingroup\$ If the RS-485 line will reliably hold a "marking" condition when nobody is transmitting, one could probably simplify things by having a shift register that runs at a rate much faster than the bit rate, using the middle tap as the data to the RS-485 chip, and the "AND" of many other taps as the "enable". For example, if one had a clock that was at least 16x the baud rate, one could use a 2x64-bit shift register with taps every 16 bits. If e.g. the clock was 32x the baud rate, then the device would be enabled two bit times before data was fed to it, and... \$\endgroup\$ – supercat Apr 17 '13 at 16:18
  • \$\begingroup\$ ...remain enabled for two bit times after the last falling edge. Two bit times should be plenty of time for the driver to start marking; even if the driver is disabled in the middle of the type, the line should remain marking until the end. If the line cannot be relied upon to remain in a marking state when nobody is transmitting, then one should enable one's driver a full byte time before transmitting. \$\endgroup\$ – supercat Apr 17 '13 at 16:20
0
\$\begingroup\$

I've been looking for a similar solution but I needed very accurate timing as the bus is running at 90% capacity. I couldn't afford to have more than half a bit length of overrun. I need to reliably disable the Tx within 2uS of the end of the stop bit.

My solution was use use a S/R D type flip flop to latch the start bit then drive that into an LTC timing chip (LTC6994), these provide 3% accuracy at the baud rate I needed of 230kbps. The output of the timing chip drives the reset on the D type.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.