diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 209d0b5..8670255 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -7,6 +7,25 @@ keybrd version 1.0.0 will be released when the public API is stable. ## [Unreleased][unreleased] +## [0.3.2] - 2016-06-10 +### Changed +* Changed uC from scanning port arrays to scanning Arduino pins. + Thereby added support for Arduino boards, Teensy 3, and Teensy LC micro controllers. +* Changed IOE from scanning port arrays to scanning single ports. +* Moved scanner and debouncer into their own classes. + +### Added +* Row_uC +* Row_IOE +* RowScannerInterface +* RowScanner_PinsArray +* RowScanner_PinsBitwise +* DebouncerInterface +* Debouncer_4Samples + +### Removed +* Port arrays + ## [0.3.1] - 2016-06-02 ### Added * RowBase class diff --git a/doc/keybrd_library_developer_guide.md b/doc/keybrd_library_developer_guide.md index 9991e63..b674dcf 100644 --- a/doc/keybrd_library_developer_guide.md +++ b/doc/keybrd_library_developer_guide.md @@ -8,8 +8,8 @@ The most common reason for new classes are: ## Who this guide is for This guide is for the maintainers and developers of the keybrd library and it's extensions. -It is assumed the reader is familiar with C++ language including pointers, objects, classes, static class variables, aggregation, inheritance, polymorphism, and enum. -Some classes use bit manipulation. +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 @@ -17,9 +17,14 @@ Keybrd library class inheritance diagram ``` Matrix - RowBase - | - Row + RowBase + / \ + Row_uC Row_IOE + + RowScannerInterface + / \ + RowScanner_PinsArray RowScanner_PinsBitwise + IOExpanderPort @@ -36,8 +41,13 @@ Keybrd library class inheritance diagram LED_AVR LED_MCP23018 LED_PCA9655E (one LED class for each type of IC) + DebouncerInterface + | + Debouncer_4Samples + + LayerStateInterface - | + | LayerState @@ -66,32 +76,70 @@ Keybrd library class inheritance diagram ## Dependency diagrams -single-layer dependency diagram with LEDs +Example single-layer dependency diagram with LEDs ``` - matrix[1..*] - | - row[1..*]_____________________________ - | \ \ \ - rowPort[1] rowPin[1] colPort[1] keys[1] - | | - colPins[1..*] code[1..*] - | - LED[1] + matrix[1..*] + | + ___ row_uC[1..*] ________ + / \ \ + RowScanner_PinsArray debouncer keys[1..*] + / \ | + strobePin[1] readPins[1..*] code[1..*] + | + LED[1] ``` -multi-layer dependency diagram with LEDs and I/O Expander +Example single-layer dependency diagram I/O Expander ``` - matrix[1..*] - | layerStates[1..*] - row[1..*]_________________________________________/__ | \ - | \ \ \ / \ | \ - rowPort[1] rowPin[1] colPort[1] keys[1] / code_layer[1..*] LED[0..*] - \ / \ | / / - \ / colPins[1..*] key[1..*] / - \ / | / - \ / code[1..*] / - \ / ______________________________________/ + ________ row_uC[1..*] _________ + / \ \ + RowScanner_PinsArray[1] debouncer[1] keys[1..*] + / \ | + strobePin[1] readPins[1..*] code[1..*] + + + ___ row_IOE[1..*] _________ + / \ \ + RowScanner_PinsBitwise[1] debouncer[1] keys[1..*] + / | \ | + rowPort[1] rowPin[1] colPort[1] code[1..*] + \ / \ + \ / colPins[1..*] + \ / + IOExpanderPort[0..*] + +``` + +Example multi-layer dependency diagram with layer LEDs +``` + layerStates[1..*] + ________ row_uC[1..*] _____________________/__ | \ + / \ \ / \ | \ + RowScanner_PinsArray[1] debouncer[1] keys[1..*] / code_layer[1..*] LED[0..*] + / \ | / + strobePin[1] readPins[1..*] code[1..*] + +``` + +Example multi-layer dependency diagram with I/O Expander +``` + + ________ row_uC[1..*] ________________________ _______layerStates[1..*] + / \ \ \ / | + RowScanner_PinsArray[1] debouncer[1] keys[1..*] code_layer[1..*] | + / \ | ________________________| + strobePin[1] readPins[1..*] code[1..*] | + | + | + ___ row_IOE[1..*] _________ __________| + / \ \ / | + RowScanner_PinsBitwise[1] debouncer[1] keys[1..*] code_layer[1..*] | + / | \ | _____________________| + rowPort[1] rowPin[1] colPort[1] code[1..*] + \ / \ + \ / colPins[1..*] + \ / IOExpanderPort[0..*] ``` @@ -162,29 +210,25 @@ Following the style guide makes it easier for the next programmer to understand ## Trace of keybrd scan Arduino does not have a debugger. So here is the next best thing; a list of functions in the order that they are called. +The trace is of a single-layer keybrd scan (no LEDs and no I/O expander). Refer to it like a table of contents while reading the keybrd library. ``` - Matrix::scan() for each row - Row::process() - Row::wait() - Row::scan() - RowPort_*::setActivePin*() strobe row on - for each col port - ColPort_*::read() read col port - RowPort_*::setActivePin*() strobe row off - Row::getRowState() for each col port - for each connected col pin - if key is pressed + Matrix::scan() for each row + RowBase::process() + RowBase::wait() delay time for debounce + RowScanner_PinsArray::scan() strobe row on + for each readPin set rowState bit - Row::debounce() debounce - Row::pressRelease() for each key in row - if falling edge - Key_*::release() scanCode->release() - Code_*::release() Keyboard.release(scancode) - if rising edge - Key_*::press() scanCode->press() - Code_*::press() Keyboard.press(scancode) + strobe row off + Debouncer_4Samples::debounce() debounce + RowBase::pressRelease() for each key in row + if falling edge + Key_*::release() scanCode->release() + Code_*::release() Keyboard.release(scancode) + if rising edge + Key_*::press() scanCode->press() + Code_*::press() Keyboard.press(scancode) ``` ## The Arduino libraries diff --git a/doc/planned_features.md b/doc/planned_features.md index a4182e6..6377b9e 100644 --- a/doc/planned_features.md +++ b/doc/planned_features.md @@ -2,19 +2,19 @@ planned_features is a view of where the keybrd project is headed. Top priority ============ -Redesign elements of debouncer. +Add support for shift registers, for compact split keyboards up to 32 keys per matrix. Med priority ============ -Add support for Teensy LC micro controller - Add 16x16 matrix capability (currently limited to 8x8 matrices) Low priority ============ Add matrix-to-layout mapping array (to decouple matrix from layout) -Change tutorial sketches from teensy 2.0 and PCA9655E-D IOE to Teensy LC and MCP23018 IOE +Update tutorials: +* Currently tutorial sketches are obsolete and won't compile +* Change tutorial sketches from teensy 2.0 and PCA9655E-D IOE to Teensy LC and MCP23018 IOE Add more tutorials: * tutorial_5_LEDs.md diff --git a/src/RowBase.cpp b/src/RowBase.cpp index 0a345d0..45ac658 100644 --- a/src/RowBase.cpp +++ b/src/RowBase.cpp @@ -24,7 +24,7 @@ For fastest response time, wait() should be placed before scan() or after pressR 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; + 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. @@ -42,12 +42,7 @@ Avoid sampling the switch input at a rate synchronous to events in the environme 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 Row::DELAY_MICROSECONDS = 0; - -Slow-scan trick for debug messages that print too fast and not aligned, add this to sketch loop(): - delay(500); - Keyboard.println(F("")); -That way debug messages are printed at a managable rate, and each scan starts a new line. + const unsigned int RowBase::DELAY_MICROSECONDS = 0; */ void RowBase::wait() { diff --git a/src/RowBase.h b/src/RowBase.h index 63214a3..6afc4ba 100644 --- a/src/RowBase.h +++ b/src/RowBase.h @@ -5,9 +5,6 @@ #include /* RowBase is an abstract base class. - -Define and initilize DELAY_MICROSECONDS in sketch. - const unsigned int RowBase::DELAY_MICROSECONDS = 0; */ class RowBase { diff --git a/src/RowScannerInterface.h b/src/RowScannerInterface.h index ca45a0f..bb1adcb 100644 --- a/src/RowScannerInterface.h +++ b/src/RowScannerInterface.h @@ -1,11 +1,6 @@ #ifndef ROWSCANNERINTERFACE_H #define ROWSCANNERINTERFACE_H -/* RowScannerInterface is an interface class. -Sets rowEnd and returns rowState. -rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row. -rowEnd and rowMask are larger type than portMask so that they can not overflow. -*/ #include #include diff --git a/src/RowScanner_PinsBitwise.cpp b/src/RowScanner_PinsBitwise.cpp index 29bd381..42d0a7f 100644 --- a/src/RowScanner_PinsBitwise.cpp +++ b/src/RowScanner_PinsBitwise.cpp @@ -1,7 +1,7 @@ #include "RowScanner_PinsBitwise.h" /* Strobes the row and reads the columns. -Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. +Sets rowEnd and returns rowState. */ uint8_t RowScanner_PinsBitwise::scan(uint16_t& rowEnd) { @@ -16,13 +16,9 @@ uint8_t RowScanner_PinsBitwise::scan(uint16_t& rowEnd) } delayMicroseconds(3); //time to stablize voltage - //read all the port pins + //read the port pins refColPort.read(); -/* shows strobing pin 1 and 2, but realy stobing 0 and 1 todo -Keyboard.print(F(" strobePin=")); -Keyboard.print(strobePin); -Keyboard.print(F(", ")); -*/ + //strobe row off if (activeHigh) { diff --git a/src/Row_IOE.h b/src/Row_IOE.h index 7c856e9..3fc651a 100644 --- a/src/Row_IOE.h +++ b/src/Row_IOE.h @@ -5,14 +5,29 @@ #include #include -/* -Simlar to Row but using RowScanner_PinsBitwise. +/* Row_DH_IOE is a row connected to an Input/Output Expander. Configuration ------------- +Define and initilize DELAY_MICROSECONDS in sketch. Detailed how to is in RowBase.cpp. Instantiation ------------- +Example instantiation of a row: + const uint8_t IOExpanderPort::ADDR = 0x18; + + IOExpanderPort port1(1, 0); + RowPort_PCA9655E rowPort1(port1); + + IOExpanderPort port0(0, 0); + ColPort_PCA9655E colPort0(port0, 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 ); + + Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 }; + Row_IOE row_0(rowPort1, 1<<0, colPort0, ptrsKeys_0); + +Number of pins in colPort0 should equal number of keys in ptrsKeys_0[] array. + if a pin is missing, a key will be unresposive + if a Key pointer is missing, the keyboard will fail in an unprdictable way */ class Row_IOE : public RowBase { diff --git a/src/Row_uC.h b/src/Row_uC.h index 3af67be..bac33ac 100644 --- a/src/Row_uC.h +++ b/src/Row_uC.h @@ -5,13 +5,24 @@ #include #include -/* +/* Row_uC is a row connected to a micro controller. Configuration ------------- +Define and initilize DELAY_MICROSECONDS in sketch. Detailed how to is in RowBase.cpp. Instantiation ------------- - todo - see RowDH +Example instantiation of a row: + + const uint8_t colPins[] = {0,1,2,3,7,8}; + 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); + +Number of colPins should equal number of keys in ptrsKeys_0[] array. + if a colPin is missing, a key will be unresposive + if a Key pointer is missing, the keyboard will fail in an unprdictable way */ class Row_uC : public RowBase { diff --git a/tutorials/breadboard_keyboard_supplies.ods b/tutorials/breadboard_keyboard_supplies.ods index 1e5f209..95e1288 100644 Binary files a/tutorials/breadboard_keyboard_supplies.ods and b/tutorials/breadboard_keyboard_supplies.ods differ diff --git a/tutorials/tutorial_0_introduction.md b/tutorials/tutorial_0_introduction.md index 0d813c1..74f28cf 100644 --- a/tutorials/tutorial_0_introduction.md +++ b/tutorials/tutorial_0_introduction.md @@ -19,7 +19,7 @@ The tutorials assume the reader: * is new to Arduino, firmware, controllers, and the internal workings of keyboards -> All the tutorial sketches are tested on teensy 2.0 and PCA9655E-D I/O expander +> Most of the tutorial sketches are obsolete and will not compile. Will be updated soon. > The tutorial sketches will be changed to Teensy LC and MCP23018 I/O expander