From 9f910d73ad85074e260c30133bd5481c96165f78 Mon Sep 17 00:00:00 2001 From: wolfv6 Date: Wed, 21 Sep 2016 20:29:40 -0600 Subject: [PATCH] update split keyboard tutorials 4a 4b 4c and sketches --- README.md | 2 +- src/Scanner_ShiftRegsPISOSingleRow.cpp | 1 + src/config_keybrd.h | 4 +- .../keybrd_3a_multi-layerHold.ino | 8 +- .../keybrd_3b_multi-layerLock.ino | 20 +-- .../keybrd_3c_sublayerNull.ino | 20 +-- .../keybrd_3d_sublayerNestedKeys.ino | 27 ++--- .../keybrd_3e_sublayerNestedScSc.ino | 27 +++-- .../keybrd_3f_autoShift.ino | 18 +-- ...4b_split_keyboard_with_shift_registers.ino | 21 ++-- .../keybrd_4c_split_keyboard_with_IOE.ino} | 25 ++-- tutorials/keybrd_5_LEDs/keybrd_5_LEDs.ino | 8 +- .../tutorial_3ab_multi-layer_keyboard.md | 12 +- tutorials/tutorial_3cde_sublayer_keyboard.md | 114 ++++++++++-------- tutorials/tutorial_3f_autoShift.md | 18 ++- .../tutorial_4a_connecting_split_keyboards.md | 58 +++++++++ ..._4b_split_keyboard_with_shift_registers.md | 38 +++--- .../tutorial_4c_split_keyboard_with_IOE.md | 4 +- 18 files changed, 258 insertions(+), 167 deletions(-) rename tutorials/{keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino => keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino} (86%) create mode 100644 tutorials/tutorial_4a_connecting_split_keyboards.md diff --git a/README.md b/README.md index 12eb66c..d4bacc8 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Its layout has 52 keys, 3 primary layers, 5 sub-layers, 2 matrices, 8 LEDs, and [keybrd_DH_library_developer_guide.md](https://github.com/wolfv6/keybrd_DH/blob/master/doc/keybrd_DH_library_developer_guide.md)
[mainSketch.ino](https://github.com/wolfv6/keybrd_DH/blob/master/examples/keybrd_DH/mainSketch.cpp)
-[instantiations_pins.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_pins.h)
+[instantiations_scannersLEDs.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_pins.h)
[instantiations_scancodes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_scancodes.h)
[instantiations_layercodes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_layercodes.h)
[instantiations_rows_L.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_rows_L.h)
diff --git a/src/Scanner_ShiftRegsPISOSingleRow.cpp b/src/Scanner_ShiftRegsPISOSingleRow.cpp index 18d5f31..60e31dc 100644 --- a/src/Scanner_ShiftRegsPISOSingleRow.cpp +++ b/src/Scanner_ShiftRegsPISOSingleRow.cpp @@ -21,6 +21,7 @@ Initializes shift register's shift/load pin. */ void Scanner_ShiftRegsPISOSingleRow::begin() { + SPI.begin(); digitalWrite(slaveSelect, HIGH); } diff --git a/src/config_keybrd.h b/src/config_keybrd.h index 9a6f50f..2aac5b8 100644 --- a/src/config_keybrd.h +++ b/src/config_keybrd.h @@ -13,9 +13,9 @@ Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing. For Scanner_ShiftRegsPISO: read_pins_t bits >= Scanner_ShiftRegsPISO::byte_count * 8 (For Scanner_IOE: I/O expanders are assumed to have 8 bits per port or less) */ -typedef uint8_t read_pins_t; +//typedef uint8_t read_pins_t; //typedef uint16_t read_pins_t; -//typedef uint32_t read_pins_t; +typedef uint32_t read_pins_t; /* SAMPLE_COUNT_MACRO is used in Debouncer_Samples.h SAMPLE_COUNT_MACRO = 4 is very reliable for a keyboard. 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 8dad50a..746a0eb 100644 --- a/tutorials/keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino +++ b/tutorials/keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino @@ -72,11 +72,11 @@ The Key_LayeredKeys constructor takes one array of Code pointers - one Code obje The Key object names in this sketch start with a "k_" followed by row-column coordinates. */ -Key* const ptrsCodes_00[] = { &s_a, &s_minus }; -Key_LayeredKeys k_00(ptrsCodes_00); +Key* const ptrsKeys_00[] = { &s_a, &s_minus }; +Key_LayeredKeys k_00(ptrsKeys_00); -Key* const ptrsCodes_01[] = { &s_b, &s_equal }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_01[] = { &s_b, &s_equal }; +Key_LayeredKeys k_01(ptrsKeys_01); /* Key_LayeredKeys has a reference to layerState. diff --git a/tutorials/keybrd_3b_multi-layerLock/keybrd_3b_multi-layerLock.ino b/tutorials/keybrd_3b_multi-layerLock/keybrd_3b_multi-layerLock.ino index 48b96f7..78d13e1 100644 --- a/tutorials/keybrd_3b_multi-layerLock/keybrd_3b_multi-layerLock.ino +++ b/tutorials/keybrd_3b_multi-layerLock/keybrd_3b_multi-layerLock.ino @@ -7,10 +7,10 @@ This sketch: | Layout | **0** | **1** | |:------:|:-----:|:-----:| | **0** | a - | b = | -| **1** |Normal | Sym | +| **1** | Alpha | Sym | -Pressing the "Normal" layer key locks the Normal layer. -Letters 'a' 'b' are on the Normal layer. +Pressing the "Alpha" layer key locks the Alpha layer. +Letters 'a' 'b' are on the Alpha layer. Pressing the "Sym" layer key locks the Sym layer. Symbols '-' '=' are on the Sym layer. @@ -39,7 +39,7 @@ Scanner_uC scanner(LOW, readPins, readPinCount); // =================== CODES =================== // ---------------- LAYER CODE ----------------- -enum layers { NORMAL, SYM }; +enum layers { ALPHA, SYM }; LayerState layerState; @@ -47,10 +47,10 @@ LayerState layerState; The Code_LayerLock constructor has two parameters: 1) the layerId that becomes the active layer when the key is pressed 2) a LayerState that will keep track of the active layer -When l_normal is pressed, NORMAL becomes the active layer. +When l_normal is pressed, ALPHA becomes the active layer. When l_sym is pressed, SYM becomes the active layer. */ -Code_LayerLock l_normal(NORMAL, layerState); +Code_LayerLock l_normal(ALPHA, layerState); Code_LayerLock l_sym(SYM, layerState); // ---------------- SCAN CODES ----------------- @@ -60,11 +60,11 @@ Code_Sc s_minus(KEY_MINUS); Code_Sc s_equal(KEY_EQUAL); // =================== KEYS ==================== -Key* const ptrsCodes_00[] = { &s_a, &s_minus }; -Key_LayeredKeys k_00(ptrsCodes_00); +Key* const ptrsKeys_00[] = { &s_a, &s_minus }; +Key_LayeredKeys k_00(ptrsKeys_00); -Key* const ptrsCodes_01[] = { &s_b, &s_equal }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_01[] = { &s_b, &s_equal }; +Key_LayeredKeys k_01(ptrsKeys_01); LayerStateInterface& Key_LayeredKeys::refLayerState = layerState; diff --git a/tutorials/keybrd_3c_sublayerNull/keybrd_3c_sublayerNull.ino b/tutorials/keybrd_3c_sublayerNull/keybrd_3c_sublayerNull.ino index e3de03c..d88796d 100644 --- a/tutorials/keybrd_3c_sublayerNull/keybrd_3c_sublayerNull.ino +++ b/tutorials/keybrd_3c_sublayerNull/keybrd_3c_sublayerNull.ino @@ -7,7 +7,7 @@ This sketch: | Layout | **0** | **1** | **2** | |:------:|:-----:|:-----:|:-----:| | **0** | a - 1 | b = | c Num | -| **1** |Normal | Sym | Enter | +| **1** | Alpha | Sym | Enter | */ // ################## GLOBAL ################### @@ -38,11 +38,11 @@ Scanner_uC scanner(LOW, readPins, readPinCount); /* ---------------- LAYER CODE ----------------- One LayerState object manages all 3 layers. */ -enum layers { NORMAL, SYM, NUM }; +enum layers { ALPHA, SYM, NUM }; LayerState layerState; -Code_LayerLock l_normal(NORMAL, layerState); +Code_LayerLock l_normal(ALPHA, layerState); Code_LayerLock l_sym(SYM, layerState); Code_LayerHold l_num(NUM, layerState); @@ -68,22 +68,22 @@ The layout has one key with 3 layers, and two keys with 2 layers. But the layer scheme has 3 layers for all three keys. The extra layers are filled with duplicate codes and null codes. */ -Key* const ptrsCodes_00[] = { &s_a, &s_minus, &s_1 }; -Key_LayeredKeys k_00(ptrsCodes_00); +Key* const ptrsKeys_00[] = { &s_a, &s_minus, &s_1 }; +Key_LayeredKeys k_00(ptrsKeys_00); /* s_equal is duplicated in layer 2. */ -Key* const ptrsCodes_01[] = { &s_b, &s_equal, &s_equal }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_01[] = { &s_b, &s_equal, &s_equal }; +Key_LayeredKeys k_01(ptrsKeys_01); /* code_null occupies layer 2. Class Code_Null doesn't do anything. It is useful for blank codes. Remember to fill all layers with codes. -If the code_null were omitted from the array, dereferencing ptrsCodes_02[2] could cause a crash. +If the code_null were omitted from the array, dereferencing ptrsKeys_02[2] could cause a crash. */ -Key* const ptrsCodes_02[] = { &s_c, &l_num, &code_null }; -Key_LayeredKeys k_02(ptrsCodes_02); +Key* const ptrsKeys_02[] = { &s_c, &l_num, &code_null }; +Key_LayeredKeys k_02(ptrsKeys_02); // =================== ROWS ==================== Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02 }; diff --git a/tutorials/keybrd_3d_sublayerNestedKeys/keybrd_3d_sublayerNestedKeys.ino b/tutorials/keybrd_3d_sublayerNestedKeys/keybrd_3d_sublayerNestedKeys.ino index 167c3ed..9edabe2 100644 --- a/tutorials/keybrd_3d_sublayerNestedKeys/keybrd_3d_sublayerNestedKeys.ino +++ b/tutorials/keybrd_3d_sublayerNestedKeys/keybrd_3d_sublayerNestedKeys.ino @@ -7,7 +7,7 @@ This sketch: | Layout | **0** | **1** | **2** | |:------:|:-----:|:-----:|:-----:| | **0** | a - 1 | b = | c Num | -| **1** |Normal | Sym | Enter | +| **1** | Alpha | Sym | Enter | */ // ################## GLOBAL ################### @@ -36,11 +36,11 @@ Scanner_uC scanner(LOW, readPins, readPinCount); // =================== CODES =================== // ----------------- LAYER CODE ---------------- -enum layers { NORMAL, SYM }; +enum layers { ALPHA, SYM }; LayerState layerState; -Code_LayerLock l_normal(NORMAL, layerState); +Code_LayerLock l_normal(ALPHA, layerState); Code_LayerLock l_sym(SYM, layerState); /* @@ -49,8 +49,7 @@ Key_LayeredKeys are associated with layerState. LayerStateInterface& Key_LayeredKeys::refLayerState = layerState; /* ---------------- SUBLAYER CODE -------------- -Sublayers are implemented just like main layers. -Here the Num sublayer is given it's own proper LayerState. +Sublayers are implemented just like primary layers. */ enum subLayers { SUBSYM, SUBNUM }; @@ -80,23 +79,23 @@ Code_Sc s_1(KEY_1); The key k_sub00 contains codes for layerIds SUBSYM and SUBNUM. (The Num sublayer only has one key because small example. Usually sublayers have multiple keys.) */ -Key* const ptrsCodes_sub00[] = { &s_minus, &s_1 }; -Key_LayeredKeys1 k_sub00(ptrsCodes_sub00); +Key* const ptrsKeys_sub00[] = { &s_minus, &s_1 }; +Key_LayeredKeys1 k_sub00(ptrsKeys_sub00); /* k_sub00 is nested in k_00. -The key k_00 contains code and key for layerIds NORMAL and SYS. +The key k_00 contains code and key for layerIds ALPHA and SYM. Notice that k_sub00 is of type Key_LayeredKeys1, while k_00 is of type Key_LayeredKeys. k_sub00 and k_00 are associated with distinct LayerStates. */ -Key* const ptrsCodes_00[] = { &s_a, &k_sub00 }; -Key_LayeredKeys k_00(ptrsCodes_00); +Key* const ptrsKeys_00[] = { &s_a, &k_sub00 }; +Key_LayeredKeys k_00(ptrsKeys_00); -Key* const ptrsCodes_01[] = { &s_b, &s_equal }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_01[] = { &s_b, &s_equal }; +Key_LayeredKeys k_01(ptrsKeys_01); -Key* const ptrsCodes_02[] = { &s_c, &l_num }; -Key_LayeredKeys k_02(ptrsCodes_02); +Key* const ptrsKeys_02[] = { &s_c, &l_num }; +Key_LayeredKeys k_02(ptrsKeys_02); // =================== ROWS ==================== Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02 }; diff --git a/tutorials/keybrd_3e_sublayerNestedScSc/keybrd_3e_sublayerNestedScSc.ino b/tutorials/keybrd_3e_sublayerNestedScSc/keybrd_3e_sublayerNestedScSc.ino index 6be426a..5d59c1f 100644 --- a/tutorials/keybrd_3e_sublayerNestedScSc/keybrd_3e_sublayerNestedScSc.ino +++ b/tutorials/keybrd_3e_sublayerNestedScSc/keybrd_3e_sublayerNestedScSc.ino @@ -7,7 +7,7 @@ This sketch: | Layout | **0** | **1** | **2** | |:------:|:-----:|:-----:|:-----:| | **0** | a - 1 | b = | c Num | -| **1** |Normal | Sym | Enter | +| **1** | Alpha | Sym | Enter | */ // ################## GLOBAL ################### @@ -36,13 +36,16 @@ Scanner_uC scanner(LOW, readPins, readPinCount); // =================== CODES =================== // ---------------- LAYER CODE ----------------- -enum layers { NORMAL, SYM }; +enum layers { ALPHA, SYM }; LayerState layerState; -Code_LayerLock l_normal(NORMAL, layerState); +Code_LayerLock l_normal(ALPHA, layerState); Code_LayerLock l_sym(SYM, layerState); +/* +Key_LayeredKeys are associated with layerState. +*/ LayerStateInterface& Key_LayeredKeys::refLayerState = layerState; // ---------------- SUBLAYER CODE -------------- @@ -52,6 +55,9 @@ LayerState sublayerState; Code_LayerHold l_num(SUBNUM, sublayerState); +/* +Key_LayeredScSc is associated with layerState. +*/ LayerStateInterface& Key_LayeredScSc::refLayerState = sublayerState; // ---------------- SCAN CODES ----------------- @@ -74,18 +80,17 @@ Key_LayeredScSc sub_00(KEY_MINUS, KEY_1); /* k_sub00 is nested in k_00. -The key k_00 contains code and key for layerIds NORMAL and SYS. -Notice that k_sub00 is of type Key_LayeredKeys1, while k_00 is of type Key_LayeredKeys. +The key k_00 contains code and key for layerIds ALPHA and SYM. k_sub00 and k_00 are associated with distinct LayerStates. */ -Key* const ptrsCodes_00[] = { &s_a, &sub_00 }; -Key_LayeredKeys k_00(ptrsCodes_00); +Key* const ptrsKeys_00[] = { &s_a, &sub_00 }; +Key_LayeredKeys k_00(ptrsKeys_00); -Key* const ptrsCodes_01[] = { &s_b, &s_equal }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_01[] = { &s_b, &s_equal }; +Key_LayeredKeys k_01(ptrsKeys_01); -Key* const ptrsCodes_02[] = { &s_c, &l_num }; -Key_LayeredKeys k_02(ptrsCodes_02); +Key* const ptrsKeys_02[] = { &s_c, &l_num }; +Key_LayeredKeys k_02(ptrsKeys_02); // =================== ROWS ==================== Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02 }; diff --git a/tutorials/keybrd_3f_autoShift/keybrd_3f_autoShift.ino b/tutorials/keybrd_3f_autoShift/keybrd_3f_autoShift.ino index 63e4f26..14d6cdd 100644 --- a/tutorials/keybrd_3f_autoShift/keybrd_3f_autoShift.ino +++ b/tutorials/keybrd_3f_autoShift/keybrd_3f_autoShift.ino @@ -6,8 +6,8 @@ This sketch: | Layout | **0** | **1** | |:------:|-------|-------| -| **0** | shift | a ! | -| **1** | fn | b @ | +| **0** | a ! | b @ | +| **1** | fn | shift | The layered keys in row 0 have two layers; one character for each layer. Letters 'a' and 'b' are on the normal layer. Symbols '!' and '@' are one the fn layer. @@ -74,7 +74,7 @@ const uint8_t Code_AutoShift::shiftCount = sizeof(ptrsS)/sizeof(*ptrsS); /* HOW SHIFT WORKS -When a shift key is pressed, a standard keyboard driver will temporarily modify the normal action of another key when pressed together. +When a shift key is pressed, a standard keyboard driver will temporarily modify the action of other scancodes. KEY_1 writes '1' MODIFIERKEY_LEFT_SHIFT + KEY_1 writes '!' @@ -90,21 +90,21 @@ When the user presses '!' or '@' on the fn layer: */ // =================== KEYS ==================== -Key* const ptrsCodes_01[] = { &s_a, &s_exclamation }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_00[] = { &s_a, &s_exclamation }; +Key_LayeredKeys k_00(ptrsKeys_00); -Key* const ptrsCodes_11[] = { &s_b, &s_at }; -Key_LayeredKeys k_11(ptrsCodes_11); +Key* const ptrsKeys_01[] = { &s_b, &s_at }; +Key_LayeredKeys k_01(ptrsKeys_01); LayerStateInterface& Key_LayeredKeys::refLayerState = layerState; // =================== ROWS ==================== -Key* const ptrsKeys_0[] = { &s_shift, &k_01 }; +Key* const ptrsKeys_0[] = { &k_00, &k_01 }; uint8_t keyCount_0 = sizeof(ptrsKeys_0)/sizeof(*ptrsKeys_0); Row row_0(scanner, 0, ptrsKeys_0, keyCount_0); //Row row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0); -Key* const ptrsKeys_1[] = { &l_fn, &k_11 }; +Key* const ptrsKeys_1[] = { &l_fn, &s_shift }; uint8_t keyCount_1 = sizeof(ptrsKeys_1)/sizeof(*ptrsKeys_1); Row row_1(scanner, 1, ptrsKeys_1, keyCount_1); //Row row_1(1, readPins, READ_PIN_COUNT, ptrsKeys_1); diff --git a/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino b/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino index a21cfaa..4356d73 100644 --- a/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino +++ b/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino @@ -1,4 +1,4 @@ -/* tutorial_4a_split_keyboard_with_shift_registers.ino +/* tutorial_4b_split_keyboard_with_shift_registers.ino Tested on Teensy LC and two 74HC165 shift registers. The right matrix has 2 shift registers daisy chained. @@ -19,7 +19,6 @@ The right matrix has 2 shift registers daisy chained. #include //Right matrix -//#include //needed?? todo #include // =============== CONFIGURATION =============== @@ -45,13 +44,20 @@ Code_Sc s_4(KEY_4); Code_Sc s_5(KEY_5); Code_Sc s_6(KEY_6); -// =============== LEFT MATRIX ================= +// ================= SCANNERS ================== +// --------------- LEFT SCANNER ---------------- uint8_t readPins_L[] = {14}; uint8_t readPinCount_L = sizeof(readPins_L)/sizeof(*readPins_L); Scanner_uC scanner_L(LOW, readPins_L, readPinCount_L); //active LOW -//rows +/* --------------- RIGHT SCANNER --------------- +use slaveSelect pin SS (Arduino pin 10) for fastest scan +*/ +Scanner_ShiftRegsPISOSingleRow scanner_R(HIGH, SS, 2); //active HIGH + +// =================== ROWS ==================== +// ----------------- LEFT ROWS ----------------- Key* ptrsKeys_L0[] = { &s_x }; uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0); Row row_L0(scanner_L, 0, ptrsKeys_L0, KEY_COUNT_L0); @@ -60,11 +66,7 @@ Key* ptrsKeys_L1[] = { &s_y }; uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1); Row row_L1(scanner_L, 1, ptrsKeys_L1, KEY_COUNT_L1); -// =============== RIGHT MATRIX ================ -//use slaveSelect pin SS (Arduino pin 10) for fastest scan -Scanner_ShiftRegsPISOSingleRow scanner_R(HIGH, SS, 2); //active HIGH - -//rows +// ----------------- RIGHT ROWS ---------------- Key* ptrsKeys_R0[] = { &s_6, &s_5, &s_4, &s_3, //shift register on right &s_c, &s_d, &s_e, &s_f, &s_2, &s_1, &s_0, &s_g, //shift register on left @@ -75,7 +77,6 @@ Row row_R0(scanner_R, 0, ptrsKeys_R0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0)); void setup() { Keyboard.begin(); - SPI.begin();//todo move to begin() scanner_R.begin(); } diff --git a/tutorials/keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino b/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino similarity index 86% rename from tutorials/keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino rename to tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino index 4ca0008..bb56566 100644 --- a/tutorials/keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino +++ b/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino @@ -1,9 +1,8 @@ -/* keybrd_4c_split_with_IOE.ino +/* keybrd_4c_split_keyboard_with_IOE.ino This sketch: is a simple 1-layer keyboard runs on two matrices of a breadboard keyboard - is annotated with a walk-through narrative This layout table shows left and right matrices: @@ -30,8 +29,7 @@ This layout table shows left and right matrices: // ============ SPEED CONFIGURATION ============ ScanDelay scanDelay(9000); -// ================ LEFT SCANNER =============== -/* +/* ================ LEFT SCANNER =============== Left matrix rows work the same as the ones in keybrd_2_single-layer.ino */ uint8_t readPins[] = {14, 15}; @@ -39,8 +37,7 @@ const uint8_t READPIN_COUNT = sizeof(readPins)/sizeof(*readPins); Scanner_uC scanner_L(LOW, readPins, READPIN_COUNT); -// =============== RIGHT SCANNER =============== -/* +/* =============== RIGHT SCANNER =============== The right matrix is scanned by an I/O expander. The I/O expander device address is configured by hardware pins. @@ -48,13 +45,12 @@ DEVICE_ADDR is a static variable of class PortIOE. */ const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address with all 3 ADDR pins are grounded -todo explain port num and shift notation << /* port_B stobes the row while port_A reads the colums. port_A is assigned port identification number 0. port_A is assigned to portRead, which reads port_A pins 0 and 1. -"<<" (bit shift left) and "|" (or) are bitwise operators. +"<<" (bit shift left) and "|" (OR) are bitwise operators. Pin numbers to be read are to the right of "1<<" and delimited by "|". */ PortIOE port_A(0); @@ -81,18 +77,17 @@ Code_Sc s_2(KEY_2); Code_Sc s_3(KEY_3); Code_Sc s_4(KEY_4); -// =================== ROWS ==================== -/* +/* =================== ROWS ==================== Left row names contain the letter 'L', while right row names conatain the letter 'R'. The first parameteer of a Row constructor specifies the scanner. The second parameter of the Row constructor specifies the Row's strobePin. strobePin has one of two formats: * if refScanner a Scanner_uC, then strobePin is an Arduino pin number connected to this row - * otherwise strobePin is a bit pattern, 1 indicating an IC pin connected to this row + * otherwise strobePin is a bit pattern, 1 indicating an IC pin connected to the row */ -// ---------------- LEFT ROWS ------------------ -/* The left rows have a Scanner_uC and Arduino pin numbers to strobe. +/* ---------------- LEFT ROWS ------------------ +The left rows have a Scanner_uC and Arduino pin numbers to strobe. */ Key* ptrsKeys_L0[] = { &s_1, &s_2 }; const uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0); @@ -102,8 +97,7 @@ Key* ptrsKeys_L1[] = { &s_a, &s_b }; const uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1); Row row_L1(scanner_L, 1, ptrsKeys_L1, KEY_COUNT_L1); -// ---------------- RIGHT ROWS ----------------- -/* +/* ---------------- RIGHT ROWS ----------------- The right rows have a Scanner_IOE and pin bits to strobe. */ Key* ptrsKeys_R0[] = { &s_3, &s_4 }; @@ -117,7 +111,6 @@ Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1); // ################### MAIN #################### void setup() { -delay(7000); //todo Keyboard.begin(); scanner_R.begin(); } diff --git a/tutorials/keybrd_5_LEDs/keybrd_5_LEDs.ino b/tutorials/keybrd_5_LEDs/keybrd_5_LEDs.ino index 582d7d8..1c53435 100644 --- a/tutorials/keybrd_5_LEDs/keybrd_5_LEDs.ino +++ b/tutorials/keybrd_5_LEDs/keybrd_5_LEDs.ino @@ -72,11 +72,11 @@ Code_Sc s_1(KEY_1); Code_Sc s_2(KEY_2); // =================== KEYS ==================== -Key* const ptrsCodes_01[] = { &s_a, &s_1 }; -Key_LayeredKeys k_01(ptrsCodes_01); +Key* const ptrsKeys_01[] = { &s_a, &s_1 }; +Key_LayeredKeys k_01(ptrsKeys_01); -Key* const ptrsCodes_11[] = { &s_b, &s_2 }; -Key_LayeredKeys k_11(ptrsCodes_11); +Key* const ptrsKeys_11[] = { &s_b, &s_2 }; +Key_LayeredKeys k_11(ptrsKeys_11); LayerStateInterface& Key_LayeredKeys::refLayerState = layerState; diff --git a/tutorials/tutorial_3ab_multi-layer_keyboard.md b/tutorials/tutorial_3ab_multi-layer_keyboard.md index 010b295..96841b0 100644 --- a/tutorials/tutorial_3ab_multi-layer_keyboard.md +++ b/tutorials/tutorial_3ab_multi-layer_keyboard.md @@ -120,14 +120,22 @@ A basic LayerState class is: Key_Layered classes include: * Key_LayeredKeys -* Key_LayeredScSc +* Key_LayeredScSc (covered in next tutorial) * Key_LayeredCodeSc Exercises --------- -Compile and run keybrd_3a_multi-layerHold.ino and keybrd_3b_multi-layerLock.ino +1) Compile and run [keybrd_3a_multi-layerHold.ino](keybrd_3a_multi-layerHold/keybrd_3a_multi-layerHold.ino) +and [keybrd_3b_multi-layerLock.ino](keybrd_3b_multi-layerLock/keybrd_3b_multi-layerLock.ino). Notice how Code_LayerHold and Code_LayerLock objects behave. +2) Modify the keybrd_3a_multi-layerHold.ino sketch to make a 3-layer keyboard with two Code_LayerHold keys. + +| Layout | **0** | **1** | +|:------:|:-----:|:-----:| +| **0** | a - 1 | b = 2 | +| **1** | sym | num | +
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. diff --git a/tutorials/tutorial_3cde_sublayer_keyboard.md b/tutorials/tutorial_3cde_sublayer_keyboard.md index d99d966..5c3ea0c 100644 --- a/tutorials/tutorial_3cde_sublayer_keyboard.md +++ b/tutorials/tutorial_3cde_sublayer_keyboard.md @@ -6,12 +6,18 @@ When you finish this tutorial you will be able to be able to modify a multi-laye Sublayer nomenclature --------------------- -**primary layer** - is a layer whose layer key is accessible from the default layer. - -**sublayer** - is a layer whose layer key is not accessible from the default layer. +These definitions are specific to the keybrd library. **layer group** - is a group of layers that occupy the same keys. +**primary layer group** - is a layer group containing the default layer. + +**sublayer group** - is a layer group nested in a layer of another layer group. + +**primary layer** - is a layer within the primary layer group. + +**sublayer** - is a layer within the sublayer group. + Layer scheme with a sublayer ---------------------------- This tutorial has 3 example sketches, all using this layout: @@ -19,87 +25,95 @@ This tutorial has 3 example sketches, all using this layout: | Layout | **0** | **1** | **2** | |:------:|:-----:|:-----:|:-----:| | **0** | a - 1 | b = | c Num | -| **1** |Normal | Sym | Enter | +| **1** | Alpha | Sym | Enter | Each cell in the table's body represents a key. Bottom row keys have one layer. Top row keys have 2 or 3 layers. -Pressing the "Normal" layer key locks the Normal layer. -Letters 'a' 'b' 'c' are on the Normal layer. +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 '-' '=' are on the Sym layer. +Symbols '-' '=' and "Num" layer key are on the Sym layer. -The "Num" sublayer key is on the Sym layer. If the keyboard is locked on the Sym layer, holding Num down makes Num the active layer. Releasing the Num key restores the Sym layer. Number '1' is on the Num sublayer. todo [pic of 3 col bb kb] -Three example 3 sketches implement the above layout using differently layer schemes. -Keybrd provides flexibility todo?? +Three example sketches implement the above layout using differently layer schemes. Which layer scheme is best depends on the layout. -3c - ------------ -keybrd_3c_sublayerNull.ino +Sketch 3c - one layer group +--------------------------- +Refer to keybrd_3c_sublayerNull.ino -The layer scheme has one LayerState object cover all the layer groups. +The top row has one layer group with 3 layers. +Num layer is unused to the right of 1. Duplicate codes and null codes fill the unused space. It's a bit of a kludge, but can be simple if there is little unused space. -3d - ------------ -keybrd_3d_sublayerNestedKeys.ino +layerState contains the active layer for the layer group. -The layer scheme has a distinct LayerState object for each layer group. -One LayerState object per layer group is preferred because it models the logic of the layout. +Sketch 3d - two layer groups +---------------------------- +Refer to keybrd_3d_sublayerNestedKeys.ino -In this example, NORMAL+SYM is the primary layer group, which covers the top-row keys. -layerState keeps track of the primary layer group's active layer. +The top row has two layer groups. +* NORMAL+SYM is the primary layer group. It covers the top-row keys. +* SYM1+NUM1 is a sublayer group nested in the SYM layer. The subgroup covers the top-left key. -SUBSYM+SUBNUM is the sublayer group, which covers the top-left key. -subLayerState keeps track of the sublayer group's active layer. +Two layer groups model the logic of the layout accurately +(the previous example was a kluge because it only had one layer group). -The concepts of "sublayer" and "layer group" are independent. -In the following layout for example, l_num and s_enter codes have swapped places. -Num is now a primary layer, and SYM2+NUM2 is still layer group2. +There should be one LayerState object for each layer group. In this example: +* layerState contains the active layer for the primary layer group. +* sublayerState contains the active layer for the sublayer group. + +Sketch 3e - specialized layered keys +------------------------------------ +Refer to keybrd_3e_sublayerNestedScSc.ino + +Key_LayeredKeys constructor takes any number of code or key arguments. +Key_LayeredScSc is more specialized. It's constructor takes exactly two scancode arguments. +A Key_LayeredScSc object could be instantiated with Key_LayeredKeysArray. +But using Key_LayeredScSc has advantages when a large sublayer group has two layers: +* no array is created for the two scancodes +* less clutter in sketch +* save SRAM + +Key_Layered classes include: +* Key_LayeredKeys (any number of codes or keys) +* Key_LayeredScSc (specialized for two scancodes) +* Key_LayeredCodeSc (specialized for one code and one scancode) + +Sublayer layer-key placement +---------------------------- +A layer key to a sublayer can be place in one of two places: +* on layer the sublayer group is nested in (layout above has Num-layer key on Sym layer) +* on a single-layer key (layout below has Num-layer key on bottom row) (some people would not call this arrangement a sublayer) | Layout | **0** | **1** | **2** | |:------:|:-----:|:-----:|:-----:| | **0** | a - 1 | b = | c Ent | -| **1** |Normal | Sym | Num | - -3e - ------------ -keybrd_3e_sublayerNestedScSc.ino - -Key_LayeredKeys constructor takes any number of code arguments. -Key_LayeredScSc is more specialized. It's constructor takes exactly two scancode arguments. -No array was created for the two scancodes. -This has advantages when a large sublayer group has two layers: -* save SRAM -* less clutter in sketch - -with custom layer classes, any layer scheme can be implemented -DH is a complex layer scheme implemented with keybrd lib +| **1** | Alpha | Sym | Num | Complex layerschemes -------------------- 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. -keybrd_DH is an example of a complex layer scheme (it emulates the DataHand keyboard). +[keybrd_DH](https://github.com/wolfv6/keybrd_DH) is an example of a complex layer scheme (it emulates the DataHand keyboard). +The keybrd_DH sketch is a showcase of the keybrd library's capability. It's the most complex layer scheme I know of. -The keybrd_DH project is a showcase of the keybrd library's capability. Don't let the complexity scare you; most layer schemes are much simpler. -keybrd_DH's layout has 3 layers and 5 sub-layers. -Most of the layer classes are custom classes, which reside in the keybrd_DH library. -Layer classes used by keybrd_DH are listed below. -The length of the list gives a hint of the layer scheme's complexity. +Layer-scheme classes used by keybrd_DH are listed below. +The layer scheme classes are organized into three categories, as is "Layer-scheme classes" in the previous tutorial. +Most of the layer-scheme classes are custom classes, which reside in the keybrd_DH library. DH Code_Layer classes include: * Code_LayerLock @@ -123,4 +137,10 @@ DH Key_Layered classes include: Exercises --------- +Modify keybrd_3e_sublayerNestedScSc.ino by adding the number '2' to the Num layer group. +The layout is below. +| Layout | **0** | **1** | **2** | +|:------:|:-----:|:-----:|:-----:| +| **0** | a - 1 | b = 2 | c Num | +| **1** | Alpha | Sym | Enter | diff --git a/tutorials/tutorial_3f_autoShift.md b/tutorials/tutorial_3f_autoShift.md index 06c2fb1..0deff79 100644 --- a/tutorials/tutorial_3f_autoShift.md +++ b/tutorials/tutorial_3f_autoShift.md @@ -1,16 +1,15 @@ -Tutorial 3b - autoShift +Tutorial 3f - autoShift ======================= Some multi-layer keyboards have a symbols layer that writes symbols without using the shift key: ~ ! @ # $ % ^ & * () _ {} | < > : ? -The keybrd library does this by automatically sending a MODIFIERKEY_SHIFT scancode. - +The keybrd AutoShift class automatically sends a MODIFIERKEY_SHIFT scancode as needed. Two keybrd classes use AutoShift: * Code_ScS * Code_ScNS -The [keybrd_3b_autoShift.ino](keybrd_3b_autoShift/keybrd_3b_autoShift.ino) sketch explains the AutoShift feature. +The [keybrd_3f_autoShift.ino](keybrd_3f_autoShift/keybrd_3f_autoShift.ino) sketch explains the AutoShift feature. It will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md). After reading the sketch you too will be able to automatically shifted characters. @@ -18,12 +17,19 @@ After reading the sketch you too will be able to automatically shifted character Exercises --------- -1) Modify the keybrd_3b_autoShift sketch to make a 3-layer keyboard with a default layer and two Code_LayerHold objects. +1) Modify the keybrd_3f_autoShift sketch to make a 3-layer keyboard with a default layer and two Code_LayerHold objects. | Layout | **0** | **1** | |:------:|:-----:|:-----:| -| **0** | a ! 6 | b @ 7 | +| **0** | a ! 1 | b @ 2 | | **1** | sym | num | +2) Modify the keybrd_3f_autoShift sketch to write 1 and 2, regardless of if shift is held down or not (hint: use Code_ScNS). + +| Layout | **0** | **1** | +|:------:|-------|-------| +| **0** | a 1 | b 2 | +| **1** | fn | shift | +
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. diff --git a/tutorials/tutorial_4a_connecting_split_keyboards.md b/tutorials/tutorial_4a_connecting_split_keyboards.md new file mode 100644 index 0000000..391982c --- /dev/null +++ b/tutorials/tutorial_4a_connecting_split_keyboards.md @@ -0,0 +1,58 @@ +keybrd Tutorial 4a - Connecting split keyboards +=============================================== +Split keyboards have left and right parts: +* one keyboard half contains the controller and USB port. +* the other keyboard half can contain shift registers or an I/O expander. + +The two halves need to be connected. +The preferred connection method depends on the number of keys, number of available controller pins, cable flexibility, LEDs, and cost. + +## Split keyboard connections table + +| connection type | controller pins | wire count | max keys | +|:----------------------:|:---------------:|:----------:|:--------:| +| just cable | 6 | 6 | 9 | +| just cable | 7 | 7 | 12 | +| just cable | 8 | 8 | 16 | +| just cable | 9 | 9 | 20 | +| | | | | +| 2 PISO shift registers | 3 | 5 | 16 | +| 3 PISO shift registers | 3 | 5 | 24 | +| | | | | +| I/O expander SPI | 4 | 6 | 64 | +| I/O expander I2C | 2 | 4 | 64 | + +Fewer wires makes a cable more flexible. +A flexibility cable makes it easy to position the keyboard and route the cable. +But if there are enough pins on the controller, just using a cable with more wires is simpler and costs less. + +I/O Expanders can power LEDs, while PISO shift registers can not. + +I2C is a little slow if the I/O expander is scanning more than 4 rows. + +## Cables table + +| connector name | wire count | +|:-----------------------------------------------------:|:----------:| +| TRRS | 4 | +| 6-pin mini-DIN connector (PS/2) | 4 | +| USB 2 | 4 | +| 4P4C Modular connector (RJ9, RJ10, RJ22) handset plug | 4 | +| 6P4C Modular connector (RJ-14) 2-line phone | 4 | +| 6P6C Modular connector (RJ12) 3-line phone | 6 | +| eSATA | 7 | +| 8p8c Modular connector (RJ45) Ethernet | 8 | +| USB 3.0, 3.1 | 9 | + +Only ready-made cables that are widely available are listed. +There are hundreds of other connectors listed at http://pinouts.ru/ +There are also wireless options if you don't mind adding complexity and maintaining a battery. + +The 8-wire "GearIT Cat 6 Ethernet Flat Patch Cable 7 Feet" is very flexible. +It's available at Walmart if you want to feel the merchandise before you buy. +All the modular connectors are flat. + +For prototyping on perfboards, consider a 0.1” header. + +
+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. diff --git a/tutorials/tutorial_4b_split_keyboard_with_shift_registers.md b/tutorials/tutorial_4b_split_keyboard_with_shift_registers.md index d06996c..40f3999 100644 --- a/tutorials/tutorial_4b_split_keyboard_with_shift_registers.md +++ b/tutorials/tutorial_4b_split_keyboard_with_shift_registers.md @@ -1,16 +1,16 @@ keybrd Tutorial 4b - split keyboard with shift registers ======================================================== -When you finish this tutorial you will be able to be able to modify a split keybrd sketch with 10 to 24 keys on the peripheral hand. +When you finish this tutorial you will be able to be able to modify a split keybrd sketch with 10 to 24 keys on the shift registers. Overview of split keyboard with shift registers ------------------------------------------------ -Only the right matrix is shown. The left matrix was omitted to reduce clutter. +Only the right matrix is shown. The left matrix is not needed and was omitted to reduce clutter. -The layout has 2 rows and 7 columns. +The right-matrix layout has 2 rows and 7 columns. Electronically, the matrix only has one row. Diodes are not needed because there is only one row. -The two black rectangles are shift registers daisy chained together. +The two black rectangles are SN74HC165N shift registers daisy chained together. Shift register details are in the SN74HC165N datasheet. ![breadboard keyboard with shift_registers](keybrd_4b_split_keyboard_with_shift_registers/shift_reg_front.JPG ) @@ -20,7 +20,7 @@ Building a split breadboard keyboard with shift registers Add components to the breadboard as shown in the picture. Each shift register has a small notch on one end to identify pin 1. -In the picture, pin 1s are on the left end. +In the picture, pin 1s are on the left end, towards the controller. Shift registers are chained together by colored wires that lay flat on the breadboard. Each shift register has 8 parallel input pins, 4 on each side. @@ -32,17 +32,17 @@ A decoupling capacitor between the power and ground wires prevents power disturb Switches are connected to power (red bus) and shift register input pins (jumpers). -I apologize for not having a schematic. This table should help you figure out the pictures: +I apologize for not providing a schematic. This table should help you figure out the pictures: ``` 74HC165 left (lower half of breadboard) NAME PIN# DESCRIPTION TO TEENSY LC PIN# CHAIN SH/LD 1 shift or load input CS0 10 green wire CLK 2 clock input SCK0 13 yellow wire - D4 3 parallel input blue bus - D5 4 parallel input blue bus - D6 5 parallel input blue bus - D7 6 parallel input blue bus + D4 3 parallel input + D5 4 parallel input + D6 5 parallel input + D7 6 parallel input /QH 7 ~serial output GND 8 ground gnd blue bus @@ -50,10 +50,10 @@ GND 8 ground gnd blue bus NAME PIN# DESCRIPTION TO TEENSY LC PIN# CHAIN VCC 16 power pin 3.3V red wire CLK INH 15 clock inhibit blue bus - D3 14 parallel input blue bus - D2 13 parallel input blue bus - D1 12 parallel input blue bus - D0 11 parallel input blue bus + D3 14 parallel input + D2 13 parallel input + D1 12 parallel input + D0 11 parallel input SER 10 serial input blue wire to next QH QH 9 serial output MISO0 12 blue wire to previous SER @@ -62,20 +62,20 @@ SER 10 serial input blue wire to next QH Sketch for split keyboard with shift registers ---------------------------------------------- [keybrd_4b_split_keyboard_with_shift_registers.ino](keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino) is a simple sketch with two shift registers. -The sketch will run on the above breadboard keyboard. - -The sketch has code for both left and right matrix. -Notice that the left matrix is active low, while the right matrix is active high. +It will run on the above breadboard keyboard. Exercises --------- 1. Guess what happens if an unused input pin is not grounded? Try it. -2. Add a left matrix to Teensy. +2. Add a left matrix to the controller. There is room between Teensy and the shift registers for a 1-column matrix. The bus strips are occupied by the right keys, so use terminal strips instead. Other wise it is similar to the 2-column matrix in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md). + The sketch already has code for both left and right matrix. + Notice that the left matrix is active low, while the right matrix is active high. +
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. diff --git a/tutorials/tutorial_4c_split_keyboard_with_IOE.md b/tutorials/tutorial_4c_split_keyboard_with_IOE.md index 0c1298e..2faa291 100644 --- a/tutorials/tutorial_4c_split_keyboard_with_IOE.md +++ b/tutorials/tutorial_4c_split_keyboard_with_IOE.md @@ -13,10 +13,10 @@ Two rows (red buses) are connected to the I/O expander. The I/O expander is a MCP23S17. It has a small notch on one end, which identifies pin 1. -In the picture, pin 1 is on the right end. +In the picture, pin 1 is on the left end. The MCP23S17 communicates via SPI protocol, where Teensy LC is the master, and MCP23S17 is slave. -The Teensy LC and MCP23S17 are connected by 6 jumper wires: +The Teensy LC and MCP23S17 are connected via 6 jumper wires: |CONNECTION |Teensy LC|MCP23S17| |:------------------:|---------|--------|