Deshabilitar DTR en ttyUSB0

11

Me estoy conectando de Pi a la placa Arduino-clone. El problema es que necesito deshabilitar la línea DTR para evitar que Arduino se reinicie al conectarse.

He leído que en RPi no es posible controlar DTR, DCD y otras líneas. ¿Es esto cierto para RPi a nivel mundial o solo para pines GPIO utilizados para la comunicación en serie?

Si es posible desactivar DTR en el puerto USB, ¿cómo lo logras?

jnovacho
fuente

Respuestas:

6

Las propiedades de un convertidor serie USB no tienen nada que ver con el hardware del sistema de alojamiento, sino solo con el chip serie USB en sí y la pila de software del sistema de alojamiento.

El pi debe usar controladores serie USB USB de Linux.

Por lo tanto, puede habilitar / deshabilitar el enlace de DTR al puerto abrir / cerrar a través del método habitual de Linux para borrar la hupclconfiguración como se documenta en el sitio Arduino y en otros lugares:

stty -F /dev/ttyUSB0 -hupcl

O reemplazando / dev / ttyUSB0 con cualquier archivo de dispositivo que realmente corresponda a su puerto serie USB (por ejemplo, el primer Uno conectado probablemente sería / dev / ttyACM0)

Incluso con respecto al puerto serie nativo del PI, este comportamiento de DTR está en última instancia bajo el control del software: cualquier persona que argumenta lo contrario ignora el hecho de que es solo el controlador de Linux, y no el hardware, el que tiene conocimiento del puerto. abierto o cerrado El hardware del puerto real solo puede decir que se está leyendo, escribiendo o reconfigurando, ninguno de los cuales es sinónimo de abrir el dispositivo en serie.

Chris Stratton
fuente
¿Esto solo funcionará mientras no se reinicie el host pi?
user2395126
6

La publicación @ChrisStrattons describe cómo usar stty -F /dev/ttyUSB0para evitar el bloqueo que resulta en un reinicio. Aquí hay un fragmento para hacerlo en Python:

import termios

path = '/dev/ttyACM0'

# Disable reset after hangup
with open(path) as f:
    attrs = termios.tcgetattr(f)
    attrs[2] = attrs[2] & ~termios.HUPCL
    termios.tcsetattr(f, termios.TCSAFLUSH, attrs)

ser = serial.Serial(path, 9600)
# etc.

Tenga en cuenta que el número exacto puede al volver a enchufar el cable USB, por lo que detecto la ruta al presionar:

try:
    path = glob.glob('/dev/ttyACM*')[0]
except IndexError:
    # retry, error out, etc.
    pass
Lekensteyn
fuente
He confirmado que esto funciona en Ubuntu en una computadora portátil genérica x86_64 y una Raspberry Pi 2.
Cerin
¿Hay alguna razón para usar termiosmás, por ejemplo os.system("stty -F /dev/ttyUSB0 -hupcl")? Además, por cierto, noté que esto no impide que Arduino se reinicie la primera vez que se conecta a él después de encender el sistema host; evita que se reinicie en conexiones posteriores. Que es mejor que nada. Pero desearía poder encontrar la manera de evitar que cambie DTR.
Jason C
2
@JasonC Using termiosguarda un fork / exec (llamada) en un programa externo ( stty). No estoy seguro de qué hacer con el DTR, creo que acabo de aceptar esta "característica" y agregué algo de lógica (apretón de manos personalizado al escribir / leer) para detectar si el Arduino y la aplicación en el Pi se sincronizaron.
Lekensteyn el
Mi solución final fue agregar el comando stty cuando se inicia el pi, seguido de un eco en el puerto para forzar ese primer reinicio, y un retraso de 3 segundos para esperar el reinicio de arduino. Entonces no tengo que pensar más en eso después de eso o preocuparme en los scripts de Python. Lo hice en rc.local pero donde sea. El costo es +3 segundos de tiempo de arranque pi.
Jason C el
3

Puede agregar una resistencia de 120 ohmios (o una combinación para producir 120 ohmios) entre RESETy 5Vesto evitará que se restablezca por completo. Esto es lo menos invasivo ya que otras soluciones requieren quitar una resistencia o un condensador de la placa, complica las cargas. No guarde la resistencia si está programando. Quitarlo

ingrese la descripción de la imagen aquí

Las placas Leonardo no se reinician aunque DTRse activen, pero el problema comienza cuando necesita reiniciarlo de forma remota, ya que a veces pierde la conexión a Raspberry y tiene que reiniciarlo físicamente.

Piotr Kula
fuente
3
No estoy seguro de que esto merezca un voto negativo. Es un asco hacerlo, y no está basado en software, pero después de algunas investigaciones parece ser la solución de hardware que funciona.
Jason C
0

Si usa la biblioteca Seria y pySerial, puede usar:

ser = serial.Serial ('/ dev / ttyACM0', 9600, dsrdtr = True)

polo04
fuente
-1

Puedes usar PySerial. Aquí hay un ejemplo de código Python:

port =serial.Serial(
    "/dev/ttyUSB0",
    baudrate=57600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    dsrdtr = False
    )

para más opciones comprobar PySerial.

hsantana8
fuente
1
Este no es un problema de la biblioteca. Ya probé 4 libs diferentes, siempre el mismo resultado: los comandos DTR se ignoran.
jnovacho
Si esta es una declaración precisa de algo que funciona en otro Linux, también debería funcionar en el pi, ya que el hardware pi solo aloja software genérico de Linux y no está involucrado de manera exclusiva.
Chris Stratton
1
Esto no funciona En Linux, esto todavía hace que Arduino se reinicie.
Cerin
1
Puedo confirmar que esto no funciona en cualquier versión de Pi y Arduino que tenga (no sé, lo siento, no sé nada de estas cosas, no quiero saber, me acaban de dar un sistema para depurar algún código encendido, je.) Además, no estoy seguro si está relacionado, pero stty -F /dev/ttyUSB0 -cdtrdsrinforma invalid argument: -cdtrdsr.
Jason C