@@ -26,7 +26,7 @@ Layout | |||
#include <Row_ShiftRegisters.h> | |||
// =============== CONFIGURATION =============== | |||
const unsigned int RowBase::DELAY_MICROSECONDS = 0; //500 | |||
const unsigned int RowDelay::DELAY_MICROSECONDS = 0; //500 | |||
const bool RowScanner_PinsArray::ACTIVE_HIGH = 0; //left matrix is active low | |||
const uint8_t RowScanner_SPIShiftRegisters::SHIFT_LOAD = 10; | |||
@@ -1,40 +1,4 @@ | |||
#include "RowBase.h" | |||
/* 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 scan and send would unnecessarily delay send). | |||
DELAY_MICROSECONDS explained | |||
---------------------------- | |||
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 RowBase::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. | |||
The largest allowable DELAY_MICROSECONDS is 65535 (.065535 seconds). | |||
Polling I2C may slow the scan rate enough so that no additional delay is needed: | |||
const unsigned int RowBase::DELAY_MICROSECONDS = 0; | |||
*/ | |||
void RowBase::wait() | |||
{ | |||
delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches | |||
} | |||
/* | |||
pressRelease() calls key's press() or release() function if it was pressed or released. | |||
Both parameters are bitwise. |
@@ -10,14 +10,10 @@ | |||
class RowBase | |||
{ | |||
private: | |||
static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing | |||
Key *const *const ptrsKeys; //array of Key pointers | |||
virtual void keyWasPressed(); | |||
protected: | |||
read_pins_t debounced; //bitwise, 1 means pressed, 0 means released | |||
void wait(); | |||
void pressRelease(const read_pins_mask_t rowEnd, const read_pins_t debouncedChanged); | |||
public: | |||
RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { } |
@@ -0,0 +1,7 @@ | |||
#include "RowDelay.h" | |||
void RowDelay::delay() | |||
{ | |||
delayMicroseconds(DELAY_MICROSECONDS); | |||
} | |||
@@ -0,0 +1,45 @@ | |||
#ifndef ROWDELAY_H | |||
#define ROWDELAY_H | |||
#include <Arduino.h> | |||
#include <inttypes.h> | |||
/* RowDelay() delay's scan to give switches time to debounce. | |||
For fastest response time, RowDelay() should be placed before scan() or after pressRelease() | |||
(RowDelay() between scan and send would unnecessarily delay send). | |||
DELAY_MICROSECONDS explained | |||
---------------------------- | |||
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 RowDelay::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. | |||
The largest allowable DELAY_MICROSECONDS is 65535 (.065535 seconds). | |||
Polling I2C may slow the scan rate enough so that no additional delay is needed: | |||
const unsigned int RowDelay::DELAY_MICROSECONDS = 0; | |||
DELAY_MICROSECONDS is static so multiple row types can share it. | |||
For example, primary and secondary matrices would share the same DELAY_MICROSECONDS. | |||
*/ | |||
class RowDelay | |||
{ | |||
private: | |||
static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing | |||
public: | |||
void delay(); | |||
}; | |||
#endif |
@@ -7,7 +7,7 @@ void Row_IOE::process() | |||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | |||
read_pins_t debouncedChanged; //1 means debounced changed | |||
wait(); | |||
rowDelay.delay(); | |||
rowState = scanner.scan(rowEnd); | |||
debouncedChanged = debouncer.debounce(rowState, debounced); | |||
pressRelease(rowEnd, debouncedChanged); |
@@ -2,6 +2,7 @@ | |||
#define ROWIOE_H | |||
#include <RowBase.h> | |||
#include <RowDelay.h> | |||
#include <RowScanner_PinsBitwise.h> | |||
#include <Debouncer_4Samples.h> | |||
@@ -34,6 +35,7 @@ Number of pins in colPort0 should equal number of keys in ptrsKeys_0[] array. | |||
class Row_IOE : public RowBase | |||
{ | |||
private: | |||
RowDelay rowDelay; | |||
RowScanner_PinsBitwise scanner; | |||
Debouncer_4Samples debouncer; | |||
public: |
@@ -7,7 +7,7 @@ void Row_ShiftRegisters::process() | |||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | |||
read_pins_t debouncedChanged; //1 means debounced changed | |||
wait(); | |||
rowDelay.delay(); | |||
rowState = scanner.scan(rowEnd); | |||
debouncedChanged = debouncer.debounce(rowState, debounced); | |||
pressRelease(rowEnd, debouncedChanged); |
@@ -2,6 +2,7 @@ | |||
#define ROW_SHIFTREGISTERS_H | |||
#include <RowBase.h> | |||
#include <RowDelay.h> | |||
#include <RowScanner_SPIShiftRegisters.h> | |||
#include <Debouncer_4Samples.h> | |||
//#include <Debouncer_Not.h> | |||
@@ -27,6 +28,7 @@ Number of pins in colPort0 should equal number of keys in ptrsKeys_0[] array. | |||
class Row_ShiftRegisters : public RowBase | |||
{ | |||
private: | |||
RowDelay rowDelay; | |||
RowScanner_SPIShiftRegisters scanner; | |||
Debouncer_4Samples debouncer; | |||
//Debouncer_Not debouncer; //tested |
@@ -10,7 +10,7 @@ void Row_uC::process() | |||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | |||
read_pins_t debouncedChanged; //1 means debounced changed | |||
wait(); | |||
rowDelay.delay(); | |||
rowState = scanner.scan(rowEnd); | |||
debouncedChanged = debouncer.debounce(rowState, debounced); | |||
pressRelease(rowEnd, debouncedChanged); |
@@ -2,6 +2,7 @@ | |||
#define ROW_H | |||
#include <RowBase.h> | |||
#include <RowDelay.h> | |||
#include <RowScanner_PinsArray.h> | |||
#include <Debouncer_4Samples.h> | |||
@@ -29,6 +30,7 @@ Number of colPins should equal number of keys in ptrsKeys_0[] array. | |||
class Row_uC : public RowBase | |||
{ | |||
private: | |||
RowDelay rowDelay; | |||
RowScanner_PinsArray scanner; | |||
Debouncer_4Samples debouncer; | |||
public: |