有沒有想過停車感測器是如何工作的,您的車怎麼知道離撞牆有多遠?肯定見過機器人避開障礙物吧,想知道它們是如何發現障礙物的嗎?這些問題的答案都涉及到短程測距。在這個專案中,我們將使用Arduino UNO結合ROHM測距感測器,測量15cm以內的木制目標的距離。
雖然這個專案看起來很簡單,但是感測器並不能直接給出與目標之間的距離。這時,我們要用到光電電晶體,它根據與目標之間的距離輸出一定的電壓,需要將這個電壓轉換成距離。由於光電電晶體產生的電壓變化與距離不呈線性關係,這個方法的複雜程度增加了。這涉及一種稱為曲線擬合的方法,以從實驗資料中獲得盡可能最接近的方程。透過本專案可學習以下知識:
如何正確給LED供電:
在這個DIY專案中,我們將研發一個電路,使用Arduino的數位引腳為測距感測器的LED供電。LED發出的光將從木制目標反射,並被光電電晶體接收,光電電晶體將產生電壓訊號,由Arduino中的類比引腳讀取。由於電壓變化相對於距離變化不呈線性關係,在與目標不同距離處收集的資料將用於使用MATLAB生成控制方程。然後,將透過Arduino在代碼中使用該方程來測量距離。將按照以下順序介紹這個專案:
所需元件
元件 | 連結/圖片 |
ROHM測距感測器
RPR-220PC30N |
https://www.digikey.com/products/en?keywords=RPR-220PC30N |
請注意,我在本文中使用的是射極紅光的RPR-220UC30N,而連結中是射極藍光的替代件RPR-220PC30N,功能是相同的,後者目前更容易買到 | |
Arduino UNO R3 | https://www.aliexpress.com/item/32981776049.html |
USB B資料線 (通常隨Arduino UNO R3一起提供) |
|
56kΩ和220Ω的電阻 | |
400孔無焊麵包板 | https://www.aliexpress.com/item/32711841420.html |
10根跳線 | https://www.aliexpress.com/item/32951945552.html |
所有元件都採購齊全後,第一步是把所有東西都連接起來。這個專案不需要很多元件;只需要透過正確的電阻將Arduino與ROHM RPR-220感測器正確連接即可。實際上,為了使其成為可擕式系統,我們使用雙面膠帶將Arduino貼在麵包板的背面,將ROHM感測器貼在麵包板的正面。ROHM感測器引腳的定義如下所示:
連接示意圖如下所示:
實際接線如下所示:
Arduino程式設計需要設定Arduino IDE。Arduino IDE可在Linux和Windows上使用。對於這個DIY專案,我們將使用Windows桌面應用程式。訪問以下連結下載並安裝Arduino IDE:
成功安裝後,打開Arduino IDE並使用USB B資料線連接Arduino UNO R3:在Arduino IDE中,從“工具”>“埠”>“COM 3 (Arduino Genuino / UNO)”中選擇適當的COM埠。這時,您已經完成設定,可以開始程式設計了。
首先,研發程式,以獲取目標放在不同距離時的感測器值。包含注釋的代碼如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#define IR_INPUT_PIN A0 //Pin to read values from phototransistor #define IR_LED_PIN 8 //Pin to light LED void setup() { Serial.begin(9600); pinMode(IR_INPUT_PIN, INPUT); pinMode(IR_LED_PIN, OUTPUT); } void loop(){ int ambient = 0; int lit = 0; int value = 0; digitalWrite(IR_LED_PIN, LOW); //Turning off LED to measure ambient light delay(5); //To give ADC and LED transition time ambient = analogRead(IR_INPUT_PIN); //Saving value for ambient light digitalWrite(IR_LED_PIN, HIGH); //Turning on LED delay(5); lit = analogRead(IR_INPUT_PIN); //Measuring total reflected light on sensor value = lit - ambient; //Removing ambient light value to calculate the net value of LED Serial.print("value = "); Serial.println(value); //Printing final sensor value on serial monitor delay(1000); } |
完成上述代碼後,編譯並將其上傳到Arduino。如果所有接線正確,LED將會點亮。如下所示設定用於校準的儀器(將一個目標放在15cm的距離處,尺規放在下面):
現在,在Arduino IDE中,打開“工具”>“串口監視器”。執行以下操作:
如上所述,由於目標的顏色、環境光和環境不同,這些值可能會有所不同。在本例中,距離為15、10、5和2cm處對應的值分別為15、30、97和487。
很明顯,這種關係不是線性的,我們需要一個方程來計算距離。這個方程將使用下面介紹的曲線擬合方法獲得。
打開MATLAB,如下所示寫入x和y座標資料:
現在轉到應用程式中的曲線擬合。
擬合類型選擇冪函數。
記下方程和常數a和b的值。
最終程式設計時,修改代碼以包括從曲線擬合獲得的方程,並刪除列印命令,但最終距離除外,這是必需的。由於已經使用曲線擬合找到了感測器值與距離之間的關係,因此將聲明一個附加變數來存儲距離的大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#define IR_INPUT_PIN A0 //Pin to read values from phototransistor #define IR_LED_PIN 8 //Pin to light LED double a= 73.11; //Constants obtained from MATLAB Curve fitting double b= -0.585; double dist; void setup() { Serial.begin(9600); pinMode(IR_INPUT_PIN, INPUT); pinMode(IR_LED_PIN, OUTPUT); } void loop() { int ambient = 0; int lit = 0; int value = 0; digitalWrite(IR_LED_PIN, LOW); //Turning off LED to measure ambient light delay(5); //To give ADC and LED transition time ambient = analogRead(IR_INPUT_PIN); //Saving value for ambient light digitalWrite(IR_LED_PIN, HIGH); //Turning on LED delay(5); lit = analogRead(IR_INPUT_PIN); //Measuring total reflected light on sensor value = lit - ambient; //Removing ambient light value to calculate the net value of LED //Using power function and formulating equation generated by MATLAB dist = pow(value,b); dist = a*dist; //Displaying the calculated distance Serial.print(dist); Serial.println(“ cm”); } |
測試時,使用相同的校準設定。
將最終代碼上傳到Arduino後,打開串口監視器。您將看到以釐米為單位的距離值。為了驗證測試,將螢幕上的值與地面上的尺規進行匹配。如果數值接近正確,您就成功應用曲線擬合方法進行了逼近。現在,您的系統可以可靠地計算不同場景中相似障礙物的距離。