引言
經常的時候我們要實現兩個代碼之間的通信,比如說兩個不同不同人寫的代碼要對接,例如將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
