// ================= PIN =================
#define PIN_FAIL 1 // PB1 (LOW = FAIL)
#define PIN_RESTORE 4 // PB4 (LOW = RESTORE)
#define PIN_BUZZ 0 // PB0
#define PIN_MUTE 3 // PB3
// ============== PARAMETER ==============
#define BUZ_FREQ_FAST 3000 // Hz
#define BUZ_ON_SLOW 200 // ms
#define BUZ_OFF_SLOW 1000 // ms
#define DEBOUNCE_MS 50
#define SCAN_MS 10
// ================= STATE =================
enum AlarmState {
ALARM_IDLE,
ALARM_FAIL,
ALARM_RESTORE
};
AlarmState alarmState = ALARM_IDLE;
bool mute = false;
bool lastMute = HIGH;
// debounce
unsigned long tFail = 0;
unsigned long tRestore = 0;
bool failStable = false;
bool restoreStable = false;
// buzzer
unsigned long tToggle = 0;
bool buzState = false;
unsigned long tSlow = 0;
// ================= UTIL =================
bool debounce(bool raw, bool &state, unsigned long &timer, unsigned long now) {
if (raw != state) {
if (now - timer > DEBOUNCE_MS) {
state = raw;
timer = now;
}
} else {
timer = now;
}
return state;
}
// ================= SETUP =================
void setup() {
pinMode(PIN_FAIL, INPUT_PULLUP);
pinMode(PIN_RESTORE, INPUT_PULLUP);
pinMode(PIN_MUTE, INPUT_PULLUP);
pinMode(PIN_BUZZ, OUTPUT);
digitalWrite(PIN_BUZZ, LOW);
}
// ================= LOOP =================
void loop() {
unsigned long now = millis();
// ---------- INPUT ----------
bool rawFail = (digitalRead(PIN_FAIL) == LOW);
bool rawRestore = (digitalRead(PIN_RESTORE) == LOW);
bool muteBtn = digitalRead(PIN_MUTE);
// ---------- DEBOUNCE ----------
bool fail = debounce(rawFail, failStable, tFail, now);
bool restore = debounce(rawRestore, restoreStable, tRestore, now);
// ---------- STATE MACHINE ----------
switch (alarmState) {
case ALARM_IDLE:
if (fail) alarmState = ALARM_FAIL;
else if (restore) alarmState = ALARM_RESTORE;
break;
case ALARM_FAIL:
if (!fail && restore) alarmState = ALARM_RESTORE;
else if (!fail && !restore) alarmState = ALARM_IDLE;
break;
case ALARM_RESTORE:
if (fail) alarmState = ALARM_FAIL;
else if (!restore) alarmState = ALARM_IDLE;
break;
}
// ---------- MUTE ----------
if (lastMute == HIGH && muteBtn == LOW) {
mute = !mute;
}
lastMute = muteBtn;
// ---------- BUZZER ----------
if (!mute) {
// ===== FAIL (TRRRR CONTINUOUS) =====
if (alarmState == ALARM_FAIL) {
unsigned long period_us = 1000000UL / BUZ_FREQ_FAST / 2;
if (micros() - tToggle >= period_us) {
tToggle = micros();
buzState = !buzState;
digitalWrite(PIN_BUZZ, buzState);
}
}
// ===== RESTORE (SLOW BEEP) =====
else if (alarmState == ALARM_RESTORE) {
if (now - tSlow > (BUZ_ON_SLOW + BUZ_OFF_SLOW)) {
tSlow = now;
}
if (now - tSlow < BUZ_ON_SLOW) {
digitalWrite(PIN_BUZZ, HIGH);
} else {
digitalWrite(PIN_BUZZ, LOW);
}
}
// ===== IDLE =====
else {
digitalWrite(PIN_BUZZ, LOW);
}
} else {
digitalWrite(PIN_BUZZ, LOW);
}
// ---------- SCAN TIME ----------
static unsigned long lastScan = 0;
while (millis() - lastScan < SCAN_MS);
lastScan = millis();
}