diff --git a/src/Row.cpp b/src/Row.cpp index e677111..8a8b82c 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -30,31 +30,6 @@ need a larger SAMPLE_COUNT for reliability. Larger SAMPLE_COUNTs are more reliable but consume more memory, where SAMPLE_COUNT*ROW_COUNT = bytes of memory consumed by 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 Parameter rowState is bitwise, 1 means pressed, 0 means released. diff --git a/src/Row.h b/src/Row.h index 5c6172c..5bfaefa 100644 --- a/src/Row.h +++ b/src/Row.h @@ -33,7 +33,6 @@ Number of ColPort::colPins should equal number of keys in Row::ptrsKeys array class Row : public RowBase { 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 samplesIndex; //samples[] current write index virtual uint8_t debounce(const uint8_t rowState); diff --git a/src/RowBase.cpp b/src/RowBase.cpp index ccdeab0..a2b26dc 100644 --- a/src/RowBase.cpp +++ b/src/RowBase.cpp @@ -9,12 +9,44 @@ void RowBase::process(const bool activeHigh) uint16_t rowEnd; //1 bit marks positioned after last key of row uint8_t debouncedChanged; //1 means debounced changed + wait(); scan(activeHigh); //save column-port-pin values to portState rowState = getRowState(rowEnd, activeHigh); debouncedChanged = debounce(rowState); 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() { delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches diff --git a/src/RowBase.h b/src/RowBase.h index 50bbcbe..98cc4fe 100644 --- a/src/RowBase.h +++ b/src/RowBase.h @@ -11,6 +11,7 @@ class RowBase { private: + static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing Key *const *const ptrsKeys; //array of Key pointers RowPort &refRowPort; //this row's IC port @@ -19,6 +20,7 @@ class RowBase ColPort *const *const ptrsColPorts; //array of column ports const uint8_t colPortCount; + void wait(); void scan(const bool activeHigh); uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh); virtual uint8_t debounce(const uint8_t rowState)=0;