組員:
411114231 蔣承翰
411114235 林俊良
411114236 鄭丞哲
411114238 黃宥霖
一、介紹:
探討超音波感測器的應用,包括設計超聲波感應停車場和斜咖垃圾桶的方案,並整合伺服馬達與程式碼實現具體功能,旋轉計時器利用伺服馬達聯合規律作動,產生數字變動的視覺效果 !
二、超音波距離感測Arduino程式碼:
#include <Servo.h> // 引入伺服馬達函式庫
Servo myservo; // 建立一個伺服馬達物件
int pos = 0; // 設定伺服馬達角度的變數,初始值為0
int cm = 0; // 儲存超音波測距的距離變數
// 函式:讀取超音波感測器的距離
long readUltrasonicDistance(int triggerPin, int echoPin)
{
pinMode(triggerPin, OUTPUT); // 將觸發腳設為輸出模式
digitalWrite(triggerPin, LOW); // 設定觸發腳為低電位
delayMicroseconds(2); // 延遲2微秒
digitalWrite(triggerPin, HIGH); // 設定觸發腳為高電位,發送超音波訊號
delayMicroseconds(10); // 持續10微秒
digitalWrite(triggerPin, LOW); // 停止發送訊號,設回低電位
pinMode(echoPin, INPUT); // 將回音腳設為輸入模式
return pulseIn(echoPin, HIGH); // 讀取回音腳的脈衝時間,並回傳時間值
}
// 初始化設定
void setup() {
digitalWrite(12, LOW); // 設定12號腳為低電位
myservo.attach(9); // 將伺服馬達連接到9號腳
Serial.begin(9600); // 設定序列埠通訊速率為9600
}
// 主迴圈程式
void loop() {
// 使用超音波感測器測距,計算距離並轉換為公分
cm = 0.01723 * readUltrasonicDistance(6, 7); // 超音波計算公式,6號為觸發腳,7號為回音腳
// 如果距離小於30公分
if(cm < 30){
Serial.print(cm); // 在序列監視器輸出距離值
Serial.println("cm"); // 顯示"cm"標示距離單位
// 伺服馬達從0度轉到120度
for (pos = 0; pos <= 120; pos += 1) {
myservo.write(pos); // 設定伺服馬達的角度
delay(15); // 每次變化後延遲15毫秒
}
delay(500); // 在120度的位置停留0.5秒
// 伺服馬達從120度轉回0度
for (pos = 120; pos >= 0; pos -= 1) {
myservo.write(pos); // 設定伺服馬達角度減少
delay(15); // 每次變化後延遲15毫秒
}
delay(5000); // 馬達歸位後停留5秒,延遲時間可依需求調整
}
}
二、旋轉計時器Arduino程式碼:
#include <Servo.h> // 引入Servo函式庫,用於控制伺服馬達
Servo myservo[14]; // 宣告14個伺服馬達物件
// 定義各伺服馬達對應的開啟位置與關閉位置
int segmentOn[14] = {90,88,81,80,90,78,98,90,88,65,75,90,78,98};
int segmentOff[14] = {0,0,180,180,0,180,0,0,0,155,180,0,180,0};
// 定義數字0-9在七段顯示器上的顯示方式(1表示亮起,0表示熄滅)
int digits[10][7] = {
{1,1,1,1,1,1,0}, // 0
{0,1,1,0,0,0,0}, // 1
{1,1,0,1,1,0,1}, // 2
{1,1,1,1,0,0,1}, // 3
{0,1,1,0,0,1,1}, // 4
{1,0,1,1,0,1,1}, // 5
{1,0,1,1,1,1,1}, // 6
{1,1,1,0,0,1,0}, // 7
{1,1,1,1,1,1,1}, // 8
{1,1,1,1,0,1,1} // 9
};
void setup()
{
// 將每個伺服馬達連接到指定的數位輸出腳位
myservo[0].attach(2);
myservo[1].attach(3);
myservo[2].attach(4);
myservo[3].attach(5);
myservo[4].attach(6);
myservo[5].attach(7);
myservo[6].attach(8);
myservo[7].attach(9);
myservo[8].attach(10);
myservo[9].attach(11);
myservo[10].attach(12);
myservo[11].attach(13);
myservo[12].attach(A0);
myservo[13].attach(A1);
// 初始化所有伺服馬達到開啟位置,顯示數字8
for(int i = 0; i <= 13; i++)
{
myservo[i].write(segmentOn[i]);
}
delay(5000); // 顯示數字8持續5秒
}
void loop()
{
// 從數字9開始進行倒數(十位數)
for (int g = 9; g >= 0; g--)
{
int mustDelay1 = 0;
// 如果需要改變中間段的狀態,移動相鄰的段
if(digits[g][6] != digits[g+1][6])
{
if(digits[g+1][1] == 1)
{
myservo[8].write(segmentOn[8] - 30); // 調整上中段旁的伺服馬達
mustDelay1 = 1;
}
if(digits[g+1][5] == 1)
{
myservo[12].write(segmentOn[12] + 30); // 調整下中段旁的伺服馬達
mustDelay1 = 1;
}
}
// 特殊情況:從數字9開始時,必須先移動特定段
if(g == 9)
{
myservo[8].write(segmentOn[8] - 30);
myservo[12].write(segmentOn[12] + 30);
}
if(mustDelay1 == 1)
delay(200); // 若有段移動,延遲200ms
// 顯示十位數字的各個段
for (int h = 6; h >= 0; h--)
{
if(digits[g][h] == 1)
myservo[h+7].write(segmentOn[h+7]);
else
myservo[h+7].write(segmentOff[h+7]);
if(h == 6)
delay(200); // 延遲200ms,使段變化更平滑
}
// 開始倒數個位數
for (int i = 9; i >= 0; i--)
{
int mustDelay2 = 0;
// 同樣邏輯,若需改變中間段狀態,則移動相鄰段
if(digits[i][6] != digits[i+1][6])
{
if(digits[i+1][1] == 1)
{
myservo[1].write(segmentOn[1] - 30);
mustDelay2 = 1;
}
if(digits[i+1][5] == 1)
{
myservo[5].write(segmentOn[5] + 30);
mustDelay2 = 1;
}
}
if(i == 9)
{
myservo[1].write(segmentOn[1] - 30);
myservo[5].write(segmentOn[5] + 30);
}
if(mustDelay2 == 1)
delay(200);
// 顯示個位數字的各段
for (int j = 6; j >= 0; j--)
{
if(digits[i][j] == 1)
myservo[j].write(segmentOn[j]);
else
myservo[j].write(segmentOff[j]);
if(j == 6)
delay(200);
}
// 若側邊段移動,總延遲為600ms,否則為800ms
if(mustDelay2 == 1)
delay(600);
else
delay(800);
}
}
delay(2000); // 完成倒數後,延遲2秒再重置
}
斜咖垃圾桶
超聲波感應停車場
旋轉計時器
五、組員心得:
411114235 林俊良:
這次的專題不僅加深了我對超音波感測器的理解,也讓我在Arduino的應用上收穫良多。透過設計和編寫程式碼,我學會了如何操作伺服馬達,並利用超音波模組進行距離測量,實現了停車場感應和垃圾桶自動開關的功能。在Arduino方面,我熟悉了基本的硬體連接方式,掌握了數位輸入輸出的設定,並學到了如何透過程式控制外部設備的動作,像是延遲、迴圈與條件判斷等操作。而另一個旋轉計時器,在製作時,伺服馬達會一職莫明其妙的亂轉,可能原因是因為沒有外接電源,導致電壓不穩造成的,因為我們太晚開始做,所以並沒有完成實品。
411114236 鄭丞哲
此次實作延續上學期關於超聲波感測器的應用,程式中加上測量前方物體的距離與控制伺服馬達作動功能做出感應閘門和感應垃圾桶蓋,並擁有自動開啟和關閉的功能,這部分讓我更了解Arduino是如何透過接收和發送訊號來控制馬達。除此之外,我們也想出製作一個由多個伺服馬達做出的數字時鐘,但最後因為在多個馬達驅動下所需的電源不足及沒有外接電源組合成電路的能力而失敗。我們花了很長時間嘗試解決,最終來不及去解決這些問題,我覺得應該加強對電路的理解在Arduino實作中是很重要的,希望在未來我能好好加強這方面的能力,才不會在這種基礎操作卡關,導致沒辦法做出理想的成品。
411114238 黃宥霖
這一次專題我們更加了解超聲波感測器也又是停車場感應與垃圾桶 ,而我們也利用同一個程式碼,做出兩個不同功能的應用,透過程式編寫,我們成功運用了感測器並結合伺服馬達實現自動開關功能。在這過程中,我們更加熟悉了Arduino的數位輸入與輸出設定,並運用延遲、迴圈與條件判斷等基礎邏輯來控制外部設備的運作。旋轉計時器則我們在製作時無法及時解決伺服馬達用內部電源供電不足,導致裝置電壓不穩,最終未能完成該實體。不過,這次經驗讓我深刻體會到提早規劃的重要性,也讓我對Arduino 設計有了更多的反思與學習空間透,總而言之這次專題,我不僅加強了基礎能力,也深刻體會到提前規劃與測試的重要性。
411114231 蔣承翰
這一次專題我好像又沒有記起上學期的教訓,應該要早一點準備材料與花時間想好方向。本來是要做無人機的,但是拖到了期末才發現什麼材料都沒有,然後報帳的時間又過了,最後拖延症發作花了兩天才確定好要做什麼,結果又因為材料的問題一直刪減能夠做的程度,到最後雖然將旋轉時鐘拼裝完成,但是在程式的部分在經歷了一個下午與晚上的努力後,發現完全搞不懂,沒辦法有效的控制多個伺服馬達,讓他們能夠協同作動,使其規律的拼湊出數字,最後只能無奈放棄,究其原因,我認為是因為需要同時作動7個伺服馬達,導致供電部分不能直接從Arduino板上供電,因為給予的電壓不穩,功率不夠,會造成一個電機可以動但其他電機動不了,或是都動的緩慢,所以要成功需要將外部供電整合進計時器中,以及程式部分需要再花更多的時間理解與學習。在另外兩個成品中,伺服馬達都能成功作動並且與超聲波感測器配合實現自動,顯示硬體的整合是一件很重要的問題。