Почему / dev / rfcomm0 вызывает проблемы с PySerial?

Я подключаю свой Ubuntu box к настройке беспроводного считывания по Bluetooth. Я написал скрипт на Python для отправки последовательной информации через / dev / rfcomm0. Сценарий нормально подключается и работает в течение нескольких минут, но затем Python начнет использовать 100% ЦП и сообщения перестанут проходить через него.

Я могу открыть rfcomm0 в последовательном терминале и нормально общаться через него вручную. Когда я открываю его через терминал, кажется, что он работает бесконечно. Кроме того, я могу заменить приемник Bluetooth кабелем USB и изменить порт на / dev / ttyUSB0, и со временем у меня не возникнет никаких проблем.

Кажется, я либо делаю что-то не так с rfcomm0, либо PySerial не справляется с этим.

Вот сценарий:

import psutil
import serial
import string
import time

sampleTime = 1
numSamples = 5
lastTemp = 0

TEMP_CHAR = 't'
USAGE_CHAR = 'u'
SENSOR_NAME = 'TC0D'

gauges = serial.Serial()
gauges.port = '/dev/rfcomm0'
gauges.baudrate = 9600
gauges.parity = 'N'
gauges.writeTimeout = 0
gauges.open()

print("Connected to " + gauges.portstr)

filename = '/sys/bus/platform/devices/applesmc.768/temp2_input'

def parseSensorsOutputLinux(output):
    return int(round(float(output) / 1000))

while(1):
    usage = psutil.cpu_percent(interval=sampleTime)
    gauges.write(USAGE_CHAR)
    gauges.write(chr(int(usage))) #write the first byte
    #print("Wrote usage: " + str(int(usage)))

    sensorFile = open(filename)
    temp = parseSensorsOutputLinux(sensorFile.read())
    gauges.write(TEMP_CHAR)
    gauges.write(chr(temp))
    #print("Wrote temp: " + str(temp))

Есть мысли?

Спасибо.

РЕДАКТИРОВАТЬ: Вот пересмотренный код, использующий Python-BlueZ вместо PySerial:

import psutil
import serial
import string
import time
import bluetooth

sampleTime = 1
numSamples = 5
lastTemp = 0

TEMP_CHAR = 't'
USAGE_CHAR = 'u'
SENSOR_NAME = 'TC0D'

#gauges = serial.Serial()
#gauges.port = '/dev/rfcomm0'
#gauges.baudrate = 9600
#gauges.parity = 'N'
#gauges.writeTimeout = 0
#gauges.open()

gaugeSocket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
gaugeSocket.connect(('00:06:66:42:22:96', 1))

filename = '/sys/bus/platform/devices/applesmc.768/temp2_input'

def parseSensorsOutputLinux(output):
    return int(round(float(output) / 1000))

while(1):
    usage = psutil.cpu_percent(interval=sampleTime)
    #gauges.write(USAGE_CHAR)
    gaugeSocket.send(USAGE_CHAR)
    #gauges.write(chr(int(usage))) #write the first byte
    gaugeSocket.send(chr(int(usage)))
    #print("Wrote usage: " + str(int(usage)))

    sensorFile = open(filename)
    temp = parseSensorsOutputLinux(sensorFile.read())
    #gauges.write(TEMP_CHAR)
    gaugeSocket.send(TEMP_CHAR)
    #gauges.write(chr(temp))
    gaugeSocket.send(chr(temp))
    #print("Wrote temp: " + str(temp))

Кажется, либо Ubuntu должен закрывать / dev / rfcomm0 через определенное время, либо мой приемник Bluetooth портит вверх. Даже когда возникает ошибка BluetoothE, индикатор «подключен» на ресивере продолжает гореть, и только после повторного включения и выключения питания я могу повторно подключиться.

Я не уверен, как подойти к этой проблеме. Странно, что соединение будет работать нормально в течение нескольких минут (казалось бы, случайное количество времени), а затем обрывается.

В случае, если это помогает, приемник Bluetooth - это BlueSmirf Silver от Sparkfun. Нужно ли пытаться поддерживать соединение со стороны получателя или что-то в этом роде?

1
задан 17 May 2012 в 02:22

1 ответ

Оказывается, что буфер Bluetooth на ПК был переполнен, потому что я никогда не вызывал recv () в скрипте Python.

Аксессуар Bluetooth отправлял символы на ПК, которые сценарий игнорировал и которые неизбежно приводили к переполнению буфера. Это переполнение, по-видимому, приводит к блокировке канала rfcomm до тех пор, пока буфер не будет прочитан.

Вот рабочий сценарий, для дальнейшего использования:

import psutil
import serial
import string
import time
import bluetooth

sampleTime = 1
numSamples = 5
lastTemp = 0

TEMP_CHAR = 't'
USAGE_CHAR = 'u'
SENSOR_NAME = 'TC0D'

filename = '/sys/bus/platform/devices/applesmc.768/temp2_input'


def parseSensorsOutputLinux(output):
    return int(round(float(output) / 1000))

def connect():
    while(True):    
        try:
            gaugeSocket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
            gaugeSocket.connect(('00:06:66:42:22:96', 1))
            break;
        except bluetooth.btcommon.BluetoothError as error:
            gaugeSocket.close()
            print "Could not connect: ", error, "; Retrying in 10s..."
            time.sleep(10)
    return gaugeSocket;

gaugeSocket = connect()
while(True):
    usage = psutil.cpu_percent(interval=sampleTime)
    sensorFile = open(filename)
    temp = parseSensorsOutputLinux(sensorFile.read())
    try:
        gaugeSocket.send(USAGE_CHAR)
        gaugeSocket.send(chr(int(usage)))
        #print("Wrote usage: " + str(int(usage)))

        gaugeSocket.send(TEMP_CHAR)
        gaugeSocket.send(chr(temp))
        print gaugeSocket.recv(1024)
        #print("Wrote temp: " + str(temp))
    except bluetooth.btcommon.BluetoothError as error:
        print "Caught BluetoothError: ", error
        time.sleep(5)
        gaugeSocket = connect()
        pass

gaugeSocket.close()

Главное изменение в добавлении строки

gaugeSocket.recv(1024)

, которая очищает буфер «все в порядке» сообщения, отправленные обратно с удаленного устройства.

0
ответ дан 17 May 2012 в 02:22

Другие вопросы по тегам:

Похожие вопросы: