Отключить DTR на ttyUSB0


11

Я подключаюсь от Pi к плате Arduino-клон. Проблема в том, что мне нужно отключить линию DTR, чтобы предотвратить сброс Arduino при подключении.

Я читал, что на RPi не возможно контролировать DTR, DCD и другие линии. Верно ли это для RPi глобально или только для контактов GPIO, используемых для последовательной связи?

Если возможно отключить DTR на USB-порту, как это сделать?

Ответы:


6

Свойства последовательного USB-конвертера не имеют ничего общего с аппаратным обеспечением хост-системы, а только с самим последовательным чипом USB и программным стеком хост-системы.

Пи должен использовать стандартные драйверы USB для Linux.

Следовательно, вы можете включить / отключить привязку DTR к открытию / закрытию порта с помощью обычного Linux-метода очистки hupclнастроек, как описано на сайте Arduino и в других местах:

stty -F /dev/ttyUSB0 -hupcl

Или замените / dev / ttyUSB0 тем файлом устройства, который соответствует вашему последовательному порту USB (например, первый подключенный Uno, вероятно, будет / dev / ttyACM0)

Даже в отношении собственного собственного последовательного порта PI это поведение DTR в конечном счете находится под контролем программного обеспечения - любой, кто утверждает иначе, игнорирует тот факт, что это всего лишь драйвер Linux, а не аппаратное обеспечение, которое знает какие-либо порты. открыт или закрыт. Фактическое аппаратное обеспечение порта может только сказать, что оно читается или записывается или реконфигурируется, ни одно из которых фактически не является синонимом открытия последовательного устройства.


Будет ли это работать только до тех пор, пока хост-пи не перезапустится?
user2395126

6

Пост @ChrisStrattons описывает, как использовать, stty -F /dev/ttyUSB0чтобы избежать зависания, которое приводит к сбросу. Вот фрагмент, чтобы сделать это в 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.

Обратите внимание, что точное число может быть при повторном подключении USB-кабеля, поэтому я определяю путь с помощью перетаскивания:

try:
    path = glob.glob('/dev/ttyACM*')[0]
except IndexError:
    # retry, error out, etc.
    pass

Я подтвердил, что это работает в Ubuntu на обычном ноутбуке x86_64 и Raspberry Pi 2.
Cerin

Есть ли какая-то причина использовать termios, скажем os.system("stty -F /dev/ttyUSB0 -hupcl"),? Кроме того, кстати, я заметил, что это не мешает сбросу Arduino при первом подключении к нему после включения хост-системы; это предотвращает его сброс при последующих подключениях. Что лучше, чем ничего. Но я бы хотел понять, как остановить переключение DTR.
Джейсон С

2
@JasonC Использование termiosсохраняет форк / exec (вызов) во внешнюю программу ( stty). Не уверен, что делать с DTR, думаю, я просто принял эту «особенность» и добавил некоторую логику (собственное рукопожатие при записи / чтении), чтобы определить, синхронизировались ли Arduino и приложение на Pi.
Лекенштейн

Мое окончательное решение состояло в том, чтобы добавить команду stty при загрузке pi, затем эхо-сигнал к порту для принудительного первого сброса и 3-секундную задержку для ожидания сброса arduino. Тогда мне не нужно больше думать об этом или беспокоиться об этом в скриптах Python. Я сделал это в rc.local, но где угодно. Стоимость +3 секунды пи время загрузки.
Джейсон C

3

Вы можете добавить резистор 120 Ом (или комбинацию, чтобы сделать резистор 120 Ом) между RESETи 5VЭто предотвратит полный сброс. Это наименее инвазивное решение, так как другие решения требуют удаления резистора или конденсатора с платы, что усложняет загрузку. Не держите резистор, если вы программируете. Убери это.

введите описание изображения здесь

Платы Leonardo не сбрасываются, даже если DTRсработал, но проблема возникает, когда вам нужно сбросить его удаленно, так как иногда он теряет соединение с Raspberry и вам необходимо физически сбросить его.


3
Я не уверен, что это заслуживает понижения. Это отстойно, и не основано на программном обеспечении, но после некоторого исследования оно кажется подходящим аппаратным решением.
Джейсон С

0

Если вы используете библиотеку Seria и pySerial, вы можете использовать:

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


-1

Вы можете использовать PySerial. Вот пример кода Python:

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

для дополнительных опций проверьте Pyserial.


1
Это не проблема библиотеки. Я alreadz пробовал 4 разных библиотеки, всегда один и тот же результат - команды DTR игнорируются.
Jnovacho

Если это точное утверждение о чем - то , что работает на другом Linux, он должен работать на пи , а также, как аппаратные пи только хостинг общего программного обеспечения Linux, а не однозначно участвует.
Крис Страттон

1
Это не работает В Linux это все еще вызывает сброс Arduino.
Cerin

1
Может подтвердить, что это не работает на любой версии Pi и Arduino, которую я имею (я не знаю, извините, я ничего не знаю об этих вещах, я не хочу знать, мне просто дали систему для отладки некоторого кода на, хе.) Кроме того, не уверен, что это связано, но stty -F /dev/ttyUSB0 -cdtrdsrотчеты invalid argument: -cdtrdsr.
Джейсон С
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.