3

Most 2-wire RS485 implementations I have seen use both UART RX and TX pins which works of course. And I have done so.

But I was wondering whether using UART in half-duplex mode is a good alternative that maybe(?) has benefit of cleaner code and reducing pin count.

The application is Modbus ASCII and timing is so clear (3.5 characters) that the switchover (that I do for DataEnable anyway) could be joined with a TransmitEnable.

(Some context: I have had RS485 transmitters with local echo’s on the UART RX line)

JeromeBu1982
  • 315
  • 2
  • 9

3 Answers3

3

It might be a good idea if you are in a situation where you need to preserve pins.

But it also then makes some things harder.

You need to switch single MCU pin between RX and TX modes for the single UART wire, in addition of controlling the transmitter/receiver enable pins.

It might also need a pull-up to the data lines so it floats idle between changing direction of MCU pin - some MCUs have internal pull-ups that can stay enabled all the time instead of turning on just when input.

It also makes it impossible to read back what is transmitted by the MCU, so detecting glitches, collisions or errors is not possible.

Justme
  • 127,425
  • 3
  • 97
  • 261
  • Actually, the last statement is not quite correct for all MCUs. For example, in STM32, the USART reads back its own data in half-duplex mode provided RX is enabled of course. On the other hand, in STM8, there's no need to disable RX while transmitting in half-duplex mode because own data is not read back automatically. – neoxic Nov 16 '21 at 23:02
  • 1
    @neoxic You misunderstood what I wrote. You say the MCU will receive exactly what it transmits so it can't detect glitches, collisions or errors on the RS-485 bus. I meant the MCU will transmit onto RS-485 bus and receive back what is on RS-485 bus, so it can see if it receives back same thing it sent, or has there been errors because two devices wants to transmit simultaneously on the same bus. And therefore, those errors can't be detected using one MCU pin only for RX and TX. – Justme Nov 16 '21 at 23:15
  • No, I didn't say the MCU will receive exactly what it transmits so it can't detect glitches. I did say it depends on an MCU whether it receives back what it transmits or not in half-duplex mode. In the former case, it WILL be able to check for errors on one-wire bus. In the latter case, it will NOT. – neoxic Nov 17 '21 at 03:18
  • So now you say exactly what I originally said which you claimed was not true? I don't follow. It does not matter what the MCU does in half-duplex mode, whether it receives own transmissions or not, because when using one UART RX/TX wire, the MCU side still does not know if there is a short circuit on RS485 side, as it can't monitor what is on the RS485 side. So using one wire, in neither case, MCU won't be able to detect errors as it won't be listening the actual data on RS485. – Justme Nov 17 '21 at 07:52
  • The ability to receive what is being sent is designed to make it possible for an MCU to detect errors and collisions on the line. If there's a collision (the line is being driven by another TX) or error (short circuit, instability), the receiver will likely receive NOT what the TX has just sent. By comparing the last byte sent with what has been received, the MCU can act accordingly - abort transmission, mute the receiver, wait for a random interval, and resume. But this ability (to receive what is being sent) is MCU dependant. – neoxic Nov 18 '21 at 08:08
  • @neoxic I think we are not talking about the same thing here, or there is some other misunderstanding. I understand and acknowedge what you mean in general, but in this case, the capabilities of the MCU do not matter. If you wire only one half-duplex RX/TX data wire from MCU to an RS-485 transceiver chip, as the original question was about what are the downsides of doing so, you simply can't get feedback. To get feedback from bus while transmitting, both the TX and RX wires of MCU must be connected to RS-485 tranceiver. – Justme Nov 18 '21 at 08:55
  • Maybe. Let me guess... For me, 2-wire RS485 is just what it is - a physical half-duplex layer where an UART is used as a logic driver. If you are talking about a scheme where the UART in an MCU connects to a separate "RS485 transmitter" (i.e. with its own UART/driver) then you are probably talking about the connection between them. That connection has nothing to do with RS485 because it connects two peripherals logically. In this case, there's probably nothing to gain from half-duplex mode. – neoxic Nov 18 '21 at 23:06
  • But if the UART in an MCU drives a 2-wire RS485 line directly, then in half-duplex mode it reads back what it transmits and hence is capable of detecting glitches and errors. This feature is specifically designed for RS485 applications by the way. But, as I mentioned earlier, not all MCUs, or rather not all UART peripherals, have it. – neoxic Nov 18 '21 at 23:07
  • The original question was not about an "RS-485 transceiver chip". It was about "2-wire RS485 implementations that use both RX/TX pins of an UART". See answer #3 for example where the answerer refers to it as a PHY (physical) interface. 2-wire means it is half-duplex. – neoxic Nov 18 '21 at 23:17
  • No, that's not what the question is about, please read it again. OP has used MCU with both RX and TX wires connected to RS-485 PHY, and is asking if it is a good idea to reduce MCU pin count and maybe switch to using single half-duplex RX/TX wire between MCU and RS-485 PHY and definitely thinking combining RE/TE pins. Using half-duplex between MCU and RS-485 PHY, the downside is, you can't receive/monitor/sense back from RS-485 PHY what is actually going on at the RS-485 bus while transmitting to bus with RS-485 PHY. – Justme Nov 19 '21 at 00:23
  • Ahhh, shoot...:-) I can see now where the misunderstanding was. Thank you! Yes, combining RE/DE pins in the driver will definitely cut the feedback. – neoxic Nov 20 '21 at 02:27
  • For the sake of integrity, I must also renounce my initial comment. I gave the UART in STM8 a thorough test, and it appears to be equally capable of receiving its own data in half-duplex mode. It's in fact the same UART as in STM32. – neoxic Nov 21 '21 at 21:52
