// KEYES MQ-3 酒精感測器 + Raspberry Pi Pico W
// 讀取類比輸出並在序列埠顯示數值與簡易判斷(含預熱時間)
const int MQ3_PIN = A0; // MQ-3 類比輸出接 Pico W 的 A0
const int LED_PIN = LED_BUILTIN; // Pico W 內建 LED
// === 預熱時間設定(以「分鐘」為單位) ===
const int PREHEAT_MINUTES = 1; // 建議預熱 10 分鐘以上
const unsigned long PREHEAT_MS = (unsigned long)PREHEAT_MINUTES * 60UL * 1000UL;
// 簡單序列印出控制
unsigned long lastPreheatPrint = 0;
// 這個門檻值要依實際環境微調:
// Pico W 的 ADC 是 12-bit(0~4095),
// 可以先觀察「乾淨空氣」的數值,再決定門檻。
int alcoholThreshold = 2000; // 範例值,請之後用乾淨空氣/酒精實測微調
void setup() {
pinMode(MQ3_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
analogReadResolution(12);
Serial.begin(115200);
while (!Serial) {
// 等待序列埠就緒(USB 連線)
}
Serial.println("MQ-3 酒精感測器 - Pico W 測試");
Serial.print("預熱時間設定:");
Serial.print(PREHEAT_MINUTES);
Serial.println(" 分鐘");
Serial.println("預熱期間只顯示倒數,不做酒精濃度判斷");
Serial.println("===========================================");
}
void loop() {
unsigned long now = millis();
// ============================
// 預熱階段:只做倒數提示
// ============================
if (now < PREHEAT_MS) {
// 關閉 LED
digitalWrite(LED_PIN, LOW);
// 每 1 秒輸出一次剩餘時間
if (now - lastPreheatPrint >= 1000) {
lastPreheatPrint = now;
unsigned long remainMs = PREHEAT_MS - now;
unsigned long remainSec = remainMs / 1000;
unsigned long remainMin = remainSec / 60;
unsigned long remainSecInMin = remainSec % 60;
Serial.print("預熱中,剩餘約 ");
Serial.print(remainMin);
Serial.print(" 分 ");
Serial.print(remainSecInMin);
Serial.println(" 秒...");
}
return; // 還在預熱,下面的偵測邏輯先不跑
}
// ============================
// 預熱完成,開始正式量測
// ============================
// 讀多次取平均,讓數值穩定一點
const int samples = 10;
long sum = 0;
for (int i = 0; i < samples; i++) {
int val = analogRead(MQ3_PIN); // 0 ~ 4095
sum += val;
delay(5); // 小延遲,避免太快
}
int rawValue = sum / samples; // 平均後的 ADC 值
// 將 ADC 值轉換為電壓(這裡以 5V 來換算)
float voltage = rawValue * (5.0 / 4095.0);
// 判斷是否有較高濃度酒精
bool alcoholDetected = (rawValue > alcoholThreshold);
// 控制 LED:有偵測到就亮
digitalWrite(LED_PIN, alcoholDetected ? HIGH : LOW);
// 印出資訊
Serial.print("ADC Raw = ");
Serial.print(rawValue);
Serial.print("\tVoltage = ");
Serial.print(voltage, 3);
Serial.print(" V\tStatus = ");
if (alcoholDetected) {
Serial.println("Alcohol Detected(酒精濃度較高)!!");
} else {
Serial.println("Normal / Clean Air(正常或低濃度)");
}
delay(200); // 每 200ms 更新一次
}