Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 269
Posts: 17031
Available for Design & Build services
|
 |
« Reply #15 on: December 05, 2012, 07:45:51 pm » |
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
|
|
|
|
|
California, USA
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #16 on: December 05, 2012, 11:06:38 pm » |
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  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
Melbourne, Australia
Offline
Shannon Member
Karma: 225
Posts: 14081
Lua rocks!
|
 |
« Reply #17 on: December 05, 2012, 11:32:14 pm » |
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: 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
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #18 on: December 06, 2012, 02:55:52 am » |
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. 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
Melbourne, Australia
Offline
Shannon Member
Karma: 225
Posts: 14081
Lua rocks!
|
 |
« Reply #19 on: December 06, 2012, 06:21:54 am » |
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
Full Member
Karma: 6
Posts: 141
Author: Matrix Keypad Library
|
 |
« Reply #20 on: December 06, 2012, 10:38:14 pm » |
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
Melbourne, Australia
Offline
Shannon Member
Karma: 225
Posts: 14081
Lua rocks!
|
 |
« Reply #21 on: December 07, 2012, 12:16:01 am » |
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
Tesla Member
Karma: 108
Posts: 6592
|
 |
« Reply #22 on: December 07, 2012, 03:40:40 pm » |
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
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 225
Posts: 14081
Lua rocks!
|
 |
« Reply #23 on: December 07, 2012, 03:54:26 pm » |
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
Melbourne, Australia
Offline
Shannon Member
Karma: 225
Posts: 14081
Lua rocks!
|
 |
« Reply #24 on: December 07, 2012, 04:06:52 pm » |
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
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #25 on: December 08, 2012, 01:13:24 am » |
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
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #26 on: May 11, 2013, 01:16:11 am » |
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
Tesla Member
Karma: 108
Posts: 6592
|
 |
« Reply #27 on: May 11, 2013, 08:00:05 am » |
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: #elif defined (__AVR_ATtiny2313__) # include <avr/iotn2313.h>
I don't see anything specifically for the ATtiny4313.
|
|
|
|
|
Logged
|
|
|
|
|
California, USA
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #28 on: May 11, 2013, 01:20:56 pm » |
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 #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
Melbourne, Australia
Offline
Shannon Member
Karma: 225
Posts: 14081
Lua rocks!
|
 |
« Reply #29 on: May 12, 2013, 03:35:48 am » |
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
|
|
|
|
|
|