diff --git a/doc/keybrd_library_developer_guide.md b/doc/keybrd_library_developer_guide.md index 0c879f8..5e0d549 100644 --- a/doc/keybrd_library_developer_guide.md +++ b/doc/keybrd_library_developer_guide.md @@ -21,7 +21,7 @@ Keybrd library class inheritance diagram ___ ScannerInterface ___ / | \ - Scanner_uC Scanner_IOE Scanner_ShiftRegsPISO + Scanner_uC Scanner_IOE Scanner_ShiftRegsRead PortWriteInterface diff --git a/doc/keybrd_library_user_guide.md b/doc/keybrd_library_user_guide.md index e96c7c4..09a3d8d 100644 --- a/doc/keybrd_library_user_guide.md +++ b/doc/keybrd_library_user_guide.md @@ -122,7 +122,7 @@ The following instructions are for setting active state for a Scanner_uC class (Scanner_ShiftRegs74HC165 and Scanner_Port classes is similar). For active low: -* Orient diodes with cathode (banded end) towards the write pins (row) +* Orient diodes with cathode (banded end) towards the write pins (strobe) * Instantiate the scanner in the sketch with activeState LOW, like this: ``` Scanner_uC scanner(LOW, readPins, readPinCount); diff --git a/src/Row.h b/src/Row.h index 5d4c8d5..391ac48 100644 --- a/src/Row.h +++ b/src/Row.h @@ -10,7 +10,7 @@ #include "Debouncer_Not.h" /* -strobePin has one of two formats: +strobePin has one of two formats: todo * if strobe pin is on uC (strobe for Scanner_uC or Scanner_ShiftRegsRead), then strobePin is an Arduino pin number connected to this row. * if strobe pin is on I/O expander (strobe for Scanner_IOE), then strobePin is bit pattern, diff --git a/tutorials/keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino b/tutorials/keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino index e214950..974315e 100644 --- a/tutorials/keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino +++ b/tutorials/keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino @@ -2,7 +2,7 @@ This sketch: is firmware for a simple 2-layer keyboard - runs on the first two rows and columns of a breadboard keyboard + runs on the basic breadboard keyboard | Layout | **0** | **1** | |:------:|-------|-------| diff --git a/tutorials/keybrd_7a_mapping_single-layer/keybrd_7a_mapping_single-layer.ino b/tutorials/keybrd_7a_mapping_single-layer/keybrd_7a_mapping_single-layer.ino new file mode 100644 index 0000000..93ffa4a --- /dev/null +++ b/tutorials/keybrd_7a_mapping_single-layer/keybrd_7a_mapping_single-layer.ino @@ -0,0 +1,67 @@ +/* keybrd_7a_mapping_single-layer.ino + +This sketch: + is modified from keybrd_2_single.ino by swaping readPins numbers with Row-pin numbers + runs on basic breadboard keyboard modified by flipping diodes, anodes towards rows (blue bus) + demonstrates mapping from LAYOUT to MATRIX on a single-layer keyboard + +| Layout | **0** | **1** | +|:------:|-------|-------| +| **0** | 1 | 2 | +| **1** | a | b | +*/ +// ################## GLOBAL ################### +// ================= INCLUDES ================== +#include +#include +#include +#include + +// ============ SPEED CONFIGURATION ============ +ScanDelay scanDelay(9000); + +// ================== SCANNER ================== +uint8_t readPins[] = {0, 1}; +uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins); + +Scanner_uC scanner(LOW, readPins, readPinCount); + +// =================== CODES =================== +Code_Sc s_a(KEY_A); +Code_Sc s_b(KEY_B); +Code_Sc s_1(KEY_1); +Code_Sc s_2(KEY_2); + +/* ================== LAYOUT =================== +Keyboard layout is the placement of keys. +*/ +Key* const ptrsLayout[2][2] = { //[row][col] + //col0 col1 + { &s_1, &s_2 }, //row0 + { &s_a, &s_b } //row1 +}; + +/* ================== MATRIX =================== +// --------------- KEY MAPPINGS ---------------- +ptrsLayout[row][col] coordinates correspond to the elements in the layout. +The Keys are transposed (layout rows are placed in matrix columns). +*/ +Key* ptrsKeys_0[] = { ptrsLayout[0][0], ptrsLayout[1][0] }; +uint8_t keyCount_0 = sizeof(ptrsKeys_0)/sizeof(*ptrsKeys_0); +Row row_0(scanner, 14, ptrsKeys_0, keyCount_0); + +Key* ptrsKeys_1[] = { ptrsLayout[0][1], ptrsLayout[1][1] }; +uint8_t keyCount_1 = sizeof(ptrsKeys_1)/sizeof(*ptrsKeys_1); +Row row_1(scanner, 15, ptrsKeys_1, keyCount_1); + +// ################### MAIN #################### +void setup() +{ +} + +void loop() +{ + row_0.process(); + row_1.process(); + scanDelay.delay(); +} diff --git a/tutorials/keybrd_7b_mapping_multi-layer/back.JPG b/tutorials/keybrd_7b_mapping_multi-layer/back.JPG new file mode 100644 index 0000000..2afd139 Binary files /dev/null and b/tutorials/keybrd_7b_mapping_multi-layer/back.JPG differ diff --git a/tutorials/keybrd_7b_mapping_multi-layer/crossed_columns.jpg b/tutorials/keybrd_7b_mapping_multi-layer/crossed_columns.jpg new file mode 100644 index 0000000..2258983 Binary files /dev/null and b/tutorials/keybrd_7b_mapping_multi-layer/crossed_columns.jpg differ diff --git a/tutorials/keybrd_7b_mapping_multi-layer/front.JPG b/tutorials/keybrd_7b_mapping_multi-layer/front.JPG new file mode 100644 index 0000000..60cdda7 Binary files /dev/null and b/tutorials/keybrd_7b_mapping_multi-layer/front.JPG differ diff --git a/tutorials/keybrd_7b_mapping_multi-layer/keybrd_7b_mapping_multi-layer.ino b/tutorials/keybrd_7b_mapping_multi-layer/keybrd_7b_mapping_multi-layer.ino new file mode 100644 index 0000000..9dc6f55 --- /dev/null +++ b/tutorials/keybrd_7b_mapping_multi-layer/keybrd_7b_mapping_multi-layer.ino @@ -0,0 +1,109 @@ +/* keybrd_7b_mapping_multi-layer.ino + +This sketch: + is modified from keybrd_3a_multi-layerHold.ino by swaping readPins numbers with Row-pin numbers + runs on basic breadboard keyboard modified by flipping diodes, anodes towards rows (blue bus) + demonstrates mapping from LAYOUT to MATRIX on a multi-layer keyboard + assumes you undstand keybrd Tutorial 2 - keybrd multi-layer + +| Layout | **0** | **1** | +|:------:|-------|-------| +| **0** | a - | b = | +| **1** | fn | shift | +*/ +// ################## GLOBAL ################### +// ================= INCLUDES ================== +//Keys +#include +#include +#include +#include + +//Matrix +#include +#include +#include + +// ============ SPEED CONFIGURATION ============ +ScanDelay scanDelay(9000); + +// ================== SCANNER ================== +uint8_t readPins[] = {0, 1}; +uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins); + +Scanner_uC scanner(LOW, readPins, readPinCount); + +// =================== CODES =================== +// ---------------- LAYER CODE ----------------- +enum layerIds { NORMAL, FN }; + +LayerState layerState; + +Code_LayerHold l_fn(FN, layerState); + +// ---------------- SCAN CODES ----------------- +Code_Sc s_a(KEY_A); +Code_Sc s_b(KEY_B); +Code_Sc s_minus(KEY_MINUS); +Code_Sc s_equal(KEY_EQUAL); +Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT); + +/* ================== LAYOUT =================== +Keyboard layout is the placement of keys. +nullptrs are place holders that are not mapped to the matrix. +By convention, single-layer keys are placed on layer0, and nulls are placed in the remaining layers. +If you replace a null with a code, make sure its coordinate is in the KEYS MAPPING section. +Each non-nullptr array element consums 4 bytes of SRAM (on Teensy LC 32 bit controller). +*/ +Key* const ptrsLayout[2][2][2] = { //[layer][row][col] + //layer0 + {//col0 col1 + { &s_a, &s_b }, //row0 + { &l_fn, &s_shift } //row1 + }, + //layer1 + {//col0 col1 + { &s_minus, &s_equal }, //row0 + { nullptr, nullptr } //row1 + } +}; + +/* ================== MATRIX =================== +ptrsLayout[layer][row][col] coordinates correspond to the elements in the layout. + +// --------------- CODE MAPPINGS --------------- +Each ptrsLayout in this section maps a Code to one layer in a Key. +Only Key_LayeredKeys are instantiated in this section. +*/ +Key* const ptrsKeys_00[] = { ptrsLayout[0][0][0], ptrsLayout[1][0][0] }; // { &s_a, &s_minus }; +Key_LayeredKeys k_00(ptrsKeys_00); + +Key* const ptrsKeys_01[] = { ptrsLayout[0][0][1], ptrsLayout[1][0][1] }; // { &s_b, &s_equal }; +Key_LayeredKeys k_01(ptrsKeys_01); + +LayerStateInterface& Key_LayeredKeys::refLayerState = layerState; + +/* --------------- KEY MAPPINGS ---------------- +The Keys are transposed (layout rows are placed in matrix columns). +ptrsLayout elements are from the LAYOUT section. +Key_LayeredKeys are from the CODE MAPPINGS section. +*/ +Key* const ptrsKeys_0[] = { &k_00, ptrsLayout[0][1][0] }; // { { &s_a, &s_minus }, &l_fn }; +uint8_t keyCount_0 = sizeof(ptrsKeys_0)/sizeof(*ptrsKeys_0); +Row row_0(scanner, 14, ptrsKeys_0, keyCount_0); + +Key* const ptrsKeys_1[] = { &k_01, ptrsLayout[0][1][1] }; // { { &s_b, &s_equal }, &s_shift }; +uint8_t keyCount_1 = sizeof(ptrsKeys_1)/sizeof(*ptrsKeys_1); +Row row_1(scanner, 15, ptrsKeys_1, keyCount_1); + +// ################### MAIN #################### +void setup() +{ +} + +void loop() +{ + row_0.process(); + row_1.process(); + scanDelay.delay(); +} diff --git a/tutorials/tutorial_3cde_sublayer_keyboard.md b/tutorials/tutorial_3cde_sublayer_keyboard.md index b57f9c2..d6c956a 100644 --- a/tutorials/tutorial_3cde_sublayer_keyboard.md +++ b/tutorials/tutorial_3cde_sublayer_keyboard.md @@ -1,6 +1,6 @@ Tutorial 3cde - sublayer keyboard ================================= -This tutorial assumes you have read tutorial_3ab_multi-layer_keyboard. +This tutorial assumes you understand tutorial_3ab_multi-layer_keyboard. When you finish this tutorial you will be able to be able to modify a multi-layer keybrd sketch. @@ -28,14 +28,16 @@ Pressing the Alpha-layer key locks the Alpha layer. Letters 'a' 'b' 'c' are on the Alpha layer. Pressing the Sym-layer key locks the Sym layer. -Symbols '-' '=' and "Num" layer key are on the Sym layer. +Symbols '-' '=' and 'Num' layer key are on the Sym layer. If the keyboard is locked on the Sym layer, holding Num down makes it the active layer. Number '1' is on the Num sublayer. Releasing the Num key makes the locked layer active. +Sublayers are very flexible. Example sketches 3c, 3d, and 3e implement the above layout. -Each sketch uses a different layer scheme. +Each sketch demonstrates a different layer scheme. +Which approach works best depends on the layout. The sketches will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md) with a 3rd column added to pin 16: @@ -138,8 +140,8 @@ The top row is easily implemented in one layer group with duplicate keys filling | **0** | a - 1 | b = = | c Ent Ent | layer group with three layers: Alpha Sym Num | **1** | | | | -Complex layerschemes --------------------- +Complex layer schemes +--------------------- The basic LayerState class used in the tutorials is sufficient for implementing many layer schemes. More complicated layer schemes would need custom LayerState classes, and possibly custom Code_Layer and Key_Layered classes as well. Any layer scheme can be implemented with the right custom layer classes. diff --git a/tutorials/tutorial_7ab_mapping_layout_to_matix.md b/tutorials/tutorial_7ab_mapping_layout_to_matix.md new file mode 100644 index 0000000..bc3e800 --- /dev/null +++ b/tutorials/tutorial_7ab_mapping_layout_to_matix.md @@ -0,0 +1,45 @@ +keybrd Tutorial 7ab - mapping layout to matrix +============================================ +After reading this tutorial you will be able to map a keyboard layout to a keyboard matrix. + +Keyboard mapping nomenclature +----------------------------- +**[Keyboard layout](http://en.wikipedia.org/wiki/Keyboard_layout)** - is the placement of keys. Key caps are often labeled to show a keyboard's layout. + +**[Matrix](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/)** - is a collection of switches electrically connected into rows and columns. + +**[Transpose](https://en.wikipedia.org/wiki/Transpose)** - is the mapping of layout rows to matrix columns. Used when diodes are oriented with anodes towards the matrix rows. + +When to use mapping +------------------- +In most of the other keybrd tutorial examples: +* layout and matrix are congruent +* active-low keyboard diodes are oriented with cathodes towards the matrix rows + (or active-high keyboard diodes are oriented with anodes towards the matrix rows) + +There is no standard way keyboards are manufactured. Some variations are: +* irregular matrix +* active-low keyboard diodes are oriented with anodes towards the matrix rows +* active-high keyboard diodes are oriented with cathodes towards the matrix rows +* I/O expander pins connect to matrix out of order + +Any of these variations can use a mapping to align a layout with the matrix. + +Mapping a layout to a matrix +---------------------------- +Modify the basic breadboard keyboard by flipping diodes, so that anodes are towards matrix rows (blue bus). +The [keybrd_7a_mapping_single-layer.ino](keybrd_7a_mapping_single-layer/keybrd_7a_mapping_single-layer.ino) sketch will run on the keyboard. +Annotations in the sketch explain how mapping from LAYOUT to MATRIX works. + +The [keybrd_7b_mapping_multi-layer.ino](keybrd_7b_mapping_multi-layer/keybrd_7b_mapping_multi-layer.ino) sketch will run on the same keyboard. + +Exercise +-------- +1) Make a keyboard with an irregular matrix. + * Modify the basic breadboard keyboard by crossing the columns. + * Modify the keybrd_2_single-layer.ino sketch by mapping the layout to the irregular matrix. + +![crossed columns](keybrd_7_mapping_layout_to_matix/crossed_columns.jpg "crossed columns") + +
+Creative Commons License
keybrd tutorial by Wolfram Volpi is licensed under a Creative Commons Attribution 4.0 International License.
Permissions beyond the scope of this license may be available at https://github.com/wolfv6/keybrd/issues/new.