Comunicación serial bidireccional de un solo cable: configuración de hardware

Tengo varios servos que pueden dar información de retroalimentación que quiero leer. Los servos usan un protocolo especial, por lo que necesito usar el pin Rx/Tx en mi Arduino Mega para comunicarme con ellos. El problema es que un servo tiene solo un pin de comunicación serial, por lo que no puedo usar el cableado Rx/Tx habitual.

Escuché que hay algunas configuraciones de hardware para convertir correctamente las señales UART al tipo semidúplex. Una es usar 2 resistencias conectadas a Rx y Tx de Arduino y el pin del servo. Otra es usar un transistor. Sin embargo, no pude encontrar dibujos y reglas de circuitos exactos para elegir los valores de las resistencias o el transistor. ¿Alguien puede proporcionar más información sobre eso y explicar en términos de hardware exactamente cómo estas configuraciones evitan que el Tx escriba en el Rx y la retroalimentación del servo escriba en el Tx?

EDITAR: El servo es Dynamixel XL-320 ( http://support.robotis.com/en/product/dynamixel/xl-320/xl-320.htm ). La comunicación es en serie semidúplex: puedo escribir en el servo, pero también puedo leer valores, por ejemplo, cargar (por lo tanto, necesito usar los pines Rx y Tx en mi arduino). NOTA: el manual del servo propone usar un multiplexor y un pin digital en el arduino como un bit de selección para convertir uart en semidúplex. Sin embargo, estoy pidiendo específicamente otras alternativas más pasivas.

¿Qué es el "protocolo especial"? ¿Es serial semidúplex? O es solo de una manera? Si es lo último, ¿por qué necesita dos vías?
¿O utiliza la interfaz "One-Wire" ( en.wikipedia.org/wiki/1-Wire )? ¿Qué tal un número de pieza y un enlace a la hoja de datos para su servo?
Danos más información sobre tus servos niko
EDITAR: El servo es Dynamixel XL-320 support.robotis.com/en/product/dynamixel/xl-320/xl-320.htm . La comunicación es en serie semidúplex: puedo escribir en el servo, pero también puedo leer valores, por ejemplo, cargar (por lo tanto, necesito usar los pines Rx y Tx en mi arduino). NOTA: el manual del servo propone usar un multiplexor y un pin digital en el arduino como un bit de selección para convertir uart en semidúplex. Yo, sin embargo, estoy pidiendo específicamente otros métodos más pasivos.

Respuestas (2)

Dices que quieres usar un Arduino Mega, que tiene un MCU ATmega1280.

En ATmega1280 (y ATmega en general, en su mayoría), las unidades UART Tx/Rx anulan el funcionamiento normal del puerto. Entonces, una vez que la unidad Tx está encendida, no puede configurar el pin Tx en Hi-Z (tri-state) a menos que desactive la unidad Tx primero.

El tiempo no debería ser tan crítico, porque las tasas de baudios son de 1 Mbps como máximo, mientras que el ATmega1280 funciona a 16 MHz, suponiendo que CKDIV8 no esté programado .

Entonces, en teoría, deberías tener tiempo para cambiar. Sin embargo, si su circuito equivalente es una indicación, en realidad manejan la línea Tx, por lo que puede producir un cortocircuito cuando las cosas van mal, es decir, su código tarda demasiado en desactivar la unidad Tx o escribe mientras Dynamixel responde.

En realidad, no está claro si el dynamixel realmente impulsa la línea Tx o no (la imagen del circuito dice CM-5, que es un controlador maestro, no un esclavo).

Le sugiero que no juegue con la desactivación/activación de la unidad Tx en el ATmega1280, porque tiene que codificar más y posiblemente tener en cuenta las interrupciones. En su lugar, coloque una resistencia entre las líneas Tx y Rx, así:

esquemático

simular este circuito : esquema creado con CircuitLab

A) Asumiendo que los Dynamixels tienen una resistencia pull-up interna Rpu = 10kΩ, y asumiendo el voltaje de entrada máximo para un '0' lógico Vil_max = 0.8V (solo para estar seguros), necesitamos el siguiente valor de resistencia Rx para manejar un ' 0': Ley de Ohm

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

B) Asumiendo que los Dynamixels no tienen un pull-up interno, solo use Rx = 10kΩ..100kΩ. Su unidad Tx generará un '1' en el bus inactivo, lo que convenientemente elevará el bus hasta 5 V cuando la lógica de su máquina de estado espera que el Dynamixel responda.

En cualquier caso, la resistencia evitará cortocircuitos en caso de que el Dynamixel y su controlador funcionen al mismo tiempo. También actuará como un pull-up para su propia unidad Rx, por lo que no obtendrá una entrada de datos falsa cuando el Dynamixel no esté conectado.

Le sugiero que use un multímetro para determinar en cuál de los dos casos cae su aplicación. En caso de duda, comience con 1.8kΩ, vea que su código funcione. Luego pase a 100kΩ. Si su código falla, puede estar seguro de que usan un Rpu interno, así que manténgase en 1.8kΩ. Si todo funciona con 100kΩ, entonces, bueno... funciona.

Eso fue realmente informativo, gracias FRob. Lo intentaré hoy.
Hola, FRob, me preguntaba si tienes alguna sugerencia sobre cómo evitar que tx escriba en rx.
Hola. ¿Te funcionó mi respuesta? Entonces por favor acepte. Le recomendaría que no ignore tx en su lógica rd. En su lugar, use el mensaje tx para verificar que su operación tx funcione.
Sí, funciona con cualquier valor de resistencia que sugiera. ¿No debería funcionar la operación tx de todos modos? Supongo que también puedo conectar una resistencia a rx para evitar que Arduino se escriba a sí mismo, pero no estoy seguro de cómo elegir el valor.
@niko Me temo que no puedes hacer eso. Solo llegarás a un punto en el que ya no podrás recibir nada de esa manera. Tendrás que filtrar el software, lo que no debería ser tan difícil.
Sí, ya tengo el filtro en el software. ¡Muchas gracias por la ayuda!

Como el servo está utilizando un enlace semidúplex multipunto de nivel TTL, necesitará tener su pin TX para estar conectado al bus a través de un búfer de tres estados, o configurarlo mediante programación como dirección de entrada una vez que no esté transmitiendo. El RX se puede conectar al bus constantemente, pero en este caso deberá ignorar los paquetes autoenviados, ya que se repetirán. Recomendaría una configuración similar a esta:

esquemático

simular este circuito : esquema creado con CircuitLab

Muchas gracias Eugene Sh. Soy realmente nuevo en esto así que por favor perdonen mi incompetencia. ¿Cuál es el problema inicial con el pin TX? Si está configurado como salida del arduino, ¿no ignoraría eso todos los datos entrantes? Acerca del pin RX, ¿qué significa exactamente hacer eco de un paquete?
Tx levantará la línea cuando no esté transmitiendo, por lo que interferirá con cualquier otra transmisión, por lo que debe desconectarlo en ese momento. Por eco quiero decir que si conecta tx con rx, eventualmente recibirá la propia transmisión s