PySerial write() мгновенный тайм-аут

ИЗМЕНИТЬ

Я узнал, в чем проблема, и ответил на свой вопрос.

Исходный вопрос под этой строкой

У меня есть последовательный мост между COM4 и COM5, реализованный в программном обеспечении (в частности, утилита Free Virtual Serial Configuration Utility жесткого диска)

У меня есть два разных скрипта Python, запускаемых в двух разных экземплярах Powershell, сначала получите:

import serial
receive = serial.Serial(port = 'COM5', baudrate = 9600)
text = receive.read(100)
receive.close()
print text

Затем отправитель:

import serial
send = serial.Serial(port = 'COM4', baudrate = 9600, timeout = 0)
send.write("Hello")
send.close()

При запуске скрипта-отправителя скрипт-получатель получает отправленное сообщение (Так что связь явно установлена), но скрипт-отправитель сразу же завершается с ошибкой:

Traceback (most recent call last):
  File ".\sending.py", line 3, in <module>
    send.writelines("Hello")
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 270, in write
    raise writeTimeoutError
serial.serialutil.SerialTimeoutException: Write timeout

Я получаю ту же ошибку, когда меняю сценарий отправителя на

send = serial.Serial(port = 'COM4', baudrate = 9600)

Итак, мой вопрос: что именно тайм-аут? Как предотвратить это? Я имею в виду, что данные отправляются, поэтому я, вероятно, мог бы просто поместить все это в блок try/except(and do nothing), но в долгосрочной перспективе это кажется плохим решением.


person medivh    schedule 19.08.2013    source источник
comment
Возможно, ошибка в программном мосте, я не видел этого исключения на аппаратных портах COM или USB-COM. Проходить (ничего не делать) при исключении плохо, потому что у вас есть тайм-ауты, и это снижает скорость передачи.   -  person eri    schedule 19.08.2013
comment
На самом деле, между тем, как я опубликовал это, и сейчас, я думаю, что нашел проблему - pyserial работает только с 32-битной архитектурой (по крайней мере, на платформах Windows) - файл serialwin32.py был подсказкой, может кто-нибудь подтвердить?   -  person medivh    schedule 19.08.2013
comment
У меня только что была эта проблема с мостом FTDI USB/RS-232. Драйвер, кажется, предотвращает уничтожение процесса (скрипт останавливается при исключении, python не может быть убит, CMD не закрывается), только вытягивание устройства (остерегайтесь BSOD) снова запускает процесс.   -  person handle    schedule 20.11.2014
comment
Это может быть другое дело - недавнее обновление драйвера FTDI заблокировало множество микросхем USB / RS-232. Я рекомендую пойти с другим поставщиком в будущем.   -  person medivh    schedule 16.12.2014


Ответы (2)


Подсказка находится в сообщении об ошибке[1]

File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 270, in write
raise writeTimeoutError

поэтому мы открываем этот файл и находим:

if self._writeTimeout != 0: # if blocking (None) or w/ write timeout (>0)
            # Wait for the write to complete.
            #~ win32.WaitForSingleObject(self._overlappedWrite.hEvent, win32.INFINITE)
            err = win32.GetOverlappedResult(self.hComPort, self._overlappedWrite, ctypes.byref(n), True)
            if n.value != len(data):
                raise writeTimeoutError

Прочтите это первое условное предложение еще раз:

if self._writeTimeout != 0:

поэтому давайте перепишем наш код до

send = serial.Serial(port = 'COM4', baudrate = 9600, timeout = 0)

становится

send = serial.Serial(port = 'COM4', baudrate = 9600, writeTimeout = 0)

и Et Voila: не исключение.

[1] Хорошо продуманные сообщения об ошибках? Это новое!

person medivh    schedule 19.08.2013

Проблема может заключаться в том, что интерфейс пытается соответствовать сигналам RTS, CTS, DSR или DTS. Вполне возможно, что если они не подключены должным образом виртуально, они могут таинственным образом повлиять на связь через тайм-аут.

Я бы также рекомендовал посмотреть конфигурацию используемого виртуального последовательного моста.

Одним из решений может быть игнорирование влияния с помощью rtscts=False и/или dsrdtr=False при открытии последовательного порта в Python.

Я мог бы использовать альтернативное решение для сниффинга связи с помощью hub4com, где я использовал параметр --octs = off, например таким образом, но виртуальные порты должны были быть созданы правильно до этого. hub4com --baud=115200 --route=0:All --route=1:All --route=2:All --no-default-fc-route=All:All --octs=off \\.\COM1 \\.\CNCB0 \\.\CNCB1

person JardaG    schedule 31.10.2020