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 ___
|
___ ScannerInterface ___
|
||||||
/ | \
|
/ | \
|
||||||
Scanner_uC Scanner_IOE Scanner_ShiftRegsPISO
|
Scanner_uC Scanner_IOE Scanner_ShiftRegsRead
|
||||||
|
|
||||||
|
|
||||||
PortWriteInterface
|
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).
|
(Scanner_ShiftRegs74HC165 and Scanner_Port classes is similar).
|
||||||
|
|
||||||
For active low:
|
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:
|
* Instantiate the scanner in the sketch with activeState LOW, like this:
|
||||||
```
|
```
|
||||||
Scanner_uC scanner(LOW, readPins, readPinCount);
|
Scanner_uC scanner(LOW, readPins, readPinCount);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "Debouncer_Not.h"
|
#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),
|
* if strobe pin is on uC (strobe for Scanner_uC or Scanner_ShiftRegsRead),
|
||||||
then strobePin is an Arduino pin number connected to this row.
|
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,
|
* if strobe pin is on I/O expander (strobe for Scanner_IOE), then strobePin is bit pattern,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This sketch:
|
This sketch:
|
||||||
is firmware for a simple 2-layer keyboard
|
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** |
|
| 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
|
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.
|
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.
|
Letters 'a' 'b' 'c' are on the Alpha layer.
|
||||||
|
|
||||||
Pressing the Sym-layer key locks the Sym 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.
|
If the keyboard is locked on the Sym layer, holding Num down makes it the active layer.
|
||||||
Number '1' is on the Num sublayer.
|
Number '1' is on the Num sublayer.
|
||||||
Releasing the Num key makes the locked layer active.
|
Releasing the Num key makes the locked layer active.
|
||||||
|
|
||||||
|
Sublayers are very flexible.
|
||||||
Example sketches 3c, 3d, and 3e implement the above layout.
|
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:
|
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
|
| **0** | a - 1 | b = = | c Ent Ent | layer group with three layers: Alpha Sym Num
|
||||||
| **1** | | | |
|
| **1** | | | |
|
||||||
|
|
||||||
Complex layerschemes
|
Complex layer schemes
|
||||||
--------------------
|
---------------------
|
||||||
The basic LayerState class used in the tutorials is sufficient for implementing many 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.
|
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.
|
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