pyserial поток зависает в операторе serial.in_waiting () - PullRequest
0 голосов
/ 31 января 2020

У меня есть псевдоним, который висит в неожиданном месте; проверка последовательного порта на байты в очереди. Весь последовательный ввод осуществляется в этой теме; Главное - это прежде всего менеджер дисплеев. init выполняется нормально, после выполнения подпрограммы run он зависает в операторе «Trace ('In_waiting = {}'. Format (self.serial.in_waiting ()))». main - это не процессорный боров - он обновляет дисплей, затем ждет 1,0 секунды - этот код хорошо отлажен (говорит наивный программист ;-)). Других потоков нет, хотя есть обратные вызовы для выводов GPIO. Ввод поступает с выводов RASPi UART.

Мне не имеет смысла зависать в этом месте. Я пробовал это с различными значениями тайм-аута, включая None и 0. Документация, кажется, ясно указывает на возврат 0 или n являются единственными вариантами. Я, вероятно, упускаю что-то очевидное, но это ускользает от меня.

class Monitor_PE_Devices_Thread(threading.Thread):
# Thread to monitor all of the PE devices.  All updating of the device_list items occurs
# here.
    def __init__(self):
        global device_list
        threading.Thread.__init__(self)
        Log.Debug('PE Monitoring thread initialized')
        self.buffer = ''
        self.port = '/dev/ttyAMA0'
        self.speed = 9600
        self.serial = serial.Serial(port=self.port, baudrate=self.speed, timeout=0.5)
        if self.serial.is_open: Trace('Serial port {} opened'.format(self.serial.name))
        Log.Debug('Monitoring the following devices:')
        for d in device_list:
            Log.Debug('   DevID[{}]: Name={}'.format(d, device_list[d][0]))

    def process_PE_response(self, devid, data): <block compressed>

    def read_line(self):  <block compressed>

    def run(self):
    # Main loop for PE device monitoring
        global kill_threads, device_list

        Log.Debug('PE Monitoring thread started')
        while not kill_threads:
            Trace('Top of read serial loop')
            Trace('Port status={}'.format(self.serial.is_open))
            Trace('In_waiting={}'.format(self.serial.in_waiting()))
            if self.serial.in_waiting() > 0:
                line = self.read_line()
                if len(line) > 0 and line[0] == 'a':
                    devid = line[1:3]
                    data = line[3:]
                    Trace('Data recieved for dev[{}]: {}'.format(devid, data))
                    dev = device_list.get(devid, None)
                    if dev != None:
                        device_list[devid][3] = utcnow()
                        self.process_PE_response(devid, data)
                    else:
                        Log.Debug('Unknown device id {} - ignored'.format(devid))
                else:
                    Log.Info('Invalid serial data: {}'.format(line))

Среда: python 3, pyserial 3, Raspberry Pi 3, Buster Lite, pygame

1 Ответ

0 голосов
/ 31 января 2020

В pySerial 3.0 in_waiting - это свойство , а не метод.

Поэтому при использовании self.serial.in_waiting(), Python должно повысить TypeError, потому что значение in_waiting в int, которое не вызывается.

Небольшой пример:

In [5]: class Test: 
   ...:     def __init__(self, a): 
   ...:         self._a = a 
   ...:          
   ...:     @property 
   ...:     def a(self): 
   ...:         return self._a 
   ...:                                                                                                  

In [6]: t = Test(2)                                                                                      
Out[6]: <__main__.Test at 0x8042660d0>

In [7]: t.a                                                                                              
Out[7]: 2

In [8]: t.a()                                                                                            
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-47b4c8d89978> in <module>
----> 1 t.a()

TypeError: 'int' object is not callable

Возможно, ваша программа зависание, потому что это происходит в другом потоке.

Необработанное исключение должно завершиться Monitor_PE_Devices_Thread.run().

В вашем основном потоке, который обновляет тест отображения, если Monitor_PE_Devices_Thread все еще выполняется с использованием его is_alive() метод.

...