2

RS485 already is half-duplex. So, why not introduce a little more to the PHY interface.
It is a good idea if you can find a reliable method to arbitrate RX & TX at local nodes, and arbitration of the bus. Becoming even more proactive, you may introduce a way to detect the contention on the bus. On software side, link layer can happily lose some serious part of the code.
While writing this, it indeed feels like a very interesting idea; something like Ethernet on RS485 PHY, or there must be something already out there.

jay
  • 3,781
  • 8
  • 24
  • RS-485 is NOT half duplex. It can operate in half (one direction) or full (bi-directional) duplex at the discretion of the designer. In fact, one of the changes made with '485 from '422 is that an RS-485 driver can drive a diff pair that is double terminated, with 120 ohm resistors at each end of the line. – SteveSh Aug 07 '21 at 14:46
  • @SteveSh: See https://electronics.stackexchange.com/q/69887/11683 – Dave Tweed Aug 07 '21 at 14:49
  • Thanks @SteveSh! That sounds like a good argument that I may agree. Indeed, standard may state only the electrical spec of RS-485 & RS-422, no need to limit the duplex or protocols, I guess. – jay Aug 07 '21 at 15:10
  • Listening to yourself talk is not a reliable way to detect contention on an RS485 bus. – brhans Aug 07 '21 at 15:22
  • I agree wit @brhans. Contention detection is not that simple. – jay Aug 07 '21 at 16:31
  • @SteveSh, I meant two-wire RS485 (mentioned), so half duplex context. others: listening to yourself talk on the bus was something I wanted to omit completely. Hence the idea to go full half duplex on the UART as well (will do pull-up as mentioned). Not sure if I can just combine RX/TX of 485 transceiver just like that – JeromeBu1982 Aug 07 '21 at 17:09
  • 2
    @JeromeBu1982 About " just combine RX/TX" and "pull-up to the data lines so it floats idle": If UART TX pin cannot be configured as open-drain, then it would need an external buffer. The transceiver device will need a similar consideration. The initial implementation wouldn't be as simple as "just put together", though if the concept gets implemented into devices design, it would be an attractive option, as simple as RS485 and answers those Ethernet may not, I think. – jay Aug 07 '21 at 17:31
  • Re: contention detection: I recall a field trip from back when we used to sell Westermo hardware. They have/had a family of serial to fiber optic converters which can/could work in a redundant ring on the fiber. Namely, this was the older LD-64 generation I believe. The protocol on site was something based on RS485 half duplex, with token passing and fast RX/TX switching. While starting up, apparently the bus relied on collision detection (checksum errors) to back off with transmission for a while, to "slot in" seamlessly. The Westermo nodes prevented garbling frames, and startup would fail... – frr Aug 08 '21 at 12:03
  • (...cont'd) I wouldn't call this a *bug* - rather, an integration issue. If I remember correctly, the fine Westermo fiber ring nodes would give precedence to data coming from the local metallic drop. On the ring, data would travel in a circle. If a local metallic "client" started transmitting something, the fiber converter node would block whatever was coming from the left hand side on the ring, and start repeating the activity from the local metallic drop. Thus, downstream nodes (clients) to the right would not necessarily spot a frame checksum error, and would try to follow up directly. – frr Aug 08 '21 at 12:25
  • (...cont'd) This probably led to a split / bifurcation / chaos in the token passing sequence, and the neat fast token-passing algorithm would collapse. There was a work-around that did help: to pay attention to node address ordering in the "client" protocol (the PLC chatter) and order PLC node addresses along the ring *in reverse direction*. That way, the neighbor node to follow up would be the one just left of you, and with a bit of luck, anyone inbetween (on your right) would probably not intervene... The propagation delays along the fiber ring were negligible = no problem. – frr Aug 08 '21 at 12:32
  • Good point @frr ! The "ring topology" eliminates "bus" arbitration – jay Aug 08 '21 at 12:33
2

Hmm... standard Modbus/ASCII does not use a frame break timeout of 3.5 characters worth. That timeout is characteristic of Modbus/RTU. Obviously if you own the implementation of all the nodes, this does not mean much. If your frame RX routine can detect end of frame based on frame contents (variable length frames have the length encoded early in the frame), you probably don't even need to honor the 3.5 characters worth in terms of RX/TX "turning time".

Once upon a time I've written a Modbus library for the PC, and I also happen to know a bit about the 16C550A and compatible UART's - but that knowledge is getting rusty. And I certainly know nothing about UART's occurring in MCU's. Being spoilt by the wasteful approach to pin counts in PC hardware, and having but a rusty fond memory of coding around the 16C550A UART hardware, I don't see what "using the UART in half-duplex mode" could save me in terms of code size or complexity.

That said - if I may suggest something to facilitate half-duplex RS485 operation, it would be using an UART that can steer the RX/TX automatically, by exporting the internal flag called "Transmitter Shift Register Empty" as an external discrete signal, which can be plugged directly into the RS485 level shifter (transceiver).

Note: do not confuse the desired "Transmitter Shift Register Empty" with the "Transmitter Holding Register Empty" = a different status flag in the UART. The former means the byte being currently shifted bitwise onto the line. The latter refers to the FIFO - and the THRE flag becomes active as soon as the FIFO is empty, i.e. while the shift register is still busy shifting out the last byte, i.e. too early for the RS485 transceiver to get disengaged into high Z / listening state.

Some UART implementations can send this signal as an alternative function of the RTS or DTR pins, others have dedicated output pins or can map this to some GPIO. The standard 16C550A only has the TSRE aka TEMT as an internal status flag, but lacks the capability to export this on any output pin. I.e. the 16C550A is not a stellar choice for RS485. As a shiny example of this function done right, I'd like to mention the late OX16C950 UART by Oxford Semiconductor, nowadays no longer manufactured (technical progress has its underside, and there was a string of acquisitions, roughly OX Semi -> PLX -> Avago -> Broadcom). If memory serves, modern UART's by EXAR can do it too, and some LPC SuperIO chips can also support this on some or all UART channels (Fintek, SMSC, maybe some recent ITE and Nuvoton nee Winbond). I don't have a clue about UART's in the various MCU's.

I seem to recall some UART's where this function is flawed - namely I recall an addon PCI board for the PC, with RS485 ports and HW steering, where the UART would switch the transceiver to high-Z (RX) one bit too early, effectively cutting off the stop bit. Which apparently worked fine against other UART's... I don't remember the brand of the UART chip on that board.

I've also seen a board-level design bug (thinko) in some asian industrial PC, where RS485 mode was implemented by driving the transceiver's RX/TX steering pin by the UART's TTL Data TX - so that the transceiver was switching between log.1 and high Z...

This feature, i.e. "TSRE=TEMT for RS485 RX/TX steering" can save you some headache with precise timing in software. It sure is a headache on the PC, especially under some modern OS... whether timing is a headache or not on your particular MCU, that's obviously your own business, YMMV.

frr
  • 2,573
  • 12
  • 14