#include <Arduino.h>
// Määritellään painikkeiden pinnit ja niiden määrä
const int buttonPins[] = {2, 3, 4, 5, 6}; // Painikkeiden pinnit
const int numButtons = sizeof(buttonPins) / sizeof(buttonPins[0]); // Painikkeiden määrä
// Debounce-asetukset
const unsigned int debounceDelay = 50; // Debounce-viive (millisekunteina)
unsigned long lastDebounceTime[numButtons] = {0}; // Viimeisin debounce-ajastimen aika
bool lastButtonState[numButtons] = {HIGH}; // Edellinen tila (HIGH, koska käytetään INPUT_PULLUP)
// Funktio, joka alustaa painikkeet ja keskeytykset
void initButtonsAndButtonInterrupts() {
// Alustetaan painikkeet
for (int i = 0; i < numButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP); // Aseta painike INPUT_PULLUP-tilaan
}
// Mahdollistetaan PCINT2 (pins D2-D7) keskeytykset
PCICR |= (1 << PCIE2);
PCMSK2 |= 0b01111100; // Mahdollistetaan keskeytykset pinneille 2, 3, 4, 5, 6
}
// Keskeytyspalvelija käsittelee painikkeet debounce-logiikalla
ISR(PCINT2_vect) {
unsigned long currentTime = millis();
// Käydään läpi kaikki painikkeet
for (int i = 0; i < numButtons; i++) {
bool currentButtonState = digitalRead(buttonPins[i]);
// Tarkista, onko painikkeen tila muuttunut edellisestä
if (currentButtonState != lastButtonState[i]) {
lastDebounceTime[i] = currentTime; // Nollaa debounce-ajastin
}
// Jos tarpeeksi aikaa on kulunut viimeisestä tilanmuutoksesta
if ((currentTime - lastDebounceTime[i]) > debounceDelay) {
// Jos painike on vakaa ja LOW-tilassa
if (currentButtonState == LOW && lastButtonState[i] == HIGH) {
// Tulosta painetun painikkeen pinni
Serial.print("Nappia ");
Serial.print(buttonPins[i]);
Serial.println(" painettu.");
}
}
// Päivitä edellinen tila nykyiseen
lastButtonState[i] = currentButtonState;
}
}
void setup() {
Serial.begin(9600); // Sarjayhteyden alustus
initButtonsAndButtonInterrupts(); // Kytkimien ja keskeytysten alustus
Serial.println("Ohjelma käynnistyi");
}
void loop() {
// Ei tarvetta tehdä mitään loopissa, koska keskeytykset hoitavat kaiken.
}