本文介紹的是使用arduino驅動超聲波測量距離,並通過串口將數據發送給python,從而進行數據處理,處理結果如圖所示。
準備工作
超聲波模塊+arduino開發板+杜邦線數根+python開發環境
思路
首先使用arduino車輛距離,通過串口將數據發送給python代碼進行數據處理並繪製成圖像進行實時顯示。
超聲波模塊介紹
如上圖所示,VCC 供5V電源, GND 爲地線,TRIG 觸發控制信號輸入,ECHO 迴響信號輸出等四個接口端。
2、電路連接
接線比較簡單,按照如下順序連線即可:
3、程序編寫
根據模塊的原理來進行代碼編寫,超聲測距時的操作時序如下:
以上時序圖表明你只需要提供一個 10uS 以上脈衝觸發信號,該模塊內部將發出 8 個 40kHz 週期電平並檢測回波。一旦檢測到有
回波信號則輸出迴響信號。迴響信號的脈衝寬度與所測的距離成正比。由此通過發射信號到收到的迴響信號時間間隔可以計算得
到距離。公式:uS/58=釐米或者 uS/148=英寸;或是:距離=高電平時間*聲速(340M/S)/2;建議測量週期爲 60ms 以上,以
防止發射信號對迴響信號的影響。
注意:
1、此模塊不宜帶電連接,若要帶電連接,則先讓模塊的 GND 端先連接,否則會影響模塊的正常工作。
2、測距時,被測物體的面積不少於 0.5 平方米且平面儘量要求平整,否則影響測量的結果。
編寫代碼如下:
/**
* 文件: 超聲測距.ino by 零知實驗室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
* -^^- 零知開源,讓電子製作變得更簡單! -^^-
**/
#define SR04_TRIG 9
#define SR04_ECHO 10
// the setup routine runs once when you press reset:
void setup() {
// put your setup code here, to run once:
pinMode(SR04_TRIG, OUTPUT);
pinMode(SR04_ECHO, INPUT);
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// put your main code here, to run repeatedly:
int distance = getDistance();
Serial.print("distance = ");
Serial.println(distance);
delay(300);
}
serial庫的安裝
安裝 pip install serial。下載了一會安裝好了,再運行,還是提示同樣的錯誤。上網查了一下,應該安裝 pip install pyserial。
如果上述方法安裝失敗,可能需要下載下來再安裝。
在 https://pypi.org/project/pyserial/#files 中,有
Windows下下載這個wheel格式的文件。關於wheel文件
如果你已經安裝了pip,那麼你需要把它升級到最新版本。
以管理員身份運行cmd
轉到Python安裝目錄的Scripts目錄下:
cd C:\Program Files\Python36\Scripts
pip install wheel
pip install 路徑\文件名.whl:
pip install C:\Users\0AQZ0\Downloads\matplotlib-2.1.2-cp27-cp27m-win_amd64.whl
以上經驗來源於:EmbededDriver的博客https://blog.csdn.net/u012308586/article/details/89449004
matplotlib庫的安裝
一、一般方法
1.Win+R輸入cmd進入到CMD窗口下,執行python -m pip install -U pip setuptools進行升級。
2.輸入python -m pip install matplotlib進行自動的安裝,系統會自動下載安裝包
3.進入到python idle中,運行import matplotlib,如下圖所示,如果沒有報錯,就證明安裝成果。
輸入以下代碼運行成果證明安裝沒問題
import matplotlib.pyplot as plt
labels='frogs','hogs','dogs','logs'
sizes=15,20,45,10
colors='yellowgreen','gold','lightskyblue','lightcoral'
explode=0,0.1,0,0
plt.pie(sizes,explode=explode,labels=labels,colors=colors,autopct='%1.1f%%',shadow=True,startangle=50)
plt.axis('equal')
plt.show()
以上方法來源於:豬豬俠喜歡躲貓貓的博客:最簡單的matplotlib安裝教程
二、特殊方法
我建議大家用exe文件安裝matplotlib,我使用setuptools安裝,沒安裝成功,提示一堆錯誤。所以我推薦還是exe安裝,我把matplotlib的exe安裝文件列表寫在下面的參考資料裏。你找到對應版本的下載就可以,這裏是安裝過程:
1、首先,我們下載了適合自己的版本
2、打開它,就會看到安裝界面,點擊下一步
3、這裏,輸入python的安裝目錄,點擊下一步
4、安裝過程的截圖
5、現在就安裝好了,引入一下,看看是否出現了錯誤,沒有錯誤就說明安裝成功。
錯誤參考:
如果提示錯誤:ImportError: matplotlib requires dateutil,你可以看這篇文章:http://jingyan.baidu.com/article/aa6a2c14d5aa7f0d4c19c4e2.html
如果提示錯誤:ImportError: matplotlib requires
pyparsing,你可以看這篇文章:http://jingyan.baidu.com/article/e4d08ffdd3b9690fd2f60de2.html
以上經驗來源於百度經驗:Python教程:[55]matplotlib安裝下載方法https://jingyan.baidu.com/article/154b46315523b428ca8f41e2.html
python讀取串口數據代碼
import serial
ser=serial.Serial("COM3",115200,timeout=0.5) #打開串口
while (1):
ch=ser.read()
str1=ch.decode("iso-8859-15") #bytes轉str
if(str1): #判斷數據是否爲空,很重要
l=ord(str1) #str轉int,方便數據計算和處理
print("%x" % l)
pass
python進行圖像繪製的程序代碼
import matplotlib.pyplot as plt
ax = [] # 定義一個 x 軸的空列表用來接收動態的數據
ay = [] # 定義一個 y 軸的空列表用來接收動態的數據
plt.ion() # 開啓一個畫圖的窗口
i=1
while i<1000:
#print(b)
if b == "":
b = 0
#print(b)
else:
b = float(b)
#print(b)
ax.append(i) # 添加 i 到 x 軸的數據中
i=i+1
ay.append(b) # 添加 i 的平方到 y 軸的數據中
plt.clf() # 清除之前畫的圖
plt.plot(ax,ay) # 畫出當前 ax 列表和 ay 列表中的值的圖形
plt.pause(0.1) # 暫停一秒
plt.ioff() # 關閉畫圖的窗口
繪製的圖像如下圖
整體代碼
arduino代碼:
int TrgPin = A0;
int EcoPin = A1;
float dist;
void setup()
{
Serial.begin(9600);
//設置TrgPin爲輸出狀態
pinMode(TrgPin, OUTPUT);
// 設置EcoPin爲輸入狀態
pinMode(EcoPin, INPUT);
}
void loop()
{
digitalWrite(TrgPin, LOW);
delayMicroseconds(8);
digitalWrite(TrgPin, HIGH);
// 維持10毫秒高電平用來產生一個脈衝
delayMicroseconds(10);
digitalWrite(TrgPin, LOW);
// 讀取脈衝的寬度並換算成距離
dist = pulseIn(EcoPin, HIGH) / 58.00;
Serial.print("Distance:");
Serial.print(dist);
Serial.println("cm");
delay(300);
}
python代碼:
import matplotlib.pyplot as plt
import serial
serialPort = "COM4" # 串口
baudRate = 9600 # 波特率
ser = serial.Serial(serialPort, baudRate, timeout=0.1)
#print("參數設置:串口=%s ,波特率=%d" % (serialPort, baudRate))
ax = [] # 定義一個 x 軸的空列表用來接收動態的數據
ay = [] # 定義一個 y 軸的空列表用來接收動態的數據
plt.ion() # 開啓一個畫圖的窗口
i=1
while i<1000:
str1 = ser.readline()
str1 = str(str1)
b = str1.lstrip("b'")
b = b.lstrip("Distance:")
b = b.rstrip("'")
b = b.replace('\\n', '').replace('\\r', '')
b = b.lstrip()
b = b.replace('cm', '')
b = b.lstrip()
#print(b)
if b == "":
b = 0
#print(b)
else:
b = float(b)
#print(b)
ax.append(i) # 添加 i 到 x 軸的數據中
i=i+1
ay.append(b) # 添加 i 的平方到 y 軸的數據中
plt.clf() # 清除之前畫的圖
plt.plot(ax,ay) # 畫出當前 ax 列表和 ay 列表中的值的圖形
plt.pause(0.1) # 暫停一秒
plt.ioff() # 關閉畫圖的窗口
while 1:
print("處理完畢!")
以上就是本文的全部內容,關注我學習更多知識