I have been using basically the same sketch for awakening a remote from sleep, and reading a keypad for 2 years now.
Suddenly now its giving me hassles, I have checked my wiring, even checked that I didn't fit N/C pushbuttons instead of N/O.
here's a sketch of the circuit for the keypad, actually 5 N/O pushbuttons.
The buttons on column 2 and 3 work most of the time, but sometimes do not send the data, the serial monitor just shows "sleep" when it has gone through its loop.
Both buttons on column 1 do not work. But if I hook a scope probe on column 1, both buttons run through the loop ( and show " sleep " ) and intermittently with no scope attached.
I have swapped the physical wiring over from pins 12 and 17, and its still the buttons connected to pin 17 that misbehave.
I have tried different pins for all the keypad, but no different, any ideas ?
I can just have the 5 switches grounding 5 pins with 5 diodes from the interrupt, but I want to know whats happening ...
Heres the sketch
#include <VirtualWire.h> // Wireless transmitter/receiver library
#include <Keypad.h> // Matrix Keypad library
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library
uint8_t SW[4]; // assign four data pins from bcd switches
int SW0 = 5; // bits to read from bcd switches LSB
int SW1 = 6;
int SW2 = 7;
int SW3 = 8; // - MSB
int address = 0;
int add0; // bits generated from bcd switches
int add1;
int add2;
int add3;
int clockPin = 18;
int resetPin = 19;
int PIN = 18; // preset pin number to send
int dataA; // DATA REBUILT FROM BCD INPUTS FROM SWITCHES
int dataB;
int dataC;
int dataD;
int dataF;
int dataG;
int pause=HIGH;
int dpin0 = 0; // apparently redefined by Serial as Serial Monitor works
int dpin1 = 1; // apparently redefined by Serial as Serial Monitor works
int pin2 = 2; // Int0 interrupt pin
int sleep_count = 0; // flag/counter to tell us to go sleep
// create an array to store data to be sent out
char msg [10]; // keeping msg 0 for now as we dont have period
// set up the Keypad
const byte ROWS = 2; // two rows
const byte COLS = 3; // three columns
// Define the Keymap
char keys[ROWS][COLS] =
{
{
'A', 'B','C' }
, // row 1 //
{
'D','E', 'F' }
, // row 2
};
byte rowPins[ROWS] = {
14, 15 }; // Keypad uses internal pullups? No externals supplied
// Pressing a Row button connects to a Low Columna and pulls the appropriate Row Diode Low for a Pin2 Low interrupt.
// Column pins are then set back high for the keypad library button determination.
byte colPins[COLS] = {
13,12,11};
// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//***************************************************
// * Name: pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. */
}
//***************************************************
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. */
attachInterrupt(0, pin2Interrupt, FALLING);
delay(50); // need this?
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep ...
sleep_enable(); // setting up for sleep ...
ADCSRA &= ~(1 << ADEN);
PRR = 0xFF;
sleep_mode(); // now goes to Sleep and waits for the interrupt
/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts while we get ready to read the keypad
PRR = 0x00;
/* First thing to do is disable sleep. */
sleep_disable();
// set all the keypad columns back high so can read keypad presses again
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
// then go to the void Loop()
}
void setup()
{
Serial.begin(9600);
pinMode(pin2, INPUT); // our sleep interrupt pin
digitalWrite(pin2, HIGH); // set pull up res
// define all the unused pins as inputs with internal pullups for lower power state
pinMode(dpin0, INPUT); // apparently redefined by Serial as Serial Monitor works (receiving anyway)
digitalWrite(dpin0, HIGH); // apparently redefined by Serial as Serial Monitor works
pinMode(dpin1, INPUT); // apparently redefined by Serial as Serial Monitor works
digitalWrite(dpin1, HIGH); // apparently redefined by Serial as Serial Monitor works
digitalWrite(dpin0, HIGH);
pinMode (resetPin , OUTPUT );
pinMode (clockPin , OUTPUT );
pinMode(SW0, INPUT); // LSB of bcd
byte add0 = 0;
pinMode(SW1, INPUT); // LSB+1
byte add1= 0;
pinMode(SW2, INPUT); // LSB+2
byte add2 = 0;
pinMode(SW3, INPUT); // MSB of bcd
byte add3 = 0;
PIN = 18; // ( preset for WPCC to 1101 ( 13 ) Pin number SACS = 11 Glenwoodrugby 18
Serial.println("my address is: ");
Serial.println(PIN, BIN);
digitalWrite(SW0, LOW); // disable pullups on PIN inputs to save current, finished with these pins PIN read.msg[0]
digitalWrite(SW1, LOW);
digitalWrite(SW2, LOW);
digitalWrite(SW3, LOW);
Serial.println("TX setup"); // for debug only
// vw_set_rx_pin(0);
vw_set_tx_pin(4); // data
vw_set_ptt_pin(3); // powers Tx and LED
vw_setup(2000);
digitalWrite(resetPin, HIGH);
digitalWrite(clockPin, LOW);
digitalWrite(resetPin, LOW);
}
// *************************************************************************end of void Setup()
void loop()
{
if (sleep_count>100){ // check if we should go to sleep because of "time" --> Try shorter versions of this
sleep_count=0; // turn it off for when we wake up
Serial.println("Sleep"); // for debug only
// digitalWrite(3, LOW);// set the columns low before sleeping, otherwise Keypad leaves them high and Rows have nothing to pull low.
digitalWrite(11,LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
digitalWrite(resetPin, HIGH); // making sue 4017 is off
digitalWrite(clockPin, LOW);
digitalWrite(resetPin, LOW);
enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()
} // end of checking to go to sleep
// Serial.println("wake up and read keypad");
char key = keypad.getKey(); // reading the keypad
if(key) // same as if(key != NO_KEY)- did something change?
{
Serial.print("key read =");
Serial.println(key);
msg [0] = PIN;
msg [1] = key;
digitalWrite(resetPin, LOW); // making sue 4017 is off
for ( int h = 2; h <= 9; h++ ) { // commutate all switch banks
digitalWrite(clockPin, HIGH);
address=0;
add3 = digitalRead(SW3);
add3 = add3 << 3;
add2 = digitalRead(SW2);
add2 = add2 << 2;
add1 = digitalRead(SW1);
add1 = add1 << 1;
add0 = digitalRead(SW0);
address = address|add3;
address = address|add2;
address = address|add1;
address = address|add0;
msg [h] = address;
digitalWrite(clockPin, LOW);
delay ( 5 );
}
digitalWrite(resetPin, HIGH); // making sure 4017 is off
for ( int k= 0; k <=9; k++ ) {
Serial.print("msg = ");
Serial.print(k);
Serial.print(" = ");
Serial.println(int ( msg[k]) );
}
vw_send((uint8_t *)msg, 10); // send the character out
vw_wait_tx(); // Wait until the whole message is gone
sleep_count = 0; // reset count up to sleep if transmitted a key press
} // // end of if(key) & transmitting a character
sleep_count ++;
} // end of void loop