Jump to content
Sign in to follow this  
StefanWxx

How to wake up on keypad press ? [IR-Remote Project]

Recommended Posts

Hello,
I'm still working on my Project -> C2RC -> Calculator2Remote Conversion 
The circuit and the IR codes now work after I adjusted the pulse timings. 
But now I wonder how I can put the MSP430G2553  in sleep mode..
 
I've followed the suggestion of energia
 
But I must be doing something fundamentally wrong, because I think that would be too easy:
 
/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
*/
#include <Keypad.h>
#include <IRremote.h>


const byte ROWS = 6; //four rows
const byte COLS = 5; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'0','1','2','3','w'},
  {'b1','4','5','6','.'},
  {'7','8','9','-','C'},
  {'%','m','b2','+','R'},
  {'=','M','/','*','b3'},
  {'b4','O','o','b5','b6'}
};
byte rowPins[ROWS] = {P1_3, P1_4, P2_1, P1_5, P2_0, P2_2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {P1_0, P2_4, P2_5, P1_6, P1_7}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
IRsend irsend;

void setup(){
  Serial.begin(9600);
  
  
  
  //LPM
  disableWatchDog();
  attachInterrupt(P1_3, awake, FALLING);    //row Pins = INPUT_PULLUP
  attachInterrupt(P1_4, awake, FALLING);
  attachInterrupt(P2_1, awake, FALLING);
  attachInterrupt(P1_5, awake, FALLING);
  attachInterrupt(P2_0, awake, FALLING);
  attachInterrupt(P2_2, awake, FALLING);
}
 
void loop() {
 __bis_status_register(LPM4_bits + GIE);
  /* Code after this will never be reached */
} 
  
void awake(){
  char customKey = customKeypad.getKey();
  
  switch (customKey) {
    case 'o':    
      irsend.sendSamsung(0xe0e040bf, 32);
      
      break;
    
    default:
      //irsend.sendSamsung(0xe0e040bf, 32);
    
      break;
      }
  }

The IR-LED is always OFF.

Where is my mistake?

 

Share this post


Link to post
Share on other sites

See what the IRsend library is doing. Disabling the watchdog might be what's throwing you off here. Try commenting that out? Arduino libs are never written for the paradigm of an MCU that can casually shut off its clocks so they require careful analysis to make it work.

Share this post


Link to post
Share on other sites

thank you for the advice

 

 

my paradigm leads to that I can not read the correct keys:

#include <Keypad.h>
#include <IRremote.h>


const byte ROWS = 6; //four rows
const byte COLS = 5; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = { //b1-b6 = blank ones, not connected
  {'0','1','2','3','w'},
  {'b1','4','5','6','.'},
  {'7','8','9','-','C'},
  {'%','m','b2','+','R'},
  {'=','M','/','*','b3'},
  {'b4','O','o','b5','b6'}
};
byte rowPins[ROWS] = {P1_3, P1_4, P2_1, P1_5, P2_0, P2_2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {P1_0, P2_4, P2_5, P1_6, P1_7}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
//Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
//IRsend irsend;

void setup() 
{
  Serial.begin(9600);
  delay(5000);
  Serial.println("..running!");
   Serial.println();
  
  
  
  
  
  pinsetup();
}

void pinsetup(){  //.. so that the pins are interrupt capable
  disableWatchDog(); // disable timer keeper to use less power
  pinMode(P1_3, INPUT_PULLUP);   
  pinMode(P1_4, INPUT_PULLUP); 
  pinMode(P2_1, INPUT_PULLUP); 
  pinMode(P1_5, INPUT_PULLUP); 
  pinMode(P2_0, INPUT_PULLUP); 
  pinMode(P2_2, INPUT_PULLUP); 


  pinMode(P1_0,OUTPUT);
  pinMode(P2_4,OUTPUT);
  pinMode(P2_5,OUTPUT);
  pinMode(P1_6,OUTPUT);
  pinMode(P1_7,OUTPUT);
  
  digitalWrite(P1_0, LOW);
  digitalWrite(P2_4, LOW);
  digitalWrite(P2_5, LOW);
  digitalWrite(P1_6, LOW);
  digitalWrite(P1_7, LOW);
  
 
  attachInterrupt(P1_3, awake, FALLING);    //row Pins = INPUT_PULLUP
  attachInterrupt(P1_4, awake, FALLING);
  attachInterrupt(P2_1, awake, FALLING);
  attachInterrupt(P1_5, awake, FALLING);
  attachInterrupt(P2_0, awake, FALLING);
  attachInterrupt(P2_2, awake, FALLING);
}

void loop() 
{
  Serial.println("preLPM4"); 
  //__bis_status_register(LPM4_bits + GIE);
  LPM4;  // start in ultra low power mode, all work is done in the ISR routines
  Serial.println("postLPM4"); 
}

void awake(void)
{
  detachInterrupt(P1_3);
  detachInterrupt(P1_4);
  detachInterrupt(P2_1);
  detachInterrupt(P1_5);
  detachInterrupt(P2_0);
  detachInterrupt(P2_2);
  
  enableWatchDog();

  delay(100);
  Serial.println();
  Serial.println("Awake!");
  
  //delay(500);
  Keypad keypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );
  char key = keypad.getKey();
  Serial.println(key);
  delay(200);
  
  pinsetup();
  
}

Share this post


Link to post
Share on other sites

The keypad is a switch matrix.

ArduinoMuxInput.jpg

 

Yeah thats an arduino not an MSP430, but the circuit still works the same way. Label the top row as buttons 1 to 3, second to 4 to 6 etc. The Keypad library when you call getKey will turn pin 5 on to power the top row of buttons, it will then read pins 7, 8 and 9 to see if button 1, 2 or 3 is being pressed, then it will turn pin 5 off and pin 4 on, then read pins 7, 8 and 9 to see if buttons 4, 5 or 6 are being pressed, then it turns pin 4 off and pin 3 off to check buttons 7, 8 and 9 and finally 3 off and 2 on to check buttons 10, 11 and 12. When the keypad is not in use then none of the buttons will be powered and so there will be no interrupt signal to the MSP430.

 

I've just checked the source for the Keypad library, it uses the row pins as input pullups and the column pins as outputs. If you manually set all the column pins high before entering sleep mode then you should be able to pick up the falling edge interrupts on the row pins to wake the MSP430 (at which point you should manually set all the column pins low again before letting the library take over)

Share this post


Link to post
Share on other sites

I think when you go to sleep mode all outputs go tri-state, therefore there is no ground connected to the switches and when you push a button nothing happens. Try connecting an external pulldown resistor to the output-pins, 10k should work.

Share this post


Link to post
Share on other sites

@@Thorvard,@@SixSixSevenSeven

 

in fact, I can now read the correct keys with the code, after I have added 'HIGH' to the Row Ports, before the keypad library takes over.

  #include <Keypad.h>
#include <IRremote.h>


const byte ROWS = 6; //four rows
const byte COLS = 5; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = { //b1-b6 = blank ones, not connected
  {'0','1','2','3','w'},
  {'b1','4','5','6','.'},
  {'7','8','9','-','C'},
  {'%','m','b2','+','R'},
  {'=','M','/','*','b3'},
  {'b4','O','o','b5','b6'}
};
byte rowPins[ROWS] = {P1_3, P1_4, P2_1, P1_5, P2_0, P2_2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {P1_0, P2_4, P2_5, P1_6, P1_7}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
//Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
//IRsend irsend;

void setup() 
{
  Serial.begin(9600);
  delay(5000);
  Serial.println("..running!");
   Serial.println();
  
  
  
  
  
  pinsetup();
}

void pinsetup(){  //.. so that the pins are interrupt capable
  disableWatchDog(); // disable timer keeper to use less power
  pinMode(P1_3, INPUT_PULLUP);   
  pinMode(P1_4, INPUT_PULLUP); 
  pinMode(P2_1, INPUT_PULLUP); 
  pinMode(P1_5, INPUT_PULLUP); 
  pinMode(P2_0, INPUT_PULLUP); 
  pinMode(P2_2, INPUT_PULLUP); 


  pinMode(P1_0,OUTPUT);
  pinMode(P2_4,OUTPUT);
  pinMode(P2_5,OUTPUT);
  pinMode(P1_6,OUTPUT);
  pinMode(P1_7,OUTPUT);
  
  digitalWrite(P1_0, LOW);
  digitalWrite(P2_4, LOW);
  digitalWrite(P2_5, LOW);
  digitalWrite(P1_6, LOW);
  digitalWrite(P1_7, LOW);
  
 
  attachInterrupt(P1_3, awake, FALLING);    //row Pins = INPUT_PULLUP
  attachInterrupt(P1_4, awake, FALLING);
  attachInterrupt(P2_1, awake, FALLING);
  attachInterrupt(P1_5, awake, FALLING);
  attachInterrupt(P2_0, awake, FALLING);
  attachInterrupt(P2_2, awake, FALLING);
}

void loop() 
{
  Serial.println("preLPM4"); 
  //__bis_status_register(LPM4_bits + GIE);
  LPM4;  // start in ultra low power mode, all work is done in the ISR routines
  Serial.println("postLPM4"); 
}

void awake(void)
{
  detachInterrupt(P1_3);
  detachInterrupt(P1_4);
  detachInterrupt(P2_1);
  detachInterrupt(P1_5);
  detachInterrupt(P2_0);
  detachInterrupt(P2_2);
  
  digitalWrite(P1_0, HIGH);
  digitalWrite(P2_4, HIGH);
  digitalWrite(P2_5, HIGH);
  digitalWrite(P1_6, HIGH);
  digitalWrite(P1_7, HIGH);
  
  enableWatchDog();

  delay(100);
  Serial.println();
  Serial.println("Awake!");
  
  //delay(500);
  Keypad keypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );
  char key = keypad.getKey();
  Serial.println(key);
  delay(200);
  
  pinsetup();
  
}

the first key stroke wakes up an the awake function is running, but after that he will not go back to sleep mode.

 

???

 

EDIT:

I had it last compiled on another PC (i used a different energia installation) 
The difference was in the WInterrupts.c file,
i forgot to add the line:
 
_BIC_SR_IRQ(LPM4_bits);
 
to the last 2 functions..
 
 
but now the output works as expected:
...running!

preLPM4

Awake!
5
postLPM4
preLPM4

Awake!
8
postLPM4
preLPM4

Awake!
9
postLPM4
preLPM4

Awake!
%
postLPM4
preLPM4

Awake!
/
postLPM4
preLPM4

Awake!
*
postLPM4
preLPM4

Awake!
/
postLPM4
preLPM4

Awake!
*
postLPM4
preLPM4

Awake!
-
postLPM4
preLPM4

Awake!
+
postLPM4
preLPM4

Awake!
O
postLPM4
preLPM4

Awake!
C
postLPM4
preLPM4

Awake!
R
postLPM4
preLPM4

Awake!
m
postLPM4
preLPM4

Awake!
M
postLPM4
preLPM4

Awake!
o
postLPM4
preLPM4

Awake!
4
postLPM4
preLPM4

Now i think its solved! Many thanks  :rolleyes:

Share this post


Link to post
Share on other sites

in your awake routine you have detached the interrupts, comment that out/delete it and your problem should be fixed

 

EDIT:

Scratch that, I missed you re-running pinsetup at the end of the interrupt handler.

 

Without having a keypad here in front of me (ones on its way actually \o/ ) I can't really test whats going on for myself.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...