Skip to content Skip to sidebar Skip to footer

Small Example For Pyserial Using Threading

Can anyone please give me a small and simple example on how to use threading with pyserial communication. I am googling for over three days and I am still illeterate and I dont eve

Solution 1:

There's no factual basis for the claim by Task2:

print "I stopped Task 1 to start and execute Thread 2"

Your implementation starts one thread then immediately starts the other without stopping the first. This means that the ser.read and ser.write commands could interfere with each other.

The simplest thing you could do to address this is to introduce variables that allow communication:

import sys
import os
import time
import threading

thread_flag = None


def Report(s):
    print s
    sys.stdout.flush() # helps to ensure messages from different threads appear in the right order

def Stop():
    global thread_flag
    thread_flag = 'stop'

def Task1(ser):

    Report("Inside Thread 1")
    global thread_flag
    thread_flag = 'go'

    while True:

        Report("Thread 1 waiting for permission to read")
        while thread_flag != 'go': time.sleep( 0.001 )

        while thread_flag == 'go':
            Report("Thread 1 is reading")
            #ser.write('\x5A\x03\x02\x02\x02\x09') # Byte ArrayTo Control a MicroProcessing Unit
            #b = ser.read(7)
            #Report(b.encode('hex'))
            time.sleep(1)

        if thread_flag == 'stop': break
        else: thread_flag = 'paused'   # signals that the inner loop is done

    Report("Thread 1 complete")


def Task2(ser):

    Report("Inside Thread 2")

    global thread_flag
    thread_flag = 'pause' # signals Task1 to pause
    while thread_flag != 'paused': time.sleep(0.001) # waits for Task1 inner loop to exit
    Report("I stopped Task 1 to start and execute Thread 2")

    #ser.write('x5A\x03\x02\x08\x02\x0F')
    #c = ser.read(7)
    #Report(c.encode('hex'))

    thread_flag = 'go' # signals Thread 1 to resume
    Report("Thread 2 complete")


def Main():
    ser = None # serial.Serial(3, 11520)
    t1 = threading.Thread(target = Task1, args=[ser])
    t2 = threading.Thread(target = Task2, args=[ser])
    Report("Starting Thread 1")
    t1.start()

    time.sleep(3)
    Report("Starting Thread 2")
    t2.start()


if __name__ == '__main__':

    Main()

That approach uses a global variable, which is often frowned upon. You could instead make Task1 and Task2 methods of an object self that carries both self.ser and self.thread_flag as attributes.

For any inter-thread communication more complex than this, you need to investigate locks, mutexes and semaphores (e.g. threading.Lock)


Post a Comment for "Small Example For Pyserial Using Threading"