add tutorial_7ab_mapping_layout_to_matix.md and mapping sketches
This commit is contained in:
parent
09641ec6ed
commit
726e666ebb
@ -21,7 +21,7 @@ Keybrd library class inheritance diagram
|
||||
|
||||
___ ScannerInterface ___
|
||||
/ | \
|
||||
Scanner_uC Scanner_IOE Scanner_ShiftRegsPISO
|
||||
Scanner_uC Scanner_IOE Scanner_ShiftRegsRead
|
||||
|
||||
|
||||
PortWriteInterface
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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** |
|
||||
|:------:|-------|-------|
|
||||
|
@ -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 <Code_Sc.h>
|
||||
#include <Row.h>
|
||||
#include <Scanner_uC.h>
|
||||
#include <ScanDelay.h>
|
||||
|
||||
// ============ 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();
|
||||
}
|
BIN
tutorials/keybrd_7b_mapping_multi-layer/back.JPG
Normal file
BIN
tutorials/keybrd_7b_mapping_multi-layer/back.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 KiB |
BIN
tutorials/keybrd_7b_mapping_multi-layer/crossed_columns.jpg
Normal file
BIN
tutorials/keybrd_7b_mapping_multi-layer/crossed_columns.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
BIN
tutorials/keybrd_7b_mapping_multi-layer/front.JPG
Normal file
BIN
tutorials/keybrd_7b_mapping_multi-layer/front.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 333 KiB |
@ -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 <Code_Sc.h>
|
||||
#include <LayerState.h>
|
||||
#include <Code_LayerHold.h>
|
||||
#include <Key_LayeredKeys.h>
|
||||
|
||||
//Matrix
|
||||
#include <Row.h>
|
||||
#include <Scanner_uC.h>
|
||||
#include <ScanDelay.h>
|
||||
|
||||
// ============ 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();
|
||||
}
|
@ -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:
|
||||
|
||||
@ -139,7 +141,7 @@ The top row is easily implemented in one layer group with duplicate keys filling
|
||||
| **1** | | | |
|
||||
|
||||
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.
|
||||
|
45
tutorials/tutorial_7ab_mapping_layout_to_matix.md
Normal file
45
tutorials/tutorial_7ab_mapping_layout_to_matix.md
Normal file
@ -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")
|
||||
|
||||
<br>
|
||||
<a rel="license" href="https://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">keybrd tutorial</span> by <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd" property="cc:attributionName" rel="cc:attributionURL">Wolfram Volpi</a> is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />Permissions beyond the scope of this license may be available at <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
Reference in New Issue
Block a user