#include <Arduino.h>
// ------------ Pins -------------
const uint8_t ledPins[5] = {PA2, PA3, PA4, PA5, PA6};
const uint8_t blinkPin = PA9;
const uint8_t buttonPin = PA1;
// ------------ Running LED task state -------------
volatile bool blinkRequest = false;
volatile uint32_t lastISRTime = 0;
uint8_t data = 0x80; // start bit pattern
uint32_t lastStepTime = 0;
const uint32_t stepInterval = 500; // ms
// ------------ Blink task state -------------
bool blinking = false;
int blinkCount = 0;
bool blinkLevel = false;
uint32_t lastBlinkTime = 0;
const uint32_t blinkInterval = 500; // ms
// ISR: just request blink (debounced)
void handlePB1() {
uint32_t now = millis();
if (now - lastISRTime > 500) { // debounce 200ms
blinkRequest = true;
lastISRTime = now;
}
}
void writePattern(uint8_t v) {
for (int i = 0; i < 6; i++) {
digitalWrite(ledPins[i], (v >> i) & 1);
}
}
void setup() {
// outputs
for (int i = 0; i < 6; i++) pinMode(ledPins[i], OUTPUT);
pinMode(blinkPin, OUTPUT);
digitalWrite(blinkPin, LOW);
// button
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), handlePB1, FALLING);
writePattern(0x00);
}
void loop() {
uint32_t now = millis();
// If interrupt requested and not already blinking -> start blinking task
if (blinkRequest && !blinking) {
blinkRequest = false;
blinking = true;
blinkCount = 0;
blinkLevel = false;
lastBlinkTime = now;
digitalWrite(blinkPin, LOW);
}
// ---------------- Blink task (PA8) ----------------
if (blinking) {
if (now - lastBlinkTime >= blinkInterval) {
lastBlinkTime = now;
blinkLevel = !blinkLevel;
digitalWrite(blinkPin, blinkLevel);
// Count only HIGH pulses as "1 blink"
if (blinkLevel == true) {
blinkCount++;
}
// Stop after exactly 7 ON pulses
if (blinkCount >= 6) {
blinking = false;
digitalWrite(blinkPin, LOW);
}
}
// IMPORTANT: while blinking, we pause running LED task
return;
}
// ---------------- Running LED task (PA0..PA7) ----------------
if (now - lastStepTime >= stepInterval) {
lastStepTime = now;
writePattern(data);
data >>= 1;
if (data == 0x00) {
data = 0x80; // restart cycle after reaching end
}
}
}