1. 程式人生 > >基於Arduino和python的串列埠通訊和上位機控制

基於Arduino和python的串列埠通訊和上位機控制

 引言

經常的時候我們要實現兩個程式碼之間的通訊,比如說兩個不同不同人寫的程式碼要對接,例如將python指令控制Arduino控制元件的開關,此處使用串列埠通訊是非常方便的,下面筆者將結合自己踩過的坑來講述下自己的學習經歷。

首先是挑戰杯審報的一個專案,即採用機器學習模型分類資料,結合Arduino的壓力感測器模組,而機器學習大多采取python,資料無法做到實時傳輸,最後放棄了。

圖1 壓力感測器模型

然後是python需要通過Arduino的北斗模組獲取位置資料,這個也需要做兩個程式碼之間的通訊。

當時的我被這兩個問題卡了好久也沒有想到解決方案

感覺像是很複雜又完全沒有思路

後來查閱大量資料終於得到解決

此處大概有兩個重要的環節:串列埠通訊和上位機控制

在說之前我們先要了解一下序列介面

偉大的百度百科告訴我們:

序列介面簡稱串列埠,也稱序列通訊介面或序列通訊介面(通常指COM介面),是採用序列通訊方式的擴充套件介面。序列介面 (Serial Interface) 是指資料一位一位地順序傳送,其特點是通訊線路簡單,只要一對傳輸線就可以實現雙向通訊(可以直接利用電話線作為傳輸線),從而大大降低了成本,特別適用於遠距離通訊,但傳送速度較慢。

(傳送速度較慢這個。。。)

(反正我們就傳個幾KB的資料,慢就慢吧)

(手動微笑)

串列埠通訊

開啟我們的Arduino編譯器,可以看到有一個選擇板子所在的埠的選項

圖2 Arduino編譯器的埠

像此處寫的COM4就是指的是Arduino開發板所在的串列埠,如果需要通過Arudino來上傳程式碼到開發板上所需要使用的就是這個串列埠來與Arduino開發板進行通訊

 

用過的人都知道Arduino有一個串列埠監視器(圖右上角)和一個Serial.print()函式

圖3 串列埠監視器的位置

如果我們使用Serial.print()函式的話,傳過來的資料就能夠成功的在串列埠監視器上顯示出來

圖4 Serial.print()函式結合串列埠監視器的描述

那麼我們需要思考一個問題:

既然傳過來的資料能夠用Arduino來看

那麼其他的軟體如果能夠開啟的話效果就會非常好

由此我們就需要做串列埠通訊的問題啦

--------------------------------------------------------------------------------------------------------------------------------------------------

知識連結:其實Arduino主要起到的僅僅只有一個編譯的作用,這個串列埠監視只是它的副業。。

--------------------------------------------------------------------------------------------------------------------------------------------------

 

一、設定串列埠

此處我們採用python開啟這個串列埠以實現串列埠通訊

編譯器使用pyCharm

首先安裝pyserial

圖5 安裝pyserial

(萬能的pip install真好用)

pyserial的作用在於提供一個從串列埠讀取資訊的介面

現在我們已經擁有串列埠通訊的基礎了

趕緊把包導進來(注意使用import serial而不是import pyserial)

這裡介紹一個基本函式serial.Serial(a,b,c)來設定一個串列埠

a為一個字串代表串列埠的位置(如COM3)

b為一個數字代表波特率

(值得注意的是Arduino中Serial.begin()所設定的東西一定要求與你讀到的波特率相同)

c為超時的時間,單位為s

初始化如圖所示

圖6 串列埠設定與初始化

此處的意義是開啟一個名字叫COM1的串列埠,以9600波特率,0.5秒作為超時

二、讀取資訊

採用readline函式以讀取一列資料

由於此處我們定義的變數是ser

所以下面也同樣使用ser

即ser.readline()函式

下面貼出程式碼

首先是python端程式碼

 

