@@ -11,20 +11,70 @@ This guide is for the maintainers and developers of the keybrd library and it's | |||
It is assumed the reader is familiar with C++ language including pointers, objects, classes, static class variables, composition, aggregation, inheritance, polymorphism, and enum. | |||
Debouncer and I/O expander use bit manipulation. | |||
## Class inheritance diagrams | |||
## Custom Row classes | |||
The keybrd library is flexible for designing custom Rows | |||
* RowBase functions can be overridden in a derived class | |||
* choice of Debouncers | |||
* choice of Scanners | |||
Keybrd library class inheritance diagram | |||
this example illustrates the custom Row classes from a fictional keybrd_Ext library | |||
the keybrd_Ext library library is for a split keyboard with a matrix on each hand | |||
the diagrams show the design decisions made by the developer | |||
Row_Ext overrides RowBase::keyWasPressed() | |||
Row_Ext::keyWasPressed() is used to unstick sticky keys | |||
Row_Ext_uC scans the primary matrix | |||
Row_Ext_uC is a custom class composed of stock keybrd library classes | |||
Row_Ext_ShiftRegisters scans the secondary matrix | |||
Row_Ext_ShiftRegisters is a custom class composed of stock keybrd library classes | |||
Class inheritance diagram | |||
``` | |||
Matrix | |||
RowBase | |||
/ \ | |||
Row_uC Row_IOE | |||
RowBase | |||
| | |||
Row_Ext override RowBase::keyWasPressed() | |||
/ \ | |||
Row_Ext_uC Row_Ext_ShiftRegisters inherit Row_Ext::keyWasPressed() | |||
/home/wolfv/Documents/Arduino/keybrd_proj/keybrd/doc/keybrd_library_developer_guide.md | |||
RowScannerInterface | |||
/ \ | |||
RowScanner_PinsArray RowScanner_PinsBitwise | |||
RowScanner_PinsArray RowScanner_SPIShiftRegisters | |||
``` | |||
Dependency diagram | |||
``` | |||
________ Row_Ext_uC[1] _______________ | |||
/ \ \ | |||
RowScanner_PinsArray[1] Debouncer_Samples[1] Key[1..*] | |||
/ \ | | |||
strobePin[1] readPins[1..*] Code[1..*] | |||
_____ Row_Ext_ShiftRegisters[1] _____________ | |||
/ \ \ | |||
RowScanner_SPIShiftRegisters[1] Debouncer_Samples[1] Key[1..*] | |||
/ \ | | |||
strobePin[1] ROW_END[1] Code[1..*] | |||
``` | |||
## Class inheritance diagrams | |||
Keybrd library class inheritance diagram | |||
``` | |||
RowBase | |||
/ | \ | |||
Row_uC Row_ShiftRegisters Row_IOE | |||
RowScannerInterface | |||
/ \ \ | |||
RowScanner_PinsArray RowScanner_PinsBitwise RowScanner_SPIShiftRegisters | |||
IOExpanderPort | |||
@@ -122,6 +172,12 @@ Example multi-layer dependency diagram with layer LEDs | |||
``` | |||
Example multi-layer dependency diagram with shift registers | |||
``` | |||
Row_ShiftRegisters | |||
``` | |||
Example multi-layer dependency diagram with I/O Expander | |||
``` | |||
@@ -1,9 +1,9 @@ | |||
/* keybrd_shift_reg.ino | |||
tested on Teensy LC and daisy chained 74HC165 shift registers | |||
Tested on Teensy LC and daisy chained 74HC165 shift registers | |||
the keyboard hardware for this sketch has 4 shift registers, | |||
with every 4th input pins connected to a pull-down resistor and matrix column. | |||
unused input pins are not grounded, so add this line to RowScanner_SPIShiftRegisters::scan(): | |||
The keyboard hardware for this sketch has 4 shift registers, | |||
with every 4th input pin connected to a pull-down resistor and matrix column, also the 31st key. | |||
Unused input pins are not grounded, so add this line to RowScanner_SPIShiftRegisters::scan(): | |||
//clear unpowered pins (for testing on breadboard) | |||
rowState &= 0b01010001000100010001000100010001; | |||
@@ -5,9 +5,9 @@ process() scans the row and calls any newly pressed or released keys. | |||
void RowBase::process() | |||
{ | |||
//these variables are all bitwise, one bit per key | |||
read_pins_t rowState; //1 means pressed, 0 means released | |||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | |||
read_pins_t debouncedChanged; //1 means debounced changed | |||
read_pins_t rowState; //1 means pressed, 0 means released | |||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | |||
read_pins_t debouncedChanged; //1 means debounced changed | |||
wait(); | |||
rowState = scan(rowEnd); | |||
@@ -19,7 +19,7 @@ void RowBase::process() | |||
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). | |||
(waiting between scan and send would unnecessarily delay send). | |||
DELAY_MICROSECONDS explained | |||
---------------------------- |
@@ -11,7 +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 | |||
Key *const *const ptrsKeys; //array of Key pointers | |||
virtual void keyWasPressed(); | |||
protected: |
@@ -36,8 +36,8 @@ read_pins_t RowScanner_SPIShiftRegisters::scan(read_pins_mask_t& rowEnd) | |||
rowEnd = ROW_END; | |||
//clear unpowered pins (for testing bb) todo | |||
rowState &= 0b01010001000100010001000100010001; //also 31st key | |||
//for testing breadboard, clear unpowered pins | |||
rowState &= 0b01010001000100010001000100010001; //todo | |||
return rowState; | |||
} |
@@ -20,7 +20,7 @@ Example instantiation of a row: | |||
const uint8_t COL_PIN_COUNT = sizeof(colPins)/sizeof(*colPins); | |||
Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 }; | |||
Row_DH_uC row_0(21, colPins, COL_PIN_COUNT, ptrsKeys_0); | |||
Row_uC row_0(21, colPins, COL_PIN_COUNT, ptrsKeys_0); | |||
Number of colPins should equal number of keys in ptrsKeys_0[] array. | |||
if a colPin is missing, a key will be unresposive |