2
\$\begingroup\$

I have several servos that can give feedback data that I want to read. The servos use special protocol so I need to use Rx/Tx pin on my Arduino Mega to communicate with them. The problem is that a servo has only one serial communication pin so I cannot use the usual Rx/Tx wiring.

I have heard that there are some hardware configurations to properly convert UART signals to half duplex type. One is to use 2 resistors connected to Rx and Tx of Arduino and the pin of the servo. Another is to use a transistor. However, I could not find exact circuit drawings and rules to choose the values for the resistors or the transistor. Can somebody provide more information on that and explain in terms of hardware exactly how these configurations prevent the Tx writing to the Rx and the servo feedback writing to the Tx.

EDIT: The servo is Dynamixel XL-320 (http://support.robotis.com/en/product/dynamixel/xl-320/xl-320.htm). The communication is half-duplex serial: I can write to the servo, but I can also read values, e.g. load (therefore I need to use both Rx and Tx pins on my arduino). NOTE: the servo manual proposes using a multiplexer and a digital pin on the arduino as a select bit in order to covert uart to half-duplex. However, I am specifically asking for other, more passive alternatives.

\$\endgroup\$
  • \$\begingroup\$ What is "special protocol" ? Is it half duplex serial? Or it is just one way? If latter, why do you need two-way? \$\endgroup\$ – Eugene Sh. Aug 5 '15 at 20:03
  • \$\begingroup\$ Or does it use the "One-Wire" interface (en.wikipedia.org/wiki/1-Wire)? How about a part number and datasheet link for your servo? \$\endgroup\$ – DoxyLover Aug 5 '15 at 20:24
  • \$\begingroup\$ Give us some more information on your servos niko \$\endgroup\$ – Arjun Aug 5 '15 at 21:20
  • \$\begingroup\$ EDIT: The servo is Dynamixel XL-320 support.robotis.com/en/product/dynamixel/xl-320/xl-320.htm. The communication is half-duplex serial: I can write to the servo, but I can also read values, e.g. load (therefore I need to use both Rx and Tx pins on my arduino). NOTE: the servo manual proposes using a multiplexer and a digital pin on the arduino as a select bit in order to covert uart to half-duplex. I, however, am specifically asking for other more passive methods. \$\endgroup\$ – niko Aug 5 '15 at 21:37
1
\$\begingroup\$

You say you want to use an Arduino Mega, which has an ATmega1280 MCU.

On ATmega1280 (and ATmega in general, mostly) UART Tx/Rx units override normal port operation. So once the Tx unit is on, you cannot set the Tx pin to Hi-Z (tri-state) unless you deactivate the Tx unit first.

Timing shouldn't be that critical, because the baud rates are 1Mbps max, while the ATmega1280 runs at 16 MHz assuming CKDIV8 is not programmed.

So in theory you should have time to switch. However, if their equivalent circuit is any indication, they actually do drive the Tx line, so you might produce a short when things go wrong, i.e. either your code takes too long to disable the Tx unit or you write while the Dynamixel responds.

It's actually not clear if the dynamixel actually drives the Tx line or if they don't (the circuit picture says CM-5, which is a master controller, not a slave).

I suggest you don't muck around with disabling/enabling the Tx unit in the ATmega1280, because you have to code more and possibly account for interrupts. Instead, put a resistor between Tx and Rx lines, like so:

schematic

simulate this circuit – Schematic created using CircuitLab

A) Assuming the Dynamixels have an internal pull-up resistor Rpu = 10kΩ, and assuming maximum input Voltage for a logic '0' Vil_max = 0.8V (just to be sure), we need the following resistor value Rx to reliably drive a '0': Ohm's Law

   5V * Rx / (Rx + 10kΩ) <= 0.8V
->                    Rx <= 1.9kΩ

B) Assuming the Dynamixels do not have an internal pull-up, just use Rx = 10kΩ..100kΩ. Your Tx unit will drive a '1' on bus idle, which will conveniently pull the bus up to 5V when your state machine logic expects the Dynamixel to answer.

In any case, the resistor will prevent shorts in case the Dynamixel and your controller drive at the same time. It will also act as a pull-up for your own Rx unit, so you won't get spurious data input when the Dynamixel isn't connected.

I suggest you use a multimeter to determine which of the two cases your application falls in. When in doubt, start with 1.8kΩ, see that your code works. Then move on to 100kΩ. If your code fails, you can be sure they use an internal Rpu, so stay 1.8kΩ. If everything works with 100kΩ, then, well... it works.

\$\endgroup\$
  • \$\begingroup\$ That was really informative, thank you FRob. I will try it today. \$\endgroup\$ – niko Aug 6 '15 at 10:35
  • \$\begingroup\$ Hi FRob I was wondering whether you have a suggestion how to avoid tx writing to rx? \$\endgroup\$ – niko Aug 10 '15 at 14:36
  • \$\begingroup\$ Hi. Did my answer work for you? Then please accept. I would recommend you don't ignore tx in your rd logic. Instead, use the tx message to verify that your tx operation works. \$\endgroup\$ – FRob Aug 10 '15 at 16:01
  • \$\begingroup\$ Yes, it works with any resistor value that you suggested. Should not the tx operation work anyway? I suppose I can connect a resistor to rx as well to avoid arduino writing to itself but not sure how to choose the value. \$\endgroup\$ – niko Aug 10 '15 at 22:58
  • 1
    \$\begingroup\$ @niko I'm afraid you cannot do that. You will only get to a point where you cannot receive anything anymore that way. You'll have to filter in software, which shouldn't be that hard. \$\endgroup\$ – FRob Aug 10 '15 at 23:04
0
\$\begingroup\$

As the servo is using TTL-level multidrop half-duplex link, you will either need to have your TX pin to be connected to the bus through a tri-state buffer, or programmatically set it as input direction once not transmitting. The RX can be connected to the bus constanly, but in this case you will have to ignore the self-sent packets, as they will be echoed. I would recommend a setup similar to this:

schematic

simulate this circuit – Schematic created using CircuitLab

\$\endgroup\$
  • \$\begingroup\$ Many thanks Eugene Sh. I am really new to this so please forgive me my incompetence. What is the initial problem with the TX pin? If it is configured as output from the arduino, would not that ignore all incoming data? About the RX pin, what exactly echoing a packet means? \$\endgroup\$ – niko Aug 5 '15 at 23:11
  • \$\begingroup\$ Tx will pull the line up when not transmitting, so it will interfere with any other transmission, so you need to disconnect it at that time. By echo I mean that if you connect tx with rx, it will eventually receive the own transmission s \$\endgroup\$ – Eugene Sh. Aug 6 '15 at 0:03

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.