高三多元選修科技應用專題
平交道程式設計unknown
c_cpp
16 days ago
5.0 kB
6
Indexable
#include <Servo.h> // 引入控制伺服馬達的函式庫 // 定義蜂鳴器使用的兩個音調頻率(單位 Hz) #define NOTE_G5 784 #define NOTE_F5 698 // 設定 LED、蜂鳴器與按鈕的接腳編號 const int yellowLED = 4; const int redLED = 8; const int greenLED = 12; const int buzzer = 2; const int button = A1; // 馬達設定 Servo motor; // 宣告伺服馬達物件 const int MOTOR_PIN = 11; // 馬達控制腳位 // 設定馬達控制的 PWM 值(數值大約 0~180 之間) const int MOTOR_CW = 60; // 順時針轉動時的 PWM 值(較小代表順時針) const int MOTOR_CCW = 130; // 逆時針轉動時的 PWM 值(較大代表逆時針) const int MOTOR_STOP = 90; // 停止轉動時的 PWM 值 // 控制馬達轉動的時間(以毫秒為單位) const int rotationTime = 3750; // 順時針轉動 540 度所需時間 const int rotationTimeReverse = 4100; // 逆時針轉動 540 度所需時間(略長以補轉速差) const int motorHoldTime = 5000; // 停止等待時間 5 秒 // 用於紀錄計時的變數 long motorStartTime, warningStartTime, buzzerStartTime; // 紅黃燈交替、蜂鳴器交替的切換時間 const int warningDelay = 250; // 紅黃燈交替頻率(250ms) const int buzzerDelay = 500; // 蜂鳴器交替頻率(500ms) // 狀態控制:w=等待、d=正轉、p=等待、u=逆轉 char state = 'w'; // 控制燈與蜂鳴器的開關狀態 bool redLightOn = false; bool buzzerToneG5 = true; void setup() { Serial.begin(9600); // 啟動序列埠,方便除錯輸出 // 設定腳位模式 pinMode(buzzer, OUTPUT); pinMode(yellowLED, OUTPUT); pinMode(redLED, OUTPUT); pinMode(greenLED, OUTPUT); pinMode(button, INPUT); // 馬達初始化為停止 motor.attach(MOTOR_PIN); motor.write(MOTOR_STOP); // 初始顯示為綠燈亮 digitalWrite(greenLED, HIGH); digitalWrite(redLED, LOW); digitalWrite(yellowLED, LOW); } void loop() { // 顯示目前狀態於序列監控視窗 Serial.print("狀態: "); Serial.println(state); // === 等待啟動狀態(w)=== if (state == 'w') { noTone(buzzer); // 停止蜂鳴器 digitalWrite(greenLED, HIGH); // 綠燈常亮 digitalWrite(redLED, LOW); digitalWrite(yellowLED, LOW); motor.write(MOTOR_STOP); // 馬達不轉 // 按鈕被按下後,切換到正轉(d)狀態 if (digitalRead(button) == LOW) { state = 'd'; motorStartTime = millis(); // 記錄開始時間 } } // === 正轉、等待、逆轉階段中通用的:紅黃燈交替與蜂鳴器 === if (state == 'd' || state == 'p' || state == 'u') { // 紅黃燈交替閃爍 if (millis() - warningStartTime >= warningDelay) { redLightOn = !redLightOn; // 交替狀態切換 digitalWrite(redLED, redLightOn ? HIGH : LOW); digitalWrite(yellowLED, redLightOn ? LOW : HIGH); digitalWrite(greenLED, LOW); // 綠燈熄滅 warningStartTime = millis(); } // 蜂鳴器交替播放 G5 和 F5 if (millis() - buzzerStartTime >= buzzerDelay) { if (buzzerToneG5) { tone(buzzer, NOTE_G5, 400); } else { tone(buzzer, NOTE_F5, 400); } buzzerToneG5 = !buzzerToneG5; delay(100); // 小延遲,避免音調黏在一起 noTone(buzzer); // 停止音調 buzzerStartTime = millis(); } } // === 正轉狀態(d) === if (state == 'd') { Serial.println("馬達: 順時針旋轉"); motor.write(MOTOR_CW); // 馬達順時針轉 if (millis() - motorStartTime >= rotationTime) { // 時間到 → 停止,進入等待狀態(p) state = 'p'; motor.write(MOTOR_STOP); Serial.println("馬達: 停止"); motorStartTime = millis(); // 重置時間 } } // === 停止狀態(p) === if (state == 'p') { motor.write(MOTOR_STOP); // 保持馬達停止 if (millis() - motorStartTime >= motorHoldTime) { state = 'u'; // 進入逆轉狀態 motorStartTime = millis(); } } // === 逆轉狀態(u) === if (state == 'u') { Serial.println("馬達: 逆時針旋轉"); motor.write(MOTOR_CCW); // 馬達逆時針轉 if (millis() - motorStartTime >= rotationTimeReverse) { // 逆轉完成 → 回到等待狀態(w) state = 'w'; motor.write(MOTOR_STOP); Serial.println("馬達: 停止"); digitalWrite(greenLED, HIGH); // 恢復綠燈常亮 } } }
Editor is loading...
Leave a Comment