Complete code. This is a sketch I made for testing a keypad and I just extended it to experiment with timer.
I have made some changes to the calculation of the interruptTimeInterval.
#include <Keypad_I2C.h>
#include <Keypad.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define KEYPAD_ADDR 0x20
#define LCD_ADDR 0x27
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {0, 1, 2, 3};
byte colPins[COLS] = {4, 5, 6, 7};
Keypad_I2C keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS, KEYPAD_ADDR, PCF8574);
LiquidCrystal_I2C lcd1(
0x27, // LCD address on the I2C bus.
2, // En: (Enable) pin connected to the IO extender module
1, // Rw: (Read/write) pin connected to the IO extender module
0, // Rs: (Reset) pin connected to the IO extender module
4, // d4: data 0 pin map on IO extender module
5, // d5: data 1 pin map on IO extender module
6, // d6: data 2 pin map on IO extender module
7 // d7: data 3 pin map on IO extender module
);
char keyPressed[17];
// For LED indicator board.
#define LEDCNT 6
const int ledPins[LEDCNT] = {8, 9, 10, 11, 12, 13};
volatile int ledStatus[LEDCNT];
volatile long interruptTimeInterval = 0;
#define INTERRUPT_LED 5
#define INTERRUPT_TIME_SEC 10
void setup()
{
Serial.begin(9600);
for (int i = 0; 17 > i; i++) {
keyPressed[i] = '\0';
}
// Set up LEDs.
for (int i = 0; LEDCNT > i; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
ledStatus[i] = LOW;
}
// Set up keybaord.
Wire.begin();
keypad.begin(makeKeymap(keys));
// Set up LCD display.
lcd1.begin(16, 2);
lcd1.setBacklightPin(3, POSITIVE);
lcd1.setBacklight(HIGH);
lcd1.print("KEYPAD TEST");
// Set up software interrupt.
interruptTimeInterval = 65536 - (16000000 / (INTERRUPT_TIME_SEC * 1024));
Serial.print("Interrupt time interval=");
Serial.println(interruptTimeInterval);
delay(500);
cli();
// Set up timer 1 (16 bit timer).
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = interruptTimeInterval;
TCCR1B |= (1 << CS10) | (1 << CS12); // Prescale set to 1024
TIMSK1 |= (1 << TOIE1);
sei();
Serial.println("start");
}
ISR(TIMER1_OVF_vect)
{
TCNT1 = interruptTimeInterval;
ledStatus[INTERRUPT_LED] = (LOW == ledStatus[INTERRUPT_LED]) ? HIGH : LOW;
digitalWrite(ledPins[INTERRUPT_LED], ledStatus[INTERRUPT_LED]);
}
void loop()
{
static int keypos = -1;
char key = keypad.getKey();
int n = 0;
if (key) {
Serial.println(key);
if (15 <= keypos++) {
for (int i = 1; 17 > i; i++) {
keyPressed[i - 1] = keyPressed[i];
}
--keypos;
}
keyPressed[keypos] = key;
lcd1.setCursor(0, 1);
lcd1.print(keyPressed);
n = key - '1';
if (0 <= n && 6 > n) {
ledStatus[n] = (LOW == ledStatus[n]) ? HIGH : LOW;
digitalWrite(ledPins[n], ledStatus[n]);
}
}
}