Wake from sleep mode using keypad interrupt

Status
Not open for further replies.
Hello all,

I'm having trouble figuring out a way to wake from sleep mode using my 4x4 keypad. I'm trying to make it wake up when pin 15 changes

I'm using the Keypad.h library, and the LowPower_Teensy3 library.

Here is my code:

Code:
#include <Keypad.h>
#include <LowPower_Teensy3.h>

TEENSY3_LP LP = TEENSY3_LP();

volatile boolean teensySleep=false;

int wakeUPpin=15;

uint32_t Serialbaud = 4800;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {
    '1','2','3','A'                                                                        }
  ,
  {
    '4','5','6','B'                                                                        }
  ,
  {
    '7','8','9','C'                                                                        }
  ,
  {
    '*','0','#','D'                                                                        }
};
byte colPins[COLS] = {
  19, 20, 21, 22}; //connect to the row pinouts of the keypad
byte rowPins[ROWS] = {
  15, 16, 17, 18}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char key;
String keyStrokes="";
int numStrokes=0;
KeyState keyState;
static byte kpadState;

void keypadEvent(KeypadEvent key) {
  // in here when in alpha mode.
  kpadState = keypad.getState( );
  if (kpadState == RELEASED){
    Serial.println(key);
    switch(key){
    case'A':
      Serial.println("Function A called... putting Teensy to sleep");
      teensySleep=true;
      break;
    }
  }
}

void callbackhandler() {
  teensySleep= false;
  Serial.println("Change on pin 15, disabling Teensy sleep");
}


void setup()
{ 
  //delay(3000);//Give yourself time to open up the serial monitor  

  pinMode(wakeUPpin, INPUT_PULLUP); //Setup wakeup pin for Teensy
  attachInterrupt(wakeUPpin, callbackhandler, CHANGE);

  Serial.begin(Serialbaud);  //Begin serial communication with Serial Monitor
  Serial.println("Serial monitor operational");

  keypad.addEventListener(keypadEvent); //Add event listener for keypad strokes

  Serial.println("Beginning main loop");

}

void loop()
{
  if(teensySleep){
    Serial.println("Putting Teensy to sleep");
    LP.Sleep(); 
  }
  else{
    key= keypad.getKey();
  }

}

SOLVED:

The following code worked!

Code:
#include <Keypad.h>
#include <LowPower_Teensy3.h>

TEENSY3_LP LP = TEENSY3_LP();

uint32_t Serialbaud = 4800;

int greenLED1=29;

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns

char keys[ROWS][COLS] = {
  {
    '1','2','3','A'                                                                            }
  ,
  {
    '4','5','6','B'                                                                            }
  ,
  {
    '7','8','9','C'                                                                            }
  ,
  {
    '*','0','#','D'                                                                            }
};

byte colPins[COLS] = {
  19, 20, 21, 22}; //connect to the row pinouts of the keypad
byte rowPins[ROWS] = {
  15, 16, 17, 18}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char key;
String keyStrokes="";
int numStrokes=0;
KeyState keyState;
static byte kpadState;

void keypadEvent(KeypadEvent key) {
  // in here when in alpha mode.
  kpadState = keypad.getState( );
  if (kpadState == RELEASED){
    Serial.println(key);
    switch(key){
    case'A':
      Serial.println("Function A called... putting Teensy to sleep");
      prepSleepKeys();
      digitalWrite(greenLED1, LOW);
      delay(50);
      Serial.end();
      LP.Sleep();
      keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
      keypad.addEventListener(keypadEvent); //Add event listener for keypad strokes
      
      break;
    default:
      Serial.println(key);
      break;
    }
  }
}

