多元選修
unknown
c_cpp
8 months ago
5.1 kB
14
Indexable
#include <Servo.h> // 引入控制伺服馬達的函式庫
// 定義蜂鳴器使用的兩個音調頻率(單位 Hz)
#define NOTE_G5 784
#define NOTE_F5 698
// 設定 LED、蜂鳴器與按鈕的接腳編號
const int yellowLED = 8;
const int redLED = 5;
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 = 1200; // 順時針轉動時的 PWM 值(較小代表順時針)
const int MOTOR_CCW = 1800; // 逆時針轉動時的 PWM 值(較大代表逆時針)
const int MOTOR_STOP = 1500; // 停止轉動時的 PWM 值
// 控制馬達轉動的時間(以毫秒為單位)
const int rotationTime = 3700; // 順時針轉動 540 度所需時間
const int rotationTimeReverse = 4550; // 逆時針轉動 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.writeMicroseconds(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.writeMicroseconds(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.writeMicroseconds(MOTOR_CW); // 馬達順時針轉
if (millis() - motorStartTime >= rotationTime) {
// 時間到 → 停止,進入等待狀態(p)
state = 'p';
motor.writeMicroseconds(MOTOR_STOP);
Serial.println("馬達: 停止");
motorStartTime = millis(); // 重置時間
}
}
// === 停止狀態(p) ===
if (state == 'p') {
motor.writeMicroseconds(MOTOR_STOP); // 保持馬達停止
if (millis() - motorStartTime >= motorHoldTime) {
state = 'u'; // 進入逆轉狀態
motorStartTime = millis();
}
}
// === 逆轉狀態(u) ===
if (state == 'u') {
Serial.println("馬達: 逆時針旋轉");
motor.writeMicroseconds(MOTOR_CCW); // 馬達逆時針轉
if (millis() - motorStartTime >= rotationTimeReverse) {
// 逆轉完成 → 回到等待狀態(w)
state = 'w';
motor.writeMicroseconds(MOTOR_STOP);
Serial.println("馬達: 停止");
digitalWrite(greenLED, HIGH); // 恢復綠燈常亮
}
}
}
Editor is loading...
Leave a Comment