Twisted serialport dataReceived () предоставляет фрагментированные данные

Я использую tyring для реализации программы python, используя Twisted, для связи с Bluetooth-устройством. Ниже приведен пример кода, который я реализовал:

from twisted.internet import protocol, reactor from twisted.internet.serialport import SerialPort from twisted.protocols import basic class DeviceBluetooth(basic.Int16StringReceiver): def connectionMade(self): print 'Connection made!' self.sendString('[01] help\n') def dataReceived(self, data): print"Response: {0}".format(data) print "-----" print "choose message to send: " print "1. Stim on" print "2. Stim off" print "3. Stim status" print "4. Help" # user input ch = input("Choose command :: ") if int(ch) == 1: self.sendString('[02] stim on\n') elif int(ch) == 2: self.sendString('[03] stim off\n') elif int(ch) == 3: self.sendString('[04] stim ?\n') elif int(ch) == 4: self.sendString('[05] help\n') else: reactor.stop() SerialPort(DeviceBluetooth(), 'COM20', reactor, baudrate=115200) reactor.run() 

Когда я запускаю программу, иногда я получаю ответ, а иногда я ничего не получаю. И в большинстве случаев длинные ответы фрагментируются как часть следующего сообщения. У меня есть гипертерминал, чтобы убедиться, что я получаю соответствующий ответ от устройства Bluetooth. Итак, проблема связана с моим кодом.

Есть ли что-то, что я делаю неправильно в своем коде?


Дополнительная модификация / коррекция

Когда я заменяю функцию dataReceived () в приведенном выше коде строкойReceived (), программа никогда не входит в эту функцию.

Я также попытался выполнить вышеописанную программу с помощью протокола LineReceiver, как показано ниже:

 from twisted.internet import protocol, reactor from twisted.internet.serialport import SerialPort from twisted.protocols import basic class DeviceBluetooth(basic.LineReceiver): def connectionMade(self): print 'Connection made!' self.sendLine('[01] help') def dataReceived(self, data): print"Response: {0}".format(data) print "-----" print "choose message to send: " print "1. Stim on" print "2. Stim off" print "3. Stim status" print "4. Help" # user input ch = input("Choose command :: ") if int(ch) == 1: self.sendLine('[02] stim on') elif int(ch) == 2: self.sendLine('[03] stim off') elif int(ch) == 3: self.sendLine('[04] stim ?') elif int(ch) == 4: self.sendLine('[05] help') else: reactor.stop() SerialPort(DeviceBluetooth(), 'COM20', reactor, baudrate=115200) reactor.run() 

У меня такая же проблема, как и раньше, с фрагментированными данными из функции dataReceived.

Подклассы протокола Int16StringReceiver которые реализуют кадрирование сообщений с использованием двухбайтовых (16 бит) префиксов. Однако он переопределяет dataReceived который является методом, который реализует это обрамление. Это отключает кадрирование и просто доставляет любые байты, которые должны быть прочитаны из соединения, – независимо от того, какой размер они могут быть прочитаны.

Когда вы подклассифицируете Int16StringReceiver , вы stringReceived вместо этого переопределить stringReceived .

Для большинства моих bluetooth-работы я использовал 8-битные целые числа, поэтому я бы рекомендовал использовать Int8StringReceiver . Протокол LineReceiver ожидает LineReceiver последовательности, которая по умолчанию соответствует '\r\n' (и радиоусилителям Bluetooth я использую return '\r' ), поэтому несоответствие последовательности endline будет препятствовать тому, чтобы код когда-либо входил.

Вы пытались использовать библиотеку non-Twisted для отладки? Я настоятельно рекомендую Twisted специально для производственных сред, но PySerial – отличный способ опроса серийных данных. ( easy_install pyserial должен сделать трюк.) Попробуйте этот код:

 import serial s = serial.Serial('COM20', 115200, timeout=0) data = s.read(1024) print repr(data) 

Не забудьте использовать timeout=0 так как это сделает ваше read неблокирующимся. Это позволит вам точно проверить, какие данные выдаются радио Bluetooth.

Наконец, в зависимости от того, какое Bluetooth-радио вы используете, Windows может решить перемещать COM20 , особенно если вы используете USB-подключенную радиостанцию.