Python應用開發(fā)之實現串口通信
前言
在嵌入式開發(fā)中我們經常會用到串口,串口通信簡單,使用起來方便,且適用場景多,因此串口常常用來輸出調試Log或者跟其他外設進行通訊,也可以用作上位機和下位機之間的通訊。那這一講我就簡單介紹一下如何用Python編寫一個串口收發(fā)程序。
1.環(huán)境搭建
Python的環(huán)境這里就不具體介紹了,網上教程也很多,我主要介紹一下我們這一講用到的類庫以及當前的版本。
package | version |
---|---|
time | 注:python標準庫,無需安裝 |
pyserial | v3.5 |
注:不懂如何安裝庫的同學請自行查閱資料。
特別說明:本文舉的例子皆是基于windows系統下python3來實現的,其他平臺不一定完全適配。
2.硬件準備
我們要通過電腦的USB接口發(fā)送串口數據,在硬件上首先得保證有可用的串口設備接入,并且正確的安裝了驅動。
我這里用的是一個CH340的串口轉TTL的模塊來測試的。
可以用兩個這種模塊相互收發(fā),也可以單個模塊自發(fā)自收,或者接入其他嵌入式設備也行。
硬件接入之后我們可以在設備管理器看到設備的端口號,如下圖所示:
3.代碼編寫與測試
3.1 簡單測一下串口收發(fā)
示例代碼如下:
import serial #導入模塊 try: # 端口號,根據自己實際情況輸入,可以在設備管理器查看 port = "COM6" # 串口波特率,根據自己實際情況輸入 bps = 9600 # 超時時間,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒) time = 5 # 打開串口,并返回串口對象 uart = serial.Serial(port, bps, timeout = time) # 串口發(fā)送一個字符串 len = uart.write("hello world".encode('utf-8')) print("send len: ", len) # 串口接收一個字符串 str = '' for i in range(len): str += uart.read().decode("utf-8") print("receive data: ", str) # 關閉串口 uart.close() except Exception as result: print("******error******:", result)
運行測試:
我這里是自發(fā)自收,如果運行沒有出錯并且成功發(fā)送和接收到正確的數據,說明串口通信是走通了,那么接下來就可以繼續(xù)完善這個流程。
如果出現其他問題,則需要檢查硬件和軟件,確保所有配置都沒問題才能繼續(xù)進行下一步。
3.2 補充細節(jié)
1、串口發(fā)送各種不同類型的數據。
串口數據常用字符串和十六進制(hex)表示。下面列舉了一些例子,可以作為一種參考。
示例如下:
data1 = "hello world" # 字符串 data2 = b"hello world" # bytes data3 = "你好" # 中文字符串 data4 = 0x0A # 整形(以16進制表示) data5 = [0x10, 0x11, 0x12] # 列表/數組(以16進制表示) len = uart.write(data1.encode('utf-8')) # 發(fā)送字符串"hello world" len = uart.write(data2) # 發(fā)送字符串"hello world" len = uart.write(data3.encode('utf-8')) # 以utf-8編碼方式發(fā)送字符串"你好"(6字節(jié)) len = uart.write(data3.encode('gbk')) # 以gbk編碼方式發(fā)送字符串"你好"(4字節(jié)) len = uart.write(chr(data4.encode("utf-8")) # 發(fā)送16進制數據0x0A(1字節(jié)) for x in data5: # 遍歷列表/數組的所有元素并依次發(fā)送 len = uart.write(chr(x).encode("utf-8"))
2、完善串口接收流程
串口接收跟發(fā)送一樣,接收數據也是常用字符串和十六進制(hex)表示。
可以根據以下兩種方式接收數據:
str = uart.read(uart.in_waiting).decode("utf-8") # 以字符串接收 str = uart.read().hex() # 以16進制(hex)接收
接收的時間很短,大部分時間其實是在等待接收,所以我們需要加一個死循環(huán)或者循環(huán)線程來確保串口一直在等待接收。
示例如下:
while True: if uart.in_waiting: # str = uart.read(uart.in_waiting).decode("utf-8") # 以字符串接收 str = uart.read().hex() # 以16進制(hex)接收 print(str) # 打印數據
3、掃描端口
在不知道串口端口號的情況下可以先掃描一下可用的端口。
示例如下:
import serial import serial.tools.list_ports port_list = list(serial.tools.list_ports.comports()) print(port_list) if len(port_list) == 0: print('無可用串口') else: for i in range(0,len(port_list)): print(port_list[i])
3.3 完善整個收發(fā)流程
根據上面舉的一些例子,我們把整個流程補充完整。
示例如下:
# 導入模塊 import threading import time import serial import serial.tools.list_ports # 自定義變量 port = "COM6" # 端口號,根據自己實際情況輸入,可以在設備管理器查看 bps = 9600 # 串口波特率,根據自己實際情況輸入 timeout = 5 # 超時時間,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒) rxdata = '' # 接收的數據 # 掃描端口 def check_uart_port(): port_list = list(serial.tools.list_ports.comports()) # print(port_list) if len(port_list) == 0: print('can not fine uart port') return False else: for i in range(0,len(port_list)): print(port_list[i]) return True # 打開串口 def open_uart(port, bps, timeout): try: # 打開串口,并返回串口對象 uart = serial.Serial(port, bps, timeout=timeout) return uart except Exception as result: print("can not open uart") print(result) return False # 發(fā)送數據 def uart_send_data(uart, txbuf): len = uart.write(txbuf.encode('utf-8')) # 寫數據 return len # 接收數據 def uart_receive_data(uart): if uart.in_waiting: rxdata = uart.read(uart.in_waiting).decode("utf-8") # 以字符串接收 # rxdata = uart.read().hex() # 以16進制(hex)接收 print(rxdata) # 打印數據 # 關閉串口 def close_uart(uart): uart.close() # 創(chuàng)建一個線程用來等待串口接收數據 class myThread (threading.Thread): # 繼承父類threading.Thread def __init__(self, uart): threading.Thread.__init__(self) self.uart = uart def run(self): # 把要執(zhí)行的代碼寫到run函數里面 線程在創(chuàng)建后會直接運行run函數 while True: # print("thread_uart_receive") uart_receive_data(self.uart) # 接收數據 # time.sleep(0.01) # 主函數 def main(): # 掃描端口 result = check_uart_port() if(result == False): return # 打開串口 result = open_uart(port, bps, timeout) if (result == False): return else: uart1 = result # 創(chuàng)建一個線程用來接收串口數據 thread_uart = myThread(uart1) thread_uart.start() while True: # 定時發(fā)送數據 txbuf = "hello world" len = uart_send_data(uart1, txbuf) print("send len: ", len) time.sleep(1) # 啟動主函數 main()
運行測試:
這里還是自發(fā)自收,但是改成定時1s循環(huán)發(fā)送一幀數據,如果是實際使用的話就不要短接TX和RX了,串口是全雙工,收發(fā)是可以同步進行的。
以上就是Python應用開發(fā)之實現串口通信的詳細內容,更多關于Python串口通信的資料請關注腳本之家其它相關文章!
相關文章
Google colab中從kaggle中接入數據的操作方法
這篇文章主要介紹了Google colab中如何從kaggle中接入數據,本文涉及到兩大平臺內容,所以我默認你已經擁有了,并且使用過了一段時間的google賬號和kaggle賬號,需要的朋友可以參考下2024-03-03聊聊python 邏輯運算及奇怪的返回值(not,and,or)問題
在Python中,真值為假的對象,包括False,None,數字0,空字符串以及空的容器類型,除此以外的任何對象均為真,本文重點給大家介紹python 邏輯運算及奇怪的返回值(not,and,or)問題,感興趣的朋友一起看看吧2022-03-03python numpy矩陣信息說明,shape,size,dtype
這篇文章主要介紹了python numpy矩陣信息說明,shape,size,dtype,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05python re正則表達式模塊(Regular Expression)
Python 的 re 模塊(Regular Expression 正則表達式)提供各種正則表達式的匹配操作,在文本解析、復雜字符串分析和信息提取時是一個非常有用的工具.2014-07-07