Desativar DTR em ttyUSB0

11

Estou conectando do Pi à placa Arduino-clone. O problema é que eu preciso desativar a linha DTR, a fim de impedir que o Arduino seja redefinido na conexão.

Eu li que no RPi não é possível controlar DTR, DCD e outras linhas. Isso é verdade para o RPi globalmente ou apenas para os pinos GPIO usados ​​para comunicação serial?

Se é possível desativar o DTR na porta USB, como você consegue isso?

jnovacho
fonte

Respostas:

6

As propriedades de um conversor serial USB não têm nada a ver com o hardware do sistema de hospedagem, mas apenas com o próprio chip serial USB e com a pilha de software do sistema de hospedagem.

O pi deve estar usando drivers seriais USB Linux padrão.

Portanto, você pode ativar / desativar a ligação do DTR para abrir / fechar a porta através do método Linux usual de limpar a hupclconfiguração conforme documentado no site do Arduino e em outros lugares:

stty -F /dev/ttyUSB0 -hupcl

Ou substituindo / dev / ttyUSB0 por qualquer arquivo de dispositivo que realmente corresponda à sua porta serial USB (por exemplo, o primeiro Uno conectado provavelmente seria / dev / ttyACM0)

Mesmo com relação à porta serial nativa do PI, esse comportamento do DTR está sob controle de software - qualquer pessoa que argumenta o contrário está ignorando o fato de que é apenas o driver Linux, e não o hardware, que tem algum conhecimento da porta sendo aberto ou fechado. O hardware da porta real pode apenas dizer que está sendo lido ou gravado ou reconfigurado, nenhum dos quais é realmente sinônimo de abertura do dispositivo serial.

Chris Stratton
fonte
Isso funcionará apenas enquanto o pi de hospedagem não for reiniciado?
user2395126
6

A publicação @ChrisStrattons descreve como usar stty -F /dev/ttyUSB0para evitar o desligamento que resulta em uma redefinição. Aqui está um trecho para fazê-lo em 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.

Observe que o número exato pode estar ao reconectar o cabo USB, então eu detecto o caminho observando:

try:
    path = glob.glob('/dev/ttyACM*')[0]
except IndexError:
    # retry, error out, etc.
    pass
Lekensteyn
fonte
Eu já confirmou que isso funciona no Ubuntu em qualquer um laptop x86_64 genérico e um Raspberry Pi 2.
Cerin
Existe algum motivo para usar termiosmais, digamos os.system("stty -F /dev/ttyUSB0 -hupcl"),? Além disso, notei que isso não impede que o Arduino seja redefinido na primeira vez em que você se conectar a ele depois que o sistema host for ligado; impede que seja redefinido nas conexões subsequentes. O que é melhor que nada. Mas eu gostaria de descobrir como impedi-lo de alternar o DTR.
Jason C
2
@JasonC Using termiossalva um fork / exec (chamada) em um programa externo ( stty). Não sei o que fazer com o DTR, acho que acabei de aceitar esse "recurso" e adicionei alguma lógica (handshake personalizado por escrita / leitura) para detectar se o Arduino e o aplicativo no Pi entraram em sincronia.
Lekensteyn
Minha solução final foi adicionar o comando stty quando o pi inicializar, seguido de um eco na porta para forçar a primeira redefinição e um atraso de 3 segundos para aguardar a redefinição do arduino. Depois, não preciso mais pensar nisso ou me preocupar com isso nos scripts Python. Eu fiz isso no rc.local, mas em qualquer lugar. O custo é de +3 segundos de tempo de inicialização do pi.
Jason C
3

Você pode adicionar um resistor de 120Ohm (ou uma combinação para fazer 120Ohm) entre RESETe 5VIsso impedirá a redefinição completa. Isso é o menos invasivo, pois outras soluções exigem a remoção de um resistor ou capacitor da placa, o que complica os envios. Não guarde o resistor se estiver programando. Remova.

insira a descrição da imagem aqui

As placas Leonardo não são redefinidas mesmo que DTRsejam acionadas, mas o problema começa quando você precisa redefini-las remotamente, pois às vezes perde a conexão com o Raspberry e é necessário redefini-las fisicamente.

Piotr Kula
fonte
3
Não tenho certeza se isso merece um voto negativo. É péssimo fazê-lo, e não é baseado em software, mas depois de algumas pesquisas, parece ser a solução de hardware ideal para trabalhar.
Jason C
0

Se você usa a biblioteca Seria e pySerial, pode usar:

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

polo04
fonte
-1

Você pode usar o PySerial. Aqui está um exemplo no código Python:

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

para mais opções, selecione Pyserial.

hsantana8
fonte
1
Isso não é problema da biblioteca. Eu já tentei 4 bibliotecas diferentes, sempre o mesmo resultado - os comandos DTR são ignorados.
Jnovacho
Se esta é uma declaração precisa de algo que funciona em outro Linux, também deve funcionar no pi, pois o hardware do pi hospeda apenas software linux genérico e não está envolvido exclusivamente.
21915 Chris Stratton
1
Isso não funciona. No Linux, isso ainda faz com que o Arduino seja redefinido.
Cerin
1
Posso confirmar que isso não funciona em qualquer versão do Pi e do Arduino que eu tenho (não sei, desculpe, não sei nada dessas coisas, não quero saber, acabei de receber um sistema para depurar algum código Além disso, não tenho certeza se está relacionado, mas stty -F /dev/ttyUSB0 -cdtrdsrrelata invalid argument: -cdtrdsr.
Jason C