2014-10-23 7 views
0

У меня есть USB-соединение между Macbook Air и микроконтроллером, который непрерывно передает шестнадцатеричные данные. Я пытаюсь использовать PyUSB в Python для получения данных. Я использовал PyUSB для подключения к микроконтроллеру следующим образом:Почему я не могу вызвать функцию pyUSB dev.read() несколько раз, не получая ошибку тайм-аута?

import usb 
dev = usb.core.find(idVendor=0xXXXX, idProduct=0xXXXX) 
dev.set_configuration() 
cfg = dev.get_active_configuration() 
intf = cfg[(0,0)] 
ep = usb.util.find_descriptor(intf,custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT) 

Затем я попытался прочитать данные из устройства в массив с помощью метода dev.read(), который работал в первый раз:

dev.read(0x1,100,100) 

Это произвело массив длиной 100, но после того, как я назвал dev.read (0x1,100,100) еще несколько раз (и получил еще несколько массивов) я начал получать эту ошибку:

dev.read(0x1,100,100) 

Traceback (most recent call last): 

File "stdin", line 1, in <module> 

File "/Users/dimachy/anaconda/lib/python2.7/site-packages/usb/core.py", line 918, in read 
self.__get_timeout(timeout)) 

File "/Users/dimachy/anaconda/lib/python2.7/site-packages/usb/backend/libusb1.py", line 777, in bulk_read 
timeout) 

File "/Users/dimachy/anaconda/lib/python2.7/site-packages/usb/backend/libusb1.py", line 880, in __read 
_check(retval) 

File "/Users/dimachy/anaconda/lib/python2.7/site-packages/usb/backend/libusb1.py", line 560, in _check 
raise USBError(_str_error[ret], ret, _libusb_errno[ret]) 

usb.core.USBError: [Errno 60] Operation timed out 

Почему это происходит? Я подозреваю, что не понимаю, как буферы хранят данные в разных местах во время передачи данных, но не смогли найти четкое объяснение того, что происходит.

ответ

1

Какова длина ответа, который вы возвращаете? Как вы структурируете dev.read, вы сообщаете PyUSB, что ответ должен быть длиной 100 байт, и если вы не получите 100 байт за 100 мс, выбросите исключение тайм-аута. Если ваше устройство реагирует на меньшее сообщение, вы получите сообщение об ошибке после достижения 100 мс, даже если эта длина сообщения верна. Итак, вы можете сделать 1 из 2 вещей:

1) удалить переменную таймаута. В этом случае PyUSB будет ожидать время по умолчанию и ответ отчета без ошибки. Если вам нужно тайм-аут быстрее, чем по умолчанию, это не поможет

2) Еще лучше, если вы знаете длину ответов, которые вы получаете (кажется, что у вас есть некоторые данные, так что это может быть так), используйте это значение вместо 100 байтов. Это даст вам данные обратно без ошибок и по-прежнему позволит вам установить переменную тайм-аута.

+0

Благодарим вас за отзыв - данные _supposed_ являются непрерывным потоком (он является датчиком и начинает передачу данных сразу же после его включения) примерно в 16 килобайтах в секунду, поэтому 100 байтов должны быть легко доставлены в 100 миллисекунд. Я попробовал снова с очень большим таймаутом и пропустил ту же ошибку после нескольких звонков. – dimachidy

+0

Даже если это «непрерывный поток» данных, USB передает и принимает в пакетах, и вы не получаете пакет бесконечной длины. Вы можете отправить только один запрос для запуска потока данных, но данные вернутся в куски заданной длины. Я не уверен, что такое точное приложение, поэтому скажите, что ваш микрофон должен сообщать о температуре для 3 датчиков. Он будет считывать температуру каждого из них в определенный момент времени, упаковывать их вместе в пакет и передавать эти данные через USB. Затем, как только будет установлен установленный временной интервал, он повторит процесс. –

+0

(con't) Вы сообщаете PyUSB, что ожидаемый пакет должен быть длиной 100 байтов, и если он не получит, что в течение периода ожидания выдаст ошибку.Что вам нужно сделать, следуйте моим инструкциям выше, чтобы не дать одной команде чтения отбросить ошибку, а затем закодировать запрос на чтение до тех пор, пока вы не будете готовы прекратить чтение (например, временной интервал, пользователь нажимает кнопку, что угодно). –

0

старайтесь не фиксировать размер полученных пакетов, если вы не уверены. Если это возможно, обратите внимание на максимальный размер пакета конечной точке и использовать в качестве второго аргумента для метода чтения:

endpoint.wMaxPacketSize 

Как правило, вы можете увидеть или decriptors, конечные точки и интерфейсы, введя следующую команду в терминале:

lsusb -d vendorId:productId -v 

Это предоставит вам максимальный размер пакета напрямую. Надеюсь, это поможет вам исправить ошибку.

 Смежные вопросы

  • Нет связанных вопросов^_^