void prepSleepKeys(){
  for(int r=0; r<ROWS; r++){ //Configure row pins
    pinMode(rowPins[r],INPUT_PULLUP); //Pull row pin high (internal pullup)
    attachInterrupt(rowPins[r], callbackhandler, CHANGE); //Add Interrupt on row pin
  }
  for (int c=0; c<COLS; c++){
    pinMode(colPins[c], OUTPUT); //Connect columns to ground
    digitalWrite(colPins[c], LOW);
  }

  delay(100);

  for(int r=0; r<ROWS; r++){ //Output state of Row pins to serial monitor
    if(digitalRead(rowPins[r])){
      Serial.println("Row pin " + String(rowPins[r]) + " is HIGH");
    }
    else{
      Serial.println("Row pin " + String(rowPins[r]) + " is LOW");
    }
  }

  for(int c=0; c<COLS; c++){ //Output state of Col pins to serial monitor
    if(digitalRead(colPins[c])){
      Serial.println("Col pin " + String(colPins[c]) + " is HIGH");
    }
    else{
      Serial.println("Col pin " + String(colPins[c]) + " is LOW");
    }
  } 

}

void callbackhandler() {
  Serial.println("Change on a row pin! Teensy now awake!");
  digitalWrite(greenLED1, HIGH);
  
}

void setup() {

  pinMode(greenLED1,OUTPUT); //Define green LED pin
  digitalWrite(greenLED1, OUTPUT); //Turn on green LED
  keypad.addEventListener(keypadEvent); //Add event listener for keypad strokes
  delay(5000);

  Serial.begin(Serialbaud);  //Begin serial communication with Serial Monitor
  Serial.println("Serial monitor operational");
  Serial.println("Beginning main loop");
}

void loop() {
  key= keypad.getKey();
}
 
Last edited:
THe trouble is that the Keypad library when running would be scanning the keypad, IE putting the output pins on and seeing what's on the inputs. When in sleep you will lose that even to the point where the output pins are deactivated (But I believe in sleep they are still powered).

So at a minimum you would need to put an interupt on the 4 cols pins, and pull up the 4 row output pins just before sleep so that you can see any buttons being pressed on the cols, then you can resume your keypad scanning.
 
Hello all,

I'm having trouble figuring out a way to wake from sleep mode using my 4x4 keypad. I'm trying to make it wake up when pin 15 changes

I'm using the Keypad.h library, and the LowPower_Teensy3 library.

I think the Keypad library is killing your attachInterrupt on pin 15, also it doesn't look like you mapped all the keypad buttons to the teensy pins?

edit.. I see now how the pin mapping works i was wrong about that... hehe

But anyway, try this:

Code:
#include <Keypad.h>
#include <LowPower_Teensy3.h>


TEENSY3_LP LP = TEENSY3_LP();


volatile boolean teensySleep=false;


int wakeUPpin=15;


uint32_t Serialbaud = 4800;


const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  { '1','2','3','A' } ,
  { '4','5','6','B' } ,
  { '7','8','9','C' } ,
  { '*','0','#','D' }
};
byte colPins[COLS] = {
  19, 20, 21, 22}; //connect to the row pinouts of the keypad
byte rowPins[ROWS] = {
  15, 16, 17, 18}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char key;
String keyStrokes="";
int numStrokes=0;
KeyState keyState;
static byte kpadState;


void keypadEvent(KeypadEvent key) {
  // in here when in alpha mode.
  kpadState = keypad.getState( );
  if (kpadState == RELEASED) {
    Serial.println(key);
    switch(key){
    case 'A':
      Serial.println("Function A called... putting Teensy to sleep");
      delay(5);
      teensySleep=true;
      break;
    }
  }
}


void callbackhandler() {
  teensySleep= false;
  Serial.println("Change on pin 15, disabling Teensy sleep");
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
}




void setup() { 
  pinMode(LED_BUILTIN, OUTPUT);
  while(!Serial);
  //delay(3000);//Give yourself time to open up the serial monitor  
  Serial.begin(Serialbaud);  //Begin serial communication with Serial Monitor
  Serial.println("Serial monitor operational");
  keypad.addEventListener(keypadEvent); //Add event listener for keypad strokes
  Serial.println("Beginning main loop");
}


void loop() {
  if(teensySleep) {
    Serial.println("Putting Teensy to sleep");
    pinMode(wakeUPpin, INPUT_PULLUP); //Setup wakeup pin for Teensy
    attachInterrupt(wakeUPpin, callbackhandler, CHANGE);
    delay(10);
    LP.Sleep(); 
  }
  else{
    key= keypad.getKey();
  }
}

Also sleep will disable the USB while sleeping so you have to close and reopen the serial monitor when you wake up!
 
Last edited:
Status
Not open for further replies.
Back
Top