在當今的情況下,我們都忙于工作,沒有時間正確打掃房子。這個問題的解決方法很簡單,你只需要買一個家用吸塵器機器人,比如irobot roomba,它會通過按下一個按鈕來清潔你的房子。但是這些商業產品有一個共同的問題,那就是成本。所以今天,我們決定做一個簡單的掃地機器人, 與市面上的商業產品相比,它不僅制作簡單,而且成本非常低。經常閱讀的讀者可能還記得我們很久以前制造的Arduino 吸塵機器人,但那個機器人非常笨重,需要一個大的鉛酸電池才能移動。新的Arduino 吸塵器 我們將在這里建造將更緊湊,更實用。最重要的是,該機器人將配備超聲波傳感器和紅外接近傳感器。超聲波傳感器將允許機器人避開障礙物,以便它可以自由移動,直到房間被正確清潔,接近傳感器將幫助它避免從樓梯上摔下來。
構建基于 Arduino 的地板清潔機器人所需的材料
由于我們使用非常通用的組件來構建真空吸塵器機器人的硬件部分,因此您應該能夠在當地的愛好商店中找到所有這些組件。這是所需材料的完整列表以及所有組件的圖像。
Arduino Pro 迷你 - 1
HC-SR04 超聲波模塊 - 3
L293D 電機驅動器 - 1
5Volt N20 電機和安裝支架 - 2
N20 電動車輪 - 2
開關 - 1
LM7805 穩壓器 - 1
7.4V 鋰離子電池 - 1
紅外模塊 - 1
穿孔板 - 1
腳輪 - 1
中密度纖維板
通用便攜式吸塵器
便攜式吸塵器
在組件需求部分,我們談到了便攜式真空吸塵器,下圖正是展示了這一點。這是一款來自亞馬遜的便攜式吸塵器。這帶有一個非常簡單的機制。它在底部有三個部分(一個用于儲存灰塵的小室,中間部分包括電機、風扇和頂部的電池插座(有一個電池蓋或蓋子)。它有一個直流電機和一個風扇。這個電機通過一個簡單的開關直接連接到 3V(2*1.5volt AA 電池)。由于我們用 7.4V 電池為機器人供電,我們將切斷內部電池的連接并從 5V 供電電源。所以,我們去掉了所有不必要的部件,只剩下兩線電機。你可以在下圖中看到。
HC-SR04 超聲波傳感器模塊
為了檢測障礙物,我們使用了流行的HC-SR04 超聲波距離傳感器 ,也可以稱之為避障傳感器。工作很簡單,首先,發射器模塊發送一個超聲波,該超聲波在空氣中傳播,遇到障礙物,然后反彈回來,接收器接收到該波。通過用Arduino計算時間,我們可以確定距離。在之前關于基于 Arduino 的超聲波距離傳感器項目的文章中,我們已經非常深入地討論了這種傳感器的工作原理。如果您想了解有關 HC-SR04 超聲波距離傳感器模塊的更多信息,可以查看。
用于樓梯檢測的地板傳感器(IR 傳感器)
在功能部分,我們已經討論了機器人可以檢測樓梯并防止自己跌倒的功能。為此,我們使用了IR Sensor。我們將在IR 傳感器和 Arduino之間建立一個接口。IR Proximity Sensor的工作原理很簡單,它有一個 IR LED 和一個光電二極管,IR LED 發出 IR 光,如果有任何障礙物擋在發出的光的前面,它就會被反射,并檢測到反射光由光電二極管。但是反射產生的電壓會非常低。為了增加它,我們可以使用運算放大器比較器,我們可以放大并獲得輸出。紅外模塊具有三個引腳 - Vcc、接地和輸出。通常,當傳感器前面有障礙物時,輸出會變低。所以,我們可以用它來檢測地板。如果在一瞬間,我們從傳感器檢測到高電平,我們可以停止機器人,將其轉回或做任何我們想要防止它從樓梯上掉下來的事情。在上一篇文章中,我們制作了一個面包板版本的紅外接近傳感器模塊并詳細解釋了工作原理,如果您想了解更多關于該傳感器的信息,可以查看。
基于Arduino的地板清潔機器人電路圖
我們有三個檢測障礙物的超聲波傳感器。因此,我們需要連接超聲波傳感器的所有地線并將它們連接到公共地線。此外,我們連接傳感器的所有三個 Vcc 并將其連接到公共 VCC 引腳。接下來,我們將觸發和回聲引腳連接到 Arduino 的 PWM 引腳。我們還將 IR 模塊的 VCC 連接到 5V,并將地連接到 Arduino 的接地引腳,IR 傳感器模塊的輸出引腳連接到 Arduino 的數字引腳 D2。對于電機驅動器,我們將兩個使能引腳連接到 5v,并將驅動器電壓引腳連接到 5V,因為我們使用的是 5 伏電機。在上一篇文章中,我們制作了一個Arduino 電機驅動器擴展板,您可以查看它以了解有關L293D 電機驅動器 IC的更多信息及其操作。Arduino、超聲波模塊、電機驅動器和電機在 5 伏電壓下工作,更高的電壓會殺死它,我們使用 7.4 伏電池,將其轉換為 5 伏,使用 LM7805 穩壓器。將真空吸塵器直接連接到主電路。
為基于 Arduino 的地板清潔機器人構建電路
要將每個組件焊接在一起,首先,我拿了一小塊點狀穿孔板,根據電路圖放置每個組件,然后焊接所有東西。這部分非常簡單,但要小心。此外,我們使用了兩個母頭來放置Arduino pro mini。完成穿孔板焊接后,我們將電線連接到超聲波模塊,并將它們連接到相應的引腳上,如圖所示。
為基于 Arduino 的地板清潔機器人建造外殼
為了得到一些關于我的機器人的想法,我在網上搜索了吸塵器機器人,得到了一些圓形機器人的圖像。所以,我決定造一個圓形機器人。為了構建機器人的追逐和身體,我有很多選擇,如泡沫板、MDF、紙板等。但我選擇 MDF 是因為它很硬并且具有一些防水特性。如果您這樣做,您可以決定為您的機器人選擇哪種材料。
為了構建機器人,我拿了 MDF 板,然后畫了兩個半徑為 8 CM 的圓, 在那個圓內,我還畫了另一個半徑為 4 CM的圓用于安裝真空吸塵器。然后我剪掉了圓圈。此外,我已經為車輪路徑切割并移除了適當的部分(請參閱圖像以更好地理解)。最后,我為腳輪打了三個小孔。下一步是使用支架將電機安裝在底座上,同時將腳輪放置并固定到其位置。之后,將超聲波傳感器放置在機器人的左側、右側和中間。此外,將 IR 模塊連接到機器人的底部。不要忘記在外面添加開關。這就是構建機器人的全部內容,如果您對此感到困惑,可以參考以下圖片。
最上面的部分,我還在泡沫板上畫了一個半徑為11CM的圓,剪下來。對于頂部和底部之間的間距,我切了三個 4 厘米長的塑料管。之后,我將塑料墊片粘在底部,然后粘在頂部。如果需要,您可以用塑料或類似材料覆蓋機器人的側面部分。
基于Arduino的地板清潔機器人 - 代碼
該項目的完整代碼在文檔末尾給出。這個 Arduino 代碼類似于基于 Arduino 的超聲波距離傳感器代碼,唯一的變化是地板檢測。在以下幾行中,我將解釋代碼是如何工作的。在這種情況下,我們沒有使用任何額外的庫。下面我們一步一步地描述了代碼。我們沒有使用任何額外的庫來解碼來自 HC-SR04 傳感器的距離數據,因為它非常簡單。在以下幾行中,我們描述了如何。首先,我們需要為連接到 Arduino 板的所有三個超聲波距離傳感器定義 Trigger Pin 和 Echo Pin。在這個項目中,我們有三個 Echo 引腳和三個 Trigger 引腳。請注意,1 是左傳感器,2 是前傳感器,3 是右傳感器。
?
常量 int trigPin1 = 3; 常量 int echoPin1 = 5; 常量 int trigPin2 = 6; 常量 int echoPin2 =9; 常量 int trigPin3 = 10; 常量 int echoPin3 = 11; int irpin = 2;
?
然后我們為距離定義變量,這些變量都是 (int) 類型變量,對于持續時間,我們選擇使用 (long)。同樣,我們每個人都有三個。另外,我已經定義了一個整數來存儲運動的狀態,我們將在本節后面討論它。
?
持續時間長1; 持續時間長2; 持續時間長3; int距離左; int 距離前沿; int distanceright; 詮釋a = 0;
?
接下來,在設置部分,我們需要使用?pinModes()?函數將所有透視引腳設置為輸入或輸出。要從模塊發送超聲波,我們需要將觸發引腳設為高電平,即所有觸發引腳都應定義為?OUTPUT。為了接收回聲,我們需要讀取回聲引腳的狀態,因此所有回聲引腳都應定義為?INPUT。此外,我們啟用串行監視器以進行故障排除。為了讀取 IR 模塊的狀態,我將irpin定義為輸入。
?
pinMode(trigPin1,輸出); pinMode(trigPin2,輸出); pinMode(trigPin3,輸出); pinMode(echoPin1,輸入); pinMode(echoPin2,輸入); pinMode(echoPin3,輸入); pinMode(irpin,輸入);
?
這些數字引腳被定義為電機驅動器輸入的輸出。
?
pinMode(4,輸出); pinMode(7,輸出); pinMode(8,輸出); pinMode(12,輸出);
?
在主循環中,我們為三個傳感器設置了三個部分。所有部分的工作方式相同,但每個部分用于不同的傳感器。在本節中,我們從每個傳感器讀取障礙物距離并將其存儲在每個定義的整數中。要讀取距離,首先,我們必須確保觸發引腳清晰,為此,我們需要將觸發引腳設置為?低電平?2 μs。現在,為了產生超聲波,我們需要將觸發引腳設為?高電平?10 μs。這將發送超聲波,在?pulseIn()?函數的幫助下,我們可以讀取行進時間,并將該值存儲到變量“持續時間”中。這個函數有2個參數,第一個是echo pin的名字,第二個可以寫高或?低。HIGH 表示?pulseIn?()?函數將等待??由反彈的聲波引起?的引腳變為高電平并開始計數,然后?在聲波結束時等待引腳變為低電平將停止計數。該函數以微秒為單位給出脈沖的長度。為了計算距離,我們將持續時間乘以 0.034(空氣中的聲速為 340m/s)再除以 2(這是由于聲波的來回傳播)。最后,我們將每個傳感器的距離存儲在相應的整數中。
?
數字寫入(trigPin1,低); 延遲微秒(2); 數字寫入(trigPin1,高); 延遲微秒(10); 數字寫入(trigPin1,低); 持續時間1 = 脈沖輸入(echoPin1,高); 距離左 = 持續時間 1 * 0.034 / 2;
?
在得到每個傳感器的距離后,我們可以在if 語句的幫助下控制電機,從而控制機器人的運動。這很簡單,首先,我們給了一個障礙物距離值,在這個例子中,它是 15cm(根據你的意愿改變這個值)。然后我們根據該值給出條件。例如,當左側傳感器前方有障礙物(即左側傳感器的距離應小于或等于 15 厘米)且其他兩個距離較高(即傳感器前方沒有障礙物)時,然后借助數字寫入功能,我們可以將電機驅動到正確的位置。后來,我檢查了紅外傳感器的狀態。如果機器人在地板上,則 IR 引腳的值為LOW,如果不是,則值為高。然后我將該值存儲在int s 變量中。我們將根據這個狀態來控制機器人。
這部分代碼用于向前和向后移動機器人:
?
if(s==HIGH) { digitalWrite(4, LOW); 數字寫入(7,高); 數字寫入(8,低); 數字寫入(12,高); 延遲(1000); a=1; }
?
但是這種方法有一個問題,當電機向后移動,地板回來,機器人向前移動時,它會重復使機器人卡住。?為了克服這個問題,我們在理解 floor 不存在后將值 (1) 存儲在int中。我們還檢查這種情況是否有其他運動。
檢測到沒有地板后,機器人不會向前移動。相反,它會向左移動,這樣我們就可以避免這個問題。
?
if ((a==0)&&(s==LOW)&&(distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (a==0)&&(s==LOW)&&(distanceleft > 15 && distancefront > 15 && distanceright > 15))
?
在上述情況下。首先,機器人會檢查樓層狀態和整數值。只有滿足所有條件,機器人才會繼續前進。
現在,我們可以為電機驅動器編寫命令了。這將驅動右電機向后和左電機向前,從而將機器人向右轉動。
這部分代碼用于向右移動機器人:
?
數字寫入(4,高); 數字寫入(7,低); 數字寫入(8,高); 數字寫入(12,低);
?
如果機器人檢測到地板不存在,則該值變為 1,機器人將向左移動。左轉后,'a' 的值從 1 變為 0。
?
if ((a==1) &&(s==LOW) ||(s==LOW) && (distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (s== LOW) && (distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (s==LOW) && (distanceleft <= 15 && distancefront > 15 && distanceright > 15) || (distanceleft <= 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); 數字寫入(7,低); 數字寫入(8,低); 數字寫入(12,高); 延遲(100); a=0; }
?
這部分代碼用于向左移動機器人:
?
if ((s==LOW)&&(distanceleft > 15 && distancefront <= 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront > 15 && distanceright <= 15) ||( s==LOW)&& (distanceleft > 15 && distancefront <= 15 && distanceright > 15) ) { digitalWrite(4, LOW); 數字寫入(7,高); 數字寫入(8,高); 數字寫入(12,低); }
?
?
?
//定義引腳 常量 int trigPin1 = 3; 常量 int echoPin1 = 5; 常量 int trigPin2 = 6; 常量 int echoPin2 = 9; 常量 int trigPin3 = 10; 常量 int echoPin3 = 11; int irpin = 2; // 定義變量 持續時間長1; 持續時間長2; 持續時間長3; int距離左; int 距離前沿; int distanceright; 詮釋a = 0; 無效設置(){ pinMode(trigPin1,輸出); pinMode(trigPin2,輸出); pinMode(trigPin3, OUTPUT);// 將 trigPin 設置為輸出 pinMode(echoPin1,輸入);// 將 echoPin 設置為輸入 pinMode(echoPin2,輸入); pinMode(echoPin3,輸入); pinMode(irpin,輸入); pinMode(4,輸出); pinMode(7,輸出); pinMode(8,輸出); pinMode(12,輸出); } 無效循環(){ 數字寫入(trigPin1,低); 延遲微秒(2); 數字寫入(trigPin1,高); 延遲微秒(10); 數字寫入(trigPin1,低); 持續時間1 = 脈沖輸入(echoPin1,高); 距離左 = 持續時間 1 * 0.034 / 2; Serial.print("距離1:"); Serial.println(distanceleft); 數字寫入(trigPin2,低); 延遲微秒(2); 數字寫入(trigPin2,高); 延遲微秒(10); 數字寫入(trigPin2,低); 持續時間2 = 脈沖輸入(echoPin2,高); 距離前沿 = 持續時間 2 * 0.034 / 2; Serial.print("距離2:"); Serial.println(distancefront); 數字寫入(trigPin3,低); 延遲微秒(2); 數字寫入(trigPin3,高); 延遲微秒(10); 數字寫入(trigPin3,低); 持續時間3 = 脈沖輸入(echoPin3,高); distanceright = duration3 * 0.034 / 2; Serial.print("距離3:"); Serial.println(distanceright); int s = digitalRead(irpin); 如果(s==高) { 數字寫入(4,低); 數字寫入(7,高); 數字寫入(8,低); 數字寫入(12,高); 延遲(1000); a=1; } if ((a==0)&&(s==LOW)&&(distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (a==0)&&(s==LOW)&&(distanceleft > 15 && distancefront > 15 && distanceright > 15)) { 數字寫入(4,高); 數字寫入(7,低); 數字寫入(8,高); 數字寫入(12,低); } if ((a==1)&&(s==LOW)||(s==LOW)&&(distanceleft <= 15 && distancefront <= 15 && distanceright > 15)||(s==LOW)&&(distanceleft <= 15 && distancefront <= 15 && distanceright > 15)||(s==LOW)&& (distanceleft <= 15 && distancefront > 15 && distanceright > 15)||(distanceleft <= 15 && distancefront > 15 && distanceright > 15)) { 數字寫入(4,高); 數字寫入(7,低); 數字寫入(8,低); 數字寫入(12,高); 延遲(100); a=0; } if ((s==LOW)&&(distanceleft > 15 && distancefront <= 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront > 15 && distanceright <= 15) ||( s==LOW)&& (distanceleft > 15 && distancefront <= 15 && distanceright > 15)) { 數字寫入(4,低); 數字寫入(7,高); 數字寫入(8,高); 數字寫入(12,低); } }
?
?
評論
查看更多