#include <Keypad.h>
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] =
{
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 44, 42, 40, 38 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 52, 50, 48, 46 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const byte hookPinA = 23; // your interrupt pin
const byte interruptPin = 22; // your interrupt pin
const byte column4InterruptPin = 2; // Column 4 interrupt pin connected to column4Pin via a wire link. Could add a 1K series resistor to protect against short circuit to ground if it were output low when pin 38 is output high.
const byte column4Pin = 38; // Column 4 pin connected to column4InterruptPin via a wire link.
// States updated by ISR.
volatile byte isr_hookOffState = 0;
volatile byte isr_interruptState = 0;
volatile bool isr_column4Pressed = false;
// Working copies of ISR data.
byte hookOffState = 0;
byte interruptState = 0;
bool column4Pressed = false;
// Use a single byte for the state variable and initialise it to OFF.
enum class State : byte
{
OFF = 0,
IDLE = 1,
LISTEN_KEY = 2,
PLAYER = 3
} state = State::OFF;
void setup()
{
Serial.begin(115200);
pinMode(hookPinA, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(hookPinA), hookOffToggle, CHANGE);
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), interruptToggle, RISING); // test interrupt with a regular button
pinMode(column4InterruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(column4InterruptPin), interruptColumn4, FALLING); // Triggered by pulling column 4 low, e.g. digitalWrite(column4Pin, LOW) or within myKeypad.getKey().
}
void loop()
{
const char key = keypad.getKey();
if (key != NO_KEY)
{
Serial.println(key);
}
// Get a fresh copy of the ISR data and reset the interrupt state flag atomically
// by temporarily disabling interrupts.
cli();
hookOffState = isr_hookOffState;
interruptState = isr_interruptState;
column4Pressed = isr_column4Pressed;
isr_interruptState = 0; // Reset to detect next interrupt.
isr_column4Pressed = false; // Reset to detect next interrupt.
sei();
// Non-interrupt alternative method to test whether any button in column 4 is pressed.
/*
pinMode(column4Pin, OUTPUT);
digitalWrite(column4Pin, LOW);
column4Pressed = !digitalRead(52) || !digitalRead(50) || !digitalRead(48) || !digitalRead(46);
digitalWrite(column4Pin, HIGH);
pinMode(column4Pin, INPUT);
*/
// Debug prints.
//Serial.println(column4Pressed);
if (column4Pressed)
{
Serial.println("Column 4 is pressed.");
}
// Process the working copies of the ISR data.
// You will need to change the state machine logic to process column4Pressed obtained from the ISR or the alternative method.
switch (state)
{
case State::OFF:
break;
case State::IDLE:
break;
case State::LISTEN_KEY:
break;
case State::PLAYER:
break;
}
}
void hookOffToggle()
{
isr_hookOffState = digitalRead(hookPinA);
}
void interruptToggle()
{
isr_interruptState = 1;
}
void interruptColumn4()
{
// Test whether any button in column 4 is pressed.
isr_column4Pressed = !digitalRead(52) || !digitalRead(50) || !digitalRead(48) || !digitalRead(46);
}
mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
keypad1:R1
keypad1:R2
keypad1:R3
keypad1:R4
keypad1:C1
keypad1:C2
keypad1:C3
keypad1:C4
logic1:D0
logic1:D1
logic1:D2
logic1:D3
logic1:D4
logic1:D5
logic1:D6
logic1:D7
logic1:GND