2016-08-24 313 views
1

任何人都可以請給我一個關於如何使用pyserial通信線程的小而簡單的例子。 我google搜索了三天,我還是illeterate,我甚而不具有整合兩者的代碼工作片使用線程的pyserial的小例子

基本上我的目標在這種情況下使用線程:

有串行通信從MCU繼續進行到一定的值(比如A)。

停止達到A值 - 然後達到B值...並再次開始連續達到A值。

你可以在這裏找到一些基本的代碼。

import threading 
import time 
import sys 
import serial 
import os 
import time 

def Task1(ser): 

    while 1: 

     print "Inside Thread 1" 
     ser.write('\x5A\x03\x02\x02\x02\x09') # Byte ArrayTo Control a MicroProcessing Unit 
     b = ser.read(7) 
     print b.encode('hex') 
     print "Thread 1 still going on" 
     time.sleep(1) 


def Task2(ser): 

    print "Inside Thread 2" 
    print "I stopped Task 1 to start and execute Thread 2" 
    ser.write('x5A\x03\x02\x08\x02\x0F') 
    c = ser.read(7) 
    print c.encode('hex') 
    print "Thread 2 complete" 


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

    print "=== exiting ===" 

    ser.close() 

if __name__ == '__main__': 

    Main() 
+0

請清理你的縮進,因爲它實際上是在Python重要... – Andy

+0

所以對於初學者您在thread2中發表評論說「我停止了任務1」,但是你沒有。此外,由於您不會與您的線程「加入」,因此您很可能在線程啓動之前立即關閉串口ser.close()。 – Andy

+0

@Andy編輯你能否給我一個代碼片段。我明白你說了什麼,但我不知道如何阻止一個線程。我有另一個鎖 - 但它也失敗了。我沒有使用t1.join(),因爲當t1仍在使用時,我應該能夠退出主程序。 –

回答

0

還有的要求沒有事實依據的Task2

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

你開始執行一個線程,然後立即開始另一個停止第一。這意味着ser.readser.write命令可能會相互干擾。

你可以做些什麼來解決這一問題的最簡單的事情是引入變量,允許通信:

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() 

這種方法使用了一個全局變量,這往往是令人難以接受的。您可以改爲製作和self.thread_flag作爲屬性的對象selfTask1Task2方法。

對於任何線程間通信比這更復雜,需要調查的鎖,互斥和信號量(如threading.Lock

+0

如何停止線程?你能否給我提供一個可用的代碼片段。 –

+0

我從昨天開始調查鎖 - 沒有運氣。你的代碼給了我一個錯誤ser - 沒有打開。所以我添加了t2.join(),但仍然沒有運氣。我無法關閉主線程。線程1 - t1運行時。我還設置了t1.setDaemon(True) - 代碼現在是一個infiinte循環,沒有任何內容正在打印。 –

+0

'ser is not open'不是源於我的代碼片段的問題。這和線程是不同的問題。使用現有的'Main'並確保'ser'已打開進入。 – jez