1

I am using one XBee S2 as coordinator (API mode), 3 XBee S2 as routers (AT mode). The routers are connected to Naze32 board (using MSP). On the computer side, I have a GUI using wxpython to send out command to request data. The GUI will send out command to XBee (Coordinator) to request data from the routers every second.

I am using python-xbee library to do the send and receive frame job on computer side. Once new data received, it will notify the GUI to update some labels with the new data.

Currently I am able to send and receive frames outside a thread, but once I move the send and receive functions to a thread, it will never be able to read a frame any more. As I don't want to let the serial stop the GUI or make it not responding. Another thing is if I close the thread, then start new thread with xbee again, it will not work any more.

The communication is controlled by a button on the GUI; once "Turn on" clicked, the "self._serialOn" will set to True, then create new thread; once "Turn off" clicked, "self._serialOn" will set to False and thread is stopped.

How can I fix this problem? Thanks in advance.

class DataExchange(object):
    def __init__(self):
        self._observers = []
        self._addressList = [['\x00\x13\xA2\x00\x40\xC1\x43\x0F', '\xFF\xFE'],[],[]]
        self._serialPort = ''
        self._serialOn = False
        self.workerSerial = None

    # serial switch
    def get_serialOn(self):
        return self._serialOn

    def set_serialOn(self, value):
        self._serialOn = value
        print(self._serialOn)
        if self.serialOn == True:
            EVT_ID_VALUE = wx.NewId()
            self.workerSerial = WorkerSerialThread(self, EVT_ID_VALUE, self.serialPort, self.addressList)
            self.workerSerial.daemon = True
            self.workerSerial.start()
        elif self.serialOn == False:
            self.workerSerial.stop()
            del(self.workerSerial)
            self.workerSerial = None

    serialOn = property(get_serialOn, set_serialOn)

class WorkerSerialThread(threading.Thread):
    def __init__(self, notify_window, id, port, addresslist):
        threading.Thread.__init__(self)
        self.id = id
        self.serialPort = port
        self.addressList = addresslist

        self.counter = 0
        self._notify_window = notify_window
        self.abort = False
        self.sch = SerialCommunication(self.serialPort, self.addressList)
        try:
            self.sch.PreLoadInfo()
        except:
            print('failed')

    def run(self):
        while not self.abort:
            self.counter += 1
            print('Serial Working on '+str(self.id))
            self.sch.RegularLoadInfo()
            #wx.PostEvent(self._notify_window, DataEvent(self.counter, self.id))
            time.sleep(1)

    def stop(self):
        self.sch.board.stop()
        self.abort = True
Tairan Liu
  • 37
  • 1
  • 10

1 Answers1

0

This question was finally solved with multiprocessing rather than threading of python.

In the manual of python-xbee, it mentioned that "... Make sure that updates to external state are thread-safe...". Also in the source code, threading was used.

So I guess in this case threading will cause problem.

Anyway, using multiprocessing it finally works.

Tairan Liu
  • 37
  • 1
  • 10