Hi all,
looking for a quick advise on the following topic.
I have a Mega controlling a thermal solar unit. Lots of relays, temperature sensors, timers, several displays on it, and a keypad to control & modify things.
The whole thing works well in its current incarnation including the keypad. However because the keypad poll gets slower with other stuff the mc needs to do with more and more things I am adding the pad became less and less responsive.
I could add a diode chain and tie it to a single interrupt pin, but because the 4 column pins are already on interrupt capable pins I thought I could use those as direct interrupts.
Hardware:
Arduino Mega
4x4 keypad: http://img04.taobaocdn.com/imgextra/i4/44390641/T201uyXeBaXXXXXXXX_!!44390641.jpg
With the code below it works on the 1st keypress perfectly, subsequent keystrokes produce an interrupt but return an empty character, and after some further 5 to 10 strikes it reads it again correctly (once).
#include <PWM.h>
#include <Shifter.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <PinChangeInt.h>
#include <Average.h>
#include <MemoryFree.h>
#include <avr/wdt.h>//watchdog! resets ardo if hangs DOES NOT WORK ON MEGA with original bootloader
#include <SPI.h>//SD Modul Com
#include <SD.h>//SD Funktionen
#include <Wire.h>//LCD
#include <LiquidCrystal_I2C.h>//LCD
#include <OneWire.h>//Tempsens
#include <DallasTemperature.h>//Tempsens
#include <DS1307RTC_drift.h>//Clock
#include <Time_drift.h>//Uhrzeit
#include <Keypad.h>
...
void setup() {
byte rowPins[ROWS] = {35, 34, 33, 32}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A10, A11, A8, A9}; //connect to the column pinouts of the keypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);//initialize an instance of class NewKeypad
...
//interrupt chrck - col - input high;
pinMode(A10, INPUT_PULLUP);
pinMode(A11, INPUT_PULLUP);
pinMode(A8, INPUT_PULLUP);
pinMode(A9, INPUT_PULLUP);
//row output LOW
pinMode(35, OUTPUT);
pinMode(34, OUTPUT);
pinMode(33, OUTPUT);
pinMode(32, OUTPUT);
digitalWrite (35, LOW);
digitalWrite (34, LOW);
digitalWrite (33, LOW);
digitalWrite (32, LOW);
//interrupt col pins
PCintPort::attachInterrupt(12, &key_inter, CHANGE);//another interrupt - unrelated to keypad
PCintPort::attachInterrupt(A10, &key_poll, FALLING);
PCintPort::attachInterrupt(A11, &key_poll, FALLING);
PCintPort::attachInterrupt(A8, &key_poll, FALLING);
PCintPort::attachInterrupt(A9, &key_poll, FALLING);
...
void key_poll()
{
PCintPort::detachInterrupt(A10);
PCintPort::detachInterrupt(A11);
PCintPort::detachInterrupt(A8);
PCintPort::detachInterrupt(A9);
customKey = customKeypad.getKey();
Serial1.println(customKey);//debug
pinMode(35, OUTPUT);
pinMode(34, OUTPUT);
pinMode(33, OUTPUT);
pinMode(32, OUTPUT);
digitalWrite (35, LOW);
digitalWrite (34, LOW);
digitalWrite (33, LOW);
digitalWrite (32, LOW);
pinMode(A10, INPUT_PULLUP);//keypad
pinMode(A11, INPUT_PULLUP);
pinMode(A8, INPUT_PULLUP);
pinMode(A9, INPUT_PULLUP);
delayMicroseconds(15000);
PCintPort::attachInterrupt(A10, &key_poll, FALLING);
PCintPort::attachInterrupt(A11, &key_poll, FALLING);
PCintPort::attachInterrupt(A8, &key_poll, FALLING);
PCintPort::attachInterrupt(A9, &key_poll, FALLING);
return;
}
I tried "waitkey()", delays, and then something like this in the interrupt routine:
// int counter = 0;
//while (customKey == NO_KEY || counter < 1000)
//{
//customKey = customKeypad.getKey();
//counter = counter + 1;
//delayMicroseconds(1);
//}
but this does freeze the µ-c.
I would now go forward and throw out the keypad library and see if I can get a simple scanning algorithm together to detect keypresses unless someone tells me I am missing something else ...
Best regards,
-Thomas