2013-08-29 4 views
1

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

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 функцию() в приведенном выше коде stringReceived(), программа никогда не входит в эту функцию.

Я также попытался выше программы с протоколом 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.

ответ

1

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

При подклассе Int16StringReceiver вместо этого вы должны переопределить stringReceived.

+0

Я заменил данные dataReceived функцией stringReceived и запустил код. Но когда я это делаю, программа даже не вводит функцию stringReceived. Я также попробовал модифицированную версию вышеперечисленных программ с помощью LineReceived protcol, и здесь тоже у меня такая же проблема с фрагментированными данными из функции dataReceived. – siva82kb

+0

Почему вы переключаетесь между Int16StringReceiver и LineReceiver? Какой протокол вы пытаетесь говорить здесь? –

+0

Я пробовал протокол LineReceiver, так как хотел посмотреть, сработало ли оно. Протокол с устройства bluetooth реализован в виде линейного протокола. Я новичок в Twisted, и поэтому пытался попробовать разные вещи. – siva82kb

1

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

Вы пытались использовать библиотеку 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-подключенную радиостанцию.

+0

Мне кажется, что вы можете полагаться на поведение «LineReceiver», чтобы убедиться, что ваши данные не фрагментированы. В этом случае используйте pyserial, чтобы увидеть, какой разделитель он отправляет, а затем установите его, написав: 'delimiter = '\ n'' сразу после строки' class'. [Пример] (http://www.wallix.org/2011/08/30/getting-started-with-twisted/) – DrRobotNinja

+0

Спасибо. Я решил реализовать с использованием последовательного модуля с отдельными потоками для чтения и записи, так как это будет частью более крупного приложения с графическим интерфейсом. Я могу читать и писать без каких-либо проблем. – siva82kb

+2

Переключение с Twisted на потоки, чтобы устранить проблемы с кадрированием при взаимодействии с последовательным устройством, возможно, просто означает, что вы спрятали ошибку, чтобы она не отображалась до тех пор, пока код не будет развернут в реальном мире, где время немного отличается от времени ваша машина разработки и ваш код начинают проигрывать в различных условиях гонки. –

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