圖7 python端程式碼和執行結果(由於此處我是COM4串列埠就設定的是COM4)

 1 import serial
 2 
 3 
 4 serialPort = "COM4"  # 串列埠
 5 baudRate = 9600  # 波特率
 6 ser = serial.Serial(serialPort, baudRate, timeout=0.5)
 7 print("引數設定:串列埠=%s ,波特率=%d" % (serialPort, baudRate))
 8 
 9 
10 while 1:
11     str = ser.readline()
12     print(str)
13 
14 ser.close()

然後是Arduino端程式碼

1 void setup(){
2   Serial.begin(9600);
3 }
4 void loop(){
5   Serial.print("Hello,World!\n");
6 }

至此

Arduino端向python端傳輸資料已經完成

上位機控制

由於Arduino的控制很有可能需要其他程式碼傳送執行結果給它

所以上位機對於Arduino的控制也是十分有意義的

利用上位機的控制

我們能夠實現程式碼直接控制開關的結果

例如輸入一個數然後開關開啟燈亮

此處我們就採用這個作為Model

一、Arduino函式介紹

此處要介紹三個新的函式Serial.read() Serial.available() pinMode()

1.Serial.read()

這個函式的作用在於從COM介面讀取一個位元組的資料

2.Serial.available()

這個函式的作用在於檢視COM介面是否有資料讀入

3.pinMode((串列埠號),OUTPUT) 將一個埠設定為輸出口

有了這兩個函式過後接下來會簡單很多

二、介面實現

Arduino埠

 

我們需要實現以下功能:

1.燈原來亮

2.按下0後燈滅

3.按下1後燈亮

首先我們需要向Arduino晶片內寫入程式碼

但有一點需要注意

如果要將二極體LED直接接到介面上的話只能接13號介面

因為13號介面自帶正好適合LED的電阻

有了上面的基礎

我就直接貼程式碼了

附帶詳細註釋哦

 1 void setup(){
 2   Serial.begin(9600);
 3   pinMode(13, OUTPUT);//設定13號埠作為輸出埠
 4   digitalWrite(13,HIGH);//讓燈開始時亮
 5 }
 6 char var;
 7 void loop(){
 8   while(Serial.available()>0)//當有訊號的時候
 9   {
10     var=Serial.read();
11     if(var=='0')//傳過來的是0
12       digitalWrite(13,LOW);
13     if(var=='1')//傳過來的是1
14      digitalWrite(13,HIGH);
15   }
16 }

 

 

python埠

此處python介面採用serial中的write函式來向串列埠中寫入資料

注意一下輸入的一定要是ASCII字元

否則Arduino介面無法讀出的

 

 1 # -*- coding: utf-8 -*-
 2 import serial
 3 
 4 serialPort = "COM4"  # 串列埠
 5 baudRate = 9600  # 波特率
 6 ser = serial.Serial(serialPort, baudRate, timeout=0.5)
 7 print("引數設定:串列埠=%s ,波特率=%d" % (serialPort, baudRate))
 8 
 9 demo1=b"0"#將0轉換為ASCII碼方便傳送
10 demo2=b"1"#同理
11 while 1:
12     c=input('請輸入指令:')
13     c=ord(c)#將c轉換為UTF-8標準數字
14     if(c==48):
15         ser.write(demo1)#ser.write在於向串列埠中寫入資料
16     if(c==49):
17         ser.write(demo2)

 

執行結果如下:

圖8 輸入0時關閉

圖 9 輸入1時開啟

------------------------------------------------------------------------------------------------------------------------------------------------------

幾點注意事項:

1.介面不一定統一

2.其中函式筆者是依據自己理解來描述的,如果有問題的話希望各位大佬不要噴

3.Arduino真是太好玩了

 

如果各位大佬覺得筆者這篇寫的還算可以的話歡迎打賞哦

2018-12-31  01:26:53  Author:Lance Yu