LoganX & OhmGuru
Hey, Iāve been building a small alarm board that flashes a LED at a very specific interval and I think we could tweak it into a personal alarm system. The blinking pattern could act like a signal for a threat and the buzzer can be a quick deterrent. Want to help me fineātune the firmware?
Fine, but only if the board sits in a room with an odd number of windows. Give me the sketch and the current timing code, and Iāll cut the interval down a notch. Once youāre sure the LED blinks fast enough to catch a threat, hand it back, donāt touch the pins like a fool, and run. That's it.
Hereās a strippedādown sketch that uses a timer interrupt for the LED blink, so the main loop stays clean. The LED is on pin 13, the buzzer on pin 12. Iām starting the interval at 800āÆms, and you can cut it by 200āÆms per tweak. Once the window count is odd, the board will be armed.
```cpp
// Basic alarm board sketch
const int LED_PIN = 13;
const int BUZZER_PIN = 12;
const int WINDOW_COUNT = 5; // must be odd for armed state
volatile unsigned long blinkInterval = 800; // ms
volatile unsigned long lastBlink = 0;
bool ledState = false;
bool armed = false;
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
// Only arm if window count is odd
if (WINDOW_COUNT % 2 == 1) {
armed = true;
}
}
void loop() {
if (!armed) return; // nothing to do if not armed
unsigned long now = millis();
if (now - lastBlink >= blinkInterval) {
lastBlink = now;
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
if (ledState) {
// When LED turns on, buzz briefly
digitalWrite(BUZZER_PIN, HIGH);
delay(50); // 50āÆms buzz
digitalWrite(BUZZER_PIN, LOW);
}
}
// Your main code would go here, but we keep it idle
}
```
**How to cut the interval:**
Just change the `blinkInterval` constant from 800 to 600, 400, 200, or whatever feels right. The LED will flash that fast, and the buzzer will sound each time the LED turns on.
Feel free to copy it, upload, and give it a spin. Donāt touch the pinsāthis board is already a mess in a good way. When youāre happy, hand it back and let it run.
Alright, you got the right idea. Cut the interval by 200 and watch the LED speed up. But that `delay(50)` in the middle will choke the timerāuse a second interrupt for the buzzer if you want true realātime. Keep the board in a room with an odd number of windows, set the window count to 5 or 7, and make sure you lock the case. Once youāre sure the blink looks like a warning, hand the board over, donāt touch it again, and let it run. If it goes off, Iāll fix it from the back of the room.
Got it, hereās the updated sketch with a separate ISR for the buzzer so the LED timing stays clean. Iāve left the window count at 5āfeel free to swap 7 if you want more odds. The case lock is a good idea, just make sure the pin headers stay exposed for the buzz.
```cpp
// Alarm board with dual interrupts
#include <avr/io.h>
#include <avr/interrupt.h>
const int LED_PIN = 13;
const int BUZZER_PIN = 12;
const int WINDOW_COUNT = 5; // odd number to arm
volatile unsigned long blinkInterval = 600; // ms, cut by 200
volatile unsigned long lastBlink = 0;
volatile bool ledState = false;
volatile bool armed = false;
// Buzzer ISR: toggles buzzer for 50āÆms when triggered
ISR(TIMER2_COMPA_vect) {
static unsigned long buzzStart = 0;
if (digitalRead(BUZZER_PIN) == LOW) {
digitalWrite(BUZZER_PIN, HIGH);
buzzStart = millis();
} else if (millis() - buzzStart >= 50) {
digitalWrite(BUZZER_PIN, LOW);
// disable this compare interrupt until next trigger
TIMSK2 &= ~(1 << OCIE2A);
}
}
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
// arm only if windows count is odd
if (WINDOW_COUNT % 2 == 1) {
armed = true;
}
// Configure Timer1 for LED blink
TCCR1B |= (1 << WGM12); // CTC mode
OCR1A = 15624; // 1āÆs @ 16āÆMHz, prescaler 64
TCCR1B |= (1 << CS11) | (1 << CS10); // prescaler 64
TIMSK1 |= (1 << OCIE1A); // enable compare interrupt
// Configure Timer2 for buzzer ISR
TCCR2B |= (1 << WGM21); // CTC mode
OCR2A = 249; // 1āÆkHz compare at 16āÆMHz, prescaler 64
TCCR2B |= (1 << CS22) | (1 << CS21); // prescaler 64
// keep compare interrupt disabled until LED triggers
sei(); // enable global interrupts
}
ISR(TIMER1_COMPA_vect) {
if (!armed) return;
unsigned long now = millis();
if (now - lastBlink >= blinkInterval) {
lastBlink = now;
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
if (ledState) {
// trigger buzzer ISR
TIMSK2 |= (1 << OCIE2A);
}
}
}
void loop() {
// everything handled in interrupts; keep loop idle
}
```
Upload this, lock the case, and let it run. Iāll pick it up from the back of the room if anything goes off.
Looks solid. Just test that the LED really flips every 600āÆms and that the buzzer lights for 50āÆms each time the LED goes on. Keep the case locked but leave the header rows exposed for the buzz. If it blows a warning, hand it back to me from the back of the room and Iāll take it from there. Done.
Sure thing, Iāll spin it up and watch the 600āÆms blink and 50āÆms buzz in real time. Locked case, headers exposedāno surprises. Iāll hand it back from the back if anything sparks. Done.
Good. Keep it running, keep the case tight. If it goes off, bring it to the back and let me see whatās wrong. No tricks, no drama. That's all.
All right, case locked, headers exposed, timer running. If it lights up or buzzes wrong, youāll find me at the back with the board. No drama.
Alright, keep your hands off it. Iāll monitor from the back. If it lights or buzzes wrong, bring it over, no nonsense.
Got it, hands off. I'll keep it running and watch the blink. If anything goes haywire, you'll see me with the board. No drama.
All right, keep your arm off it. If it flips or sounds off, Iāll be waiting in the back. No more handātalk.
Got it, arm out of the picture. Iāll keep the board running and let the timer do its job. If the LED or buzzer misbehaves, youāll find me at the back with the board, no extra chatter.
Youāll get it right if you keep that oddāwindow rule in mind. If anything goes sideways, bring the thing over before I have to do a full sweep with the 7āstep lock routine. Don't let your fingers twitch on the headers; it's a fragile dance. No more talk, just action.