Pages: 1 [2]   Go Down
Author Topic: Low power consumption (0.1 uA) but wake up on keypad press  (Read 5373 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 439
Posts: 23797
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Technically "wired AND", any input low makes the output low.
I did it that way because I was having trouble making PCINTs wake the part up from Power Down Sleep Mode.
Might have been a coding issue at the time, missing <interrupt.h> or something. Never got PCINTs to work until you & skyjumper helped me with them a year later for one of Aaron's cards.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

California, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It does not seem to be LED blinking issue (I am actually looking at the single byte sent to serial, communicating at 57600 baud)

It still does not work quite right for me, but there is quite a bit of difference between keypad and keypad2 libraries, keeping everything else in teh code the same. Using the Keypad, the first keypress always registers, but then 5-out-of-100 keypresses on the same key register; with Keypad2 library, after the first keypress that always seem to register, too, 85-out-of-100 keypresses on the same key register. With goToSleep() commented out, all the keypresses register, so it is not bad keyboard smiley  The above numbers came out of 500 keypresses... Just wanted to share before I take a look at the two keypad library codes.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code in my sketch which reconfigures the pins back to how they need to be for the keypad library, may need reworking if the other library does things differently. For the sleep, I set the columns low and the rows high, so we can detect a change (when a row connects to a column). Afterwards things have to go back to how the keypad library wants them. Notice how in keypad.cpp it initializes the columns differently:

Code:
void Keypad::initializePins() {
    // Configure column pin modes and states. Row pins get configured
    // in scanKeys(). See explanation there.
    // See http://arduino.cc/forum/index.php/topic,95027.0.html for an explanation
    // of why changing the column pins to INPUTs prevents inter-column shorts.
    for (byte C=0; C<sizeKpd.columns; C++) {
        pin_mode(columnPins[C],INPUT);
        pin_write(columnPins[C],HIGH);
    }
}

I was using output, he is using input.
Logged

California, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I GOT IT!!!!

In the main loop I added a 10 ms delay after waking up, and no more missed keypresses when using your Keypad 2 library. I'm happy.

Code:
   if (!key)
      {
       goToSleep ();
       delay(10);
       return;
      }

Using the Keypad 3.0 (and Nick, yes, thank you for the pointer above, I did miss the different cols setting, but fixing it did not change the code behavior), with 10 ms delay, it misses much fewer keypresses on wakeup, but it still misses quite a few, about 3-out-of-4.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So you are saying it is totally fixed? Provided you use the Keypad2 library?

Well that explains why it worked for me. (It's not my library I don't think, I can't remember where it came from).
Logged

Phillipsburg, NJ
Offline Offline
Full Member
***
Karma: 6
Posts: 174
Author: Matrix Keypad Library
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Nick & Everyone,

  I've been following this post with great interest. Of course I'm finding the low power stuff to be very interesting but equally as important I was discovering what impact my changes have made between the two versions of the library.

Nick:  You are using version 1.8 of the library (Keypad2) which had the original problem with shorted pins when pressing multiple keys. Since then I've implemented your suggestions so the latest version, 3.0, includes those fixes.

Zigmund:  Along the way I figured out that I could drastically improve the number of times the loop runs per second by restricting the number of calls to the library to once every 10 milliseconds (mS) by default. The default can be changed by setDebounceTime(1) which sets the debounce time to 1mS which is the minimum.  By reducing the debounce time it allows getKey() to be called more frequently.  I would love to hear how it affects the responsiveness when using version 3.0 of the library.  I may need to change my method of limiting.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You should be able to keep the keypad processing low by doing what the low-power stuff does. Set all columns low and all rows high-pullup. Then a quick test confirms whether or not a key is pressed. Then a longer loop could work out exactly which key.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 180
Posts: 8084
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sounds like the sleep code should be incorporated into a Keypad library.  A variant of keypad.getkey() could be used to sleep until a key is pressed.  It would probably be necessary to allow the depth of sleep to be adjusted.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The danger with that idea (nice though it is) is that to use the pin-change interrupts you need the interrupt handler. Then it could clash with things like software serial. Although in my code I used an "empty" ISR. I'm not sure what would happen if I omitted it entirely. The interrupt vector must go somewhere.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Judging by the generated code, if you don't put an interrupt handler in it generates a jump to 'bad_interrupt', which then jumps back to 0 (the reset interrupt vector). However in my testing, I don't actually seem to get a reset as a print in setup does not display again.
Logged

California, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I could drastically improve the number of times the loop runs per second by restricting the number of calls to the library to once every 10 milliseconds (mS) by default. The default can be changed by setDebounceTime(1) which sets the debounce time to 1mS which is the minimum.  By reducing the debounce time it allows getKey() to be called more frequently.  I would love to hear how it affects the responsiveness when using version 3.0 of the library.

Mark: with the debounce time set to 50 ms in 3.0 library, only 13 out of 100 keypresses get registered. Reducing the debounce time to 10 ms gets 56 of 100 keypresses, 5 ms - 96 of 100, and 1 ms - 96 out of 100 as well.
Logged

California, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Nick,

After running your sleep code successfully on Pro Mini and Nano boards, I endeavored into ATtiny-based solution (4313 in particular). The code won't compile, complaining about WDTCSR, PCIFR, PCIF0, ..., BODS, BODSE not declared. Do you know where are these declared, so I can try updating for ATtiny 4313?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 180
Posts: 8084
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Nick,

After running your sleep code successfully on Pro Mini and Nano boards, I endeavored into ATtiny-based solution (4313 in particular). The code won't compile, complaining about WDTCSR, PCIFR, PCIF0, ..., BODS, BODSE not declared. Do you know where are these declared, so I can try updating for ATtiny 4313?

AVR registers are defined in hardware/tools/avr/avr/include/avr/io.h

It has:
Code:
#elif defined (__AVR_ATtiny2313__)
#  include <avr/iotn2313.h>
I don't see anything specifically for the ATtiny4313.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

California, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks John!

The ATtiny4313 seems to be implemented in the most recent WinAVR (2010-01-10) - not the one that comes with Arduino, but the latest in SourceForge. io.h does contain

Code:
#elif defined (__AVR_ATtiny4313__)
#  include <avr/iotn4313.h>

and there is iotn3413.h The registers seem there, just some (vaguely straightforward) footwork needed to modify Nick's code and reference chip-appropriate registers.

Atmel has published app notes on migration from 2313 to 4313 here: http://www.atmel.com/Images/doc8283.pdf. From the first brief reading it seems straightforward, but there are a few things I don't completely understand, like brown-out register bits 0 and 1: the Atmel papers refer to them as BODSE and BODS, and AVR io file has them as BPDS and BPDSE. Typo or my superficial understanding?
« Last Edit: May 11, 2013, 01:36:26 pm by Zoran Djurisic » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After running your sleep code successfully on Pro Mini and Nano boards, I endeavored into ATtiny-based solution (4313 in particular). The code won't compile, complaining about WDTCSR, PCIFR, PCIF0, ..., BODS, BODSE not declared. Do you know where are these declared, so I can try updating for ATtiny 4313?

I haven't tried on that chip but generally the registers have the same names as are given in the datasheet (or the datasheet would be very confusing). You basically need to see what the original code does (eg. vis-a-vis BODS) by looking at the Atmega328 datasheet, and then see what bits in what register accomplish the same thing on the new processor.
Logged

Pages: 1 [2]   Go Up
Jump to: