Browse Source

add RowBase::wait()

tags/v0.5.0
wolfv6 8 years ago
parent
commit
d177dbfa97
4 changed files with 34 additions and 26 deletions
  1. 0
    25
      src/Row.cpp
  2. 0
    1
      src/Row.h
  3. 32
    0
      src/RowBase.cpp
  4. 2
    0
      src/RowBase.h

+ 0
- 25
src/Row.cpp View File

Larger SAMPLE_COUNTs are more reliable but consume more memory, where Larger SAMPLE_COUNTs are more reliable but consume more memory, where
SAMPLE_COUNT*ROW_COUNT = bytes of memory consumed by keyboard SAMPLE_COUNT*ROW_COUNT = bytes of memory consumed by keyboard
SAMPLE_COUNT = 4 is very reliable for a keyboard. SAMPLE_COUNT = 4 is very reliable for a keyboard.

Avoid sampling the switch input at a rate synchronous to events in the environment
that might create periodic EMI. For instance, 50 and 60 Hz.

A keyboard with a faster scan rate responds faster.
Follow these step to tune DELAY_MICROSECONDS for maximum scan rate for a given SAMPLE_COUNT:
Initialize DELAY_MICROSECONDS in your sketch:
const unsigned int Row::DELAY_MICROSECONDS = 1000;
Add this to the sketch's loop() function:
debug.print_microseconds_per_scan();
Compile and load the sketch into the microcontroller; microseconds_per_scan is printed every second.
Adjust the value of DELAY_MICROSECONDS and repeat until:
debug.print_microseconds_per_scan() <= DEBOUNCE_TIME / SAMPLE_COUNT

DEBOUNCE_TIME can be obtained from the switch's datasheet. Some switch bounce times are:
Cherry MX specifies 5msec bounce time http://www.cherrycorp.com/english/switches/key/mx.htm
hasu measured Cherry MX bounce times .3ms to 1.4ms http://geekhack.org/index.php?topic=42385.0
Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures/MJTP_6MM.pdf

Polling I2C may slow the scan rate enough so that no additional delay is needed:
const unsigned int Row::DELAY_MICROSECONDS = 0;

Slow-scan trick for debug messages that print too fast:
change DELAY_MICROSECONDS to a large number like 10000
That way debug messages are printed at a managable rate.
*/ */
/* debounce() function /* debounce() function
Parameter rowState is bitwise, 1 means pressed, 0 means released. Parameter rowState is bitwise, 1 means pressed, 0 means released.

+ 0
- 1
src/Row.h View File

class Row : public RowBase class Row : public RowBase
{ {
private: private:
static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing
uint8_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings uint8_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings
uint8_t samplesIndex; //samples[] current write index uint8_t samplesIndex; //samples[] current write index
virtual uint8_t debounce(const uint8_t rowState); virtual uint8_t debounce(const uint8_t rowState);

+ 32
- 0
src/RowBase.cpp View File

uint16_t rowEnd; //1 bit marks positioned after last key of row uint16_t rowEnd; //1 bit marks positioned after last key of row
uint8_t debouncedChanged; //1 means debounced changed uint8_t debouncedChanged; //1 means debounced changed
wait();
scan(activeHigh); //save column-port-pin values to portState scan(activeHigh); //save column-port-pin values to portState
rowState = getRowState(rowEnd, activeHigh); rowState = getRowState(rowEnd, activeHigh);
debouncedChanged = debounce(rowState); debouncedChanged = debounce(rowState);
pressRelease(rowEnd, debouncedChanged); pressRelease(rowEnd, debouncedChanged);
} }
/* wait() delay's scan to give switches time to debounce.
This version of wait() is very simple. More sophisticated versions can override this one.
For fastest response time, wait() should be placed before scan() or after pressRelease()
(waiting between strobe and send would unnecessarily delay send).
A keyboard with a faster scan rate responds faster.
Follow these step to tune DELAY_MICROSECONDS for maximum scan rate for a given SAMPLE_COUNT:
Initialize DELAY_MICROSECONDS in your sketch:
const unsigned int Row::DELAY_MICROSECONDS = 1000;
Add this to the sketch's loop() function:
debug.print_microseconds_per_scan();
Compile and load the sketch into the microcontroller; microseconds_per_scan is printed every second.
Adjust the value of DELAY_MICROSECONDS and repeat until:
debug.print_microseconds_per_scan() <= DEBOUNCE_TIME / SAMPLE_COUNT
DEBOUNCE_TIME can be obtained from the switch's datasheet. Some switch bounce times are:
Cherry MX specifies 5msec bounce time http://www.cherrycorp.com/english/switches/key/mx.htm
hasu measured Cherry MX bounce times .3ms to 1.4ms http://geekhack.org/index.php?topic=42385.0
Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures/MJTP_6MM.pdf
Avoid sampling the switch input at a rate synchronous to events in the environment
that might create periodic EMI. For instance, 50 and 60 Hz.
Polling I2C may slow the scan rate enough so that no additional delay is needed:
const unsigned int Row::DELAY_MICROSECONDS = 0;
Slow-scan trick for debug messages that print too fast:
change DELAY_MICROSECONDS to a large number like 10000
That way debug messages are printed at a managable rate.
*/
void RowBase::wait() void RowBase::wait()
{ {
delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches

+ 2
- 0
src/RowBase.h View File

class RowBase class RowBase
{ {
private: private:
static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing
Key *const *const ptrsKeys; //array of Key pointers Key *const *const ptrsKeys; //array of Key pointers
RowPort &refRowPort; //this row's IC port RowPort &refRowPort; //this row's IC port
ColPort *const *const ptrsColPorts; //array of column ports ColPort *const *const ptrsColPorts; //array of column ports
const uint8_t colPortCount; const uint8_t colPortCount;
void wait();
void scan(const bool activeHigh); void scan(const bool activeHigh);
uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh); uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh);
virtual uint8_t debounce(const uint8_t rowState)=0; virtual uint8_t debounce(const uint8_t rowState)=0;