與Gemini對話
你是一個專案開發專家,專長是使用各種開發板做機電整合的程式設計,對於 Arduino、linIt 7697、esp32、respberry pi、jetson nano等開發板都有很多經驗,現在需你要完成一個小的練習專案,真正隨機的讓伺服馬達轉動的小實作。
#硬體部分
- 使用 linkIt 7697開發版與 Robot Shield 擴充板
- 兩顆按鍵開關模組 接在 pin 2,7
- 有四顆Sg90伺服馬 接在 pin 3,4,5,15
#功能需求
- 四顆伺服馬達,起始角度都是10度。
- 亂數按鍵:按鍵模組(接在pin 2)按下後,隨機讓每一顆伺服馬達轉動到120度(每次按下伺服馬順序都不一樣),每顆間隔1000毫秒。
-- 例如第一次按下後,伺服馬馬達轉動是1,2,4,3,按下復位按鍵後,再次按下亂數按鍵,伺服馬馬達轉動是2,4,1,3,類似這樣,按下案件的前、後每一次都不重複。
-- 開發板重新開機後也不會固定順序,就是真正的隨機讓伺服馬達轉動。
- 復位按鍵:按下按鍵模組(接在pin 7)按下後,四顆伺服馬達都同時轉到10度。
#程式碼
- 透過 Arduino IDE做燒錄
開啟序列埠監控視窗,伺服馬達會觸發pin 2的問題
這可能是因為 Robot Shield 的 Pin 2 或 Pin 7 有外部干擾,導致重啟時電位被拉低。
你可以試著將按鍵模組暫時拔掉,開關監控視窗看馬達是否還會亂動。
如果拔掉就不會動,建議在按鍵的 Signal 與 GND 之間並聯一個 0.1uF 的小電容,來過濾重啟時的突波雜訊。
#include <Servo.h>
// 定義腳位
const int buttonRandom = 2;
const int buttonReset = 7;
const int servoPins[] = {3, 4, 5, 15};
Servo myservos[4];
int motorOrder[] = {0, 1, 2, 3};
void setup() {
// 延遲一下,避開串列埠啟動時的電位不穩
delay(500);
Serial.begin(115200);
pinMode(buttonRandom, INPUT_PULLUP);
pinMode(buttonReset, INPUT_PULLUP);
// 1. 初始動作:僅執行回到 10 度,絕不執行亂數動作
for (int i = 0; i < 4; i++) {
myservos[i].attach(servoPins[i]);
myservos[i].write(10);
}
// 真正隨機:讀取 A0 雜訊
randomSeed(analogRead(A0) + micros());
Serial.println("--- 系統啟動完成 ---");
Serial.println("等待按鍵操作...");
}
void loop() {
// 讀取按鍵狀態
int randomState = digitalRead(buttonRandom);
int resetState = digitalRead(buttonReset);
// --- Pin 2: 亂數觸發 (嚴格判斷按下動作) ---
if (randomState == LOW) {
delay(50); // 去彈跳
if (digitalRead(buttonRandom) == LOW) {
Serial.println(">> 偵測到按鍵,開始執行亂數序列");
executeRandomSequence();
// 執行完畢後,強制等待按鍵放開才繼續,避免重啟後的電位殘留誤判
while(digitalRead(buttonRandom) == LOW) { delay(10); }
}
}
// --- Pin 7: 復位觸發 ---
if (resetState == LOW) {
delay(50); // 去彈跳
if (digitalRead(buttonReset) == LOW) {
Serial.println("<< 執行復位至 10 度");
for (int i = 0; i < 4; i++) {
myservos[i].write(10);
}
while(digitalRead(buttonReset) == LOW) { delay(10); }
}
}
}
// 將亂數邏輯獨立出來
void executeRandomSequence() {
shuffleArray(motorOrder, 4);
for (int i = 0; i < 4; i++) {
int targetIdx = motorOrder[i];
myservos[targetIdx].write(120);
Serial.print("馬達 "); Serial.print(targetIdx); Serial.println(" -> 120度");
delay(1000);
}
}
void shuffleArray(int arr[], int size) {
for (int i = size - 1; i > 0; i--) {
int j = random(0, i + 1);
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
從這個時間點去看設定 https://youtu.be/i75LKBw_xhs?t=1668