rename layer to layerId
This commit is contained in:
parent
59e4f38e61
commit
f62d956918
@ -2,10 +2,10 @@
|
||||
|
||||
void Code_LayerHold::press()
|
||||
{
|
||||
refLayerState.hold(layer);
|
||||
refLayerState.hold(layerId);
|
||||
}
|
||||
|
||||
void Code_LayerHold::release()
|
||||
{
|
||||
refLayerState.unhold(layer);
|
||||
refLayerState.unhold(layerId);
|
||||
}
|
||||
|
@ -10,11 +10,11 @@
|
||||
class Code_LayerHold : public Code
|
||||
{
|
||||
private:
|
||||
const uint8_t layer;
|
||||
const uint8_t layerId;
|
||||
LayerState& refLayerState;
|
||||
public:
|
||||
Code_LayerHold(const uint8_t layer, LayerState& refLayerState)
|
||||
: layer(layer), refLayerState(refLayerState) {}
|
||||
Code_LayerHold(const uint8_t layerId, LayerState& refLayerState)
|
||||
: layerId(layerId), refLayerState(refLayerState) {}
|
||||
virtual void press();
|
||||
virtual void release();
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
void Code_LayerLock::press()
|
||||
{
|
||||
refLayerState.lock(layer);
|
||||
refLayerState.lock(layerId);
|
||||
}
|
||||
|
||||
void Code_LayerLock::release()
|
||||
|
@ -10,11 +10,11 @@
|
||||
class Code_LayerLock : public Code
|
||||
{
|
||||
private:
|
||||
const uint8_t layer;
|
||||
const uint8_t layerId;
|
||||
LayerState& refLayerState;
|
||||
public:
|
||||
Code_LayerLock(const uint8_t layer, LayerState& refLayerState)
|
||||
: layer(layer), refLayerState(refLayerState) {}
|
||||
Code_LayerLock(const uint8_t layerId, LayerState& refLayerState)
|
||||
: layerId(layerId), refLayerState(refLayerState) {}
|
||||
virtual void press();
|
||||
virtual void release();
|
||||
};
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
void Key_LayeredCodeSc::press()
|
||||
{
|
||||
layer = refLayerState.getActiveLayer();
|
||||
layerId = refLayerState.getActiveLayer();
|
||||
pressCode();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* Class Key_LayeredCodeSc is a 2-layer code, one object for each layer e.g.
|
||||
layer0: ms_up //mouse up
|
||||
layer1: KEY_UP //up arrow
|
||||
When the key is pressed, the active layer is retrieved from refLayerState,
|
||||
When the key is pressed, the active layerId is retrieved from refLayerState,
|
||||
and the object for the active layer is sent to USB.
|
||||
*/
|
||||
class Key_LayeredCodeSc : public Key_LayeredCodeScBase
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
void Key_LayeredCodeScBase::pressCode()
|
||||
{
|
||||
if (layer)
|
||||
if (layerId)
|
||||
{
|
||||
Keyboard.press(scancode1);
|
||||
}
|
||||
@ -14,7 +14,7 @@ void Key_LayeredCodeScBase::pressCode()
|
||||
|
||||
void Key_LayeredCodeScBase::release()
|
||||
{
|
||||
if (layer)
|
||||
if (layerId)
|
||||
{
|
||||
Keyboard.release(scancode1);
|
||||
}
|
||||
|
@ -4,11 +4,9 @@
|
||||
#include <inttypes.h>
|
||||
#include "Code.h"
|
||||
|
||||
/* Class Key_LayeredCodeScBase is a 2-layer code, with one object for each layer e.g.
|
||||
layer0: ms_up //mouse up
|
||||
layer1: KEY_UP //up arrow
|
||||
When the key is pressed, the active layer is retrieved from refLayerState,
|
||||
and the object for the active layer is sent to USB.
|
||||
/* Class Key_LayeredCodeScBase is an abstract base class for 2-layer keys:
|
||||
if layerId=0, send code0
|
||||
if layerId=1, send scancode1
|
||||
*/
|
||||
class Key_LayeredCodeScBase : public Code
|
||||
{
|
||||
@ -16,10 +14,10 @@ class Key_LayeredCodeScBase : public Code
|
||||
Code& refCode0;
|
||||
const uint16_t scancode1;
|
||||
protected:
|
||||
bool layer;
|
||||
bool layerId; //active layer when key was pressed, 0 or 1
|
||||
public:
|
||||
Key_LayeredCodeScBase(Code& refCode0, const uint16_t scancode1, uint8_t layer):
|
||||
refCode0(refCode0), scancode1(scancode1), layer(layer) { }
|
||||
Key_LayeredCodeScBase(Code& refCode0, const uint16_t scancode1, uint8_t layerId):
|
||||
refCode0(refCode0), scancode1(scancode1), layerId(layerId) { }
|
||||
virtual void press()=0;
|
||||
virtual void release();
|
||||
virtual void pressCode();
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
void Key_LayeredKeys::press()
|
||||
{
|
||||
layer = refLayerState.getActiveLayer();
|
||||
layerId = refLayerState.getActiveLayer();
|
||||
|
||||
ptrsKeys[layer]->press();
|
||||
ptrsKeys[layerId]->press();
|
||||
}
|
||||
|
||||
void Key_LayeredKeys::release()
|
||||
{
|
||||
ptrsKeys[layer]->release();
|
||||
ptrsKeys[layerId]->release();
|
||||
}
|
||||
|
@ -8,14 +8,14 @@
|
||||
/* Class Key_LayeredKeys contains an array of Key pointers, one pointer per layer.
|
||||
Codes are a kind of Key, so the Key pointers can point to Codes or Keys.
|
||||
|
||||
When the key is pressed, active layer is retreived from refLayerState and
|
||||
the Key object of the active layer is called.
|
||||
When the key is pressed, active layerId is retreived from refLayerState and
|
||||
the Key object of the active layerId is called.
|
||||
*/
|
||||
class Key_LayeredKeys : public Key
|
||||
{
|
||||
private:
|
||||
Key*const *const ptrsKeys; //array of Key pointers, one Key per layer
|
||||
uint8_t layer; //active layer when key was pressed
|
||||
uint8_t layerId; //active layer when key was pressed
|
||||
static LayerStateInterface& refLayerState;
|
||||
public:
|
||||
Key_LayeredKeys(Key* const ptrsKeys[]): ptrsKeys(ptrsKeys) {}
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
void Key_LayeredScSc::press()
|
||||
{
|
||||
layer = refLayerState.getActiveLayer();
|
||||
layerId = refLayerState.getActiveLayer();
|
||||
pressScancode();
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include <Key_LayeredScScBase.h>
|
||||
|
||||
/* Class Key_LayeredScSc is composed of two scancodes; "S" stands for Scancode.
|
||||
layer is retreived from refLayerState.
|
||||
when layer=0, press sends scancode0
|
||||
when layer=1, press sends scancode1
|
||||
layerId is retreived from refLayerState.
|
||||
when layerId=0, press sends scancode0
|
||||
when layerId=1, press sends scancode1
|
||||
*/
|
||||
class Key_LayeredScSc : public Key_LayeredScScBase
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
void Key_LayeredScScBase::pressScancode()
|
||||
{
|
||||
if (layer)
|
||||
if (layerId)
|
||||
{
|
||||
scancode = scancode1;
|
||||
}
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include <inttypes.h>
|
||||
#include "Code.h"
|
||||
|
||||
/* Class Key_LayeredScScBase is an abstract base class. It is composed of two scancodes:
|
||||
if layer=0, send scancode0
|
||||
if layer=1, send scancode1
|
||||
/* Class Key_LayeredScScBase is an abstract base class for 2-layer keys:
|
||||
if layerId=0, send scancode0
|
||||
if layerId=1, send scancode1
|
||||
*/
|
||||
class Key_LayeredScScBase : public Code
|
||||
{
|
||||
@ -15,10 +15,10 @@ class Key_LayeredScScBase : public Code
|
||||
const uint16_t scancode1;
|
||||
uint16_t scancode;
|
||||
protected:
|
||||
bool layer; //0 or 1
|
||||
bool layerId; //active layer when key was pressed, 0 or 1
|
||||
public:
|
||||
Key_LayeredScScBase(const uint16_t scancode0, const uint16_t scancode1):
|
||||
scancode0(scancode0), scancode1(scancode1), layer(0) { }
|
||||
scancode0(scancode0), scancode1(scancode1), layerId(0) { }
|
||||
virtual void press()=0;
|
||||
virtual void release();
|
||||
void pressScancode();
|
||||
|
@ -1,29 +1,29 @@
|
||||
#include "LayerState.h"
|
||||
|
||||
void LayerState::hold(const uint8_t layer)
|
||||
void LayerState::hold(const uint8_t layerId)
|
||||
{
|
||||
setActiveLayer(layer);
|
||||
setActiveLayer(layerId);
|
||||
}
|
||||
|
||||
void LayerState::unhold(const uint8_t layer)
|
||||
void LayerState::unhold(const uint8_t layerId)
|
||||
{
|
||||
if (layer == activeLayer);
|
||||
if (layerId == activeLayer);
|
||||
{
|
||||
setActiveLayer(lockedLayer);
|
||||
}
|
||||
}
|
||||
|
||||
void LayerState::lock(const uint8_t layer)
|
||||
void LayerState::lock(const uint8_t layerId)
|
||||
{
|
||||
setActiveLayer(layer);
|
||||
lockedLayer = layer;
|
||||
setActiveLayer(layerId);
|
||||
lockedLayer = layerId;
|
||||
}
|
||||
|
||||
/*Derived classes override setActiveLayer() to also set LED indicator lights e.g. LayerState_LED
|
||||
*/
|
||||
void LayerState::setActiveLayer(const uint8_t layer)
|
||||
void LayerState::setActiveLayer(const uint8_t layerId)
|
||||
{
|
||||
activeLayer = layer;
|
||||
activeLayer = layerId;
|
||||
}
|
||||
|
||||
uint8_t LayerState::getActiveLayer()
|
||||
|
@ -13,12 +13,12 @@ class LayerState : public LayerStateInterface
|
||||
protected:
|
||||
uint8_t activeLayer; //currently active layer
|
||||
uint8_t lockedLayer; //most recently pressed lock layer
|
||||
virtual void setActiveLayer(const uint8_t layer);
|
||||
virtual void setActiveLayer(const uint8_t layerId);
|
||||
public:
|
||||
LayerState() : activeLayer(0), lockedLayer(0) {}
|
||||
virtual void hold(uint8_t layer); //set activeLayer
|
||||
virtual void unhold(const uint8_t layer); //restore activeLayer to lockedLayer
|
||||
virtual void lock(uint8_t layer); //set activeLayer and lock it
|
||||
virtual void hold(uint8_t layerId); //set activeLayer
|
||||
virtual void unhold(const uint8_t layerId); //restore activeLayer to lockedLayer
|
||||
virtual void lock(uint8_t layerId); //set activeLayer and lock it
|
||||
virtual uint8_t getActiveLayer();
|
||||
};
|
||||
#endif
|
||||
|
@ -5,9 +5,9 @@ void LayerState_LED::begin()
|
||||
ptrsLEDs[getActiveLayer()]->on();
|
||||
}
|
||||
|
||||
void LayerState_LED::setActiveLayer(const uint8_t layer)
|
||||
void LayerState_LED::setActiveLayer(const uint8_t layerId)
|
||||
{
|
||||
ptrsLEDs[activeLayer]->off();
|
||||
activeLayer = layer;
|
||||
activeLayer = layerId;
|
||||
ptrsLEDs[activeLayer]->on();
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ begin() should be called once to turn on LED for initial active layer.
|
||||
class LayerState_LED : public LayerState
|
||||
{
|
||||
private:
|
||||
LED*const *const ptrsLEDs; //array of LEDs, where layer id is array index
|
||||
virtual void setActiveLayer(const uint8_t layer); //set active layer and turn on it's LED
|
||||
LED*const *const ptrsLEDs; //array of LEDs, where layerId is array index
|
||||
virtual void setActiveLayer(const uint8_t layerId);//set active layerId and turn on it's LED
|
||||
public:
|
||||
LayerState_LED(LED*const ptrsLEDs[]): ptrsLEDs(ptrsLEDs) {}
|
||||
void begin();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* keybrd_3_multi-layer_annotated.ino
|
||||
/* keybrd_3a_multi-layerHold.ino
|
||||
|
||||
This sketch:
|
||||
is firmware for a simple 2-layer keyboard
|
||||
@ -40,7 +40,7 @@ Scanner_uC scanner(LOW, readPins, readPinCount);
|
||||
The CODES section instantiates six codes, one for each item in the layout.
|
||||
*/
|
||||
/* ---------------- LAYER CODE -----------------
|
||||
enum assigns id numbers to the layers.
|
||||
enum assigns layerId numbers to the layers.
|
||||
*/
|
||||
enum layers { NORMAL, FN };
|
||||
|
||||
@ -49,9 +49,9 @@ enum layers { NORMAL, FN };
|
||||
LayerState layerState;
|
||||
|
||||
/*
|
||||
NORMAL=0 and FN=1. LayerState's default layer id is 0.
|
||||
NORMAL=0 and FN=1. LayerState's default layerId is 0.
|
||||
The Code_LayerHold constructor has two parameters:
|
||||
1) the layer that will be active while the key is held down
|
||||
1) the layerId that will be active while the key is held down
|
||||
2) a LayerState that will keep track of the active layer
|
||||
When l_fn is pressed, it tells layerState to change the active layer to 1.
|
||||
When l_fn is released, it tells layerState that layer 1 is released, and layerState restores the default layer.
|
||||
@ -78,7 +78,7 @@ Key* const ptrsCodes_11[] = { &s_b, &s_2 };
|
||||
Key_LayeredKeys k_11(ptrsCodes_11);
|
||||
|
||||
/* Key_LayeredKeys has a reference to layerState.
|
||||
Thus Key_LayeredKeys can call layerState to get the active layer id.
|
||||
Thus Key_LayeredKeys can call layerState to get the active layerId.
|
||||
*/
|
||||
LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;
|
||||
|
@ -0,0 +1,129 @@
|
||||
/* keybrd_3b_layerLock.ino
|
||||
|
||||
This sketch:
|
||||
is firmware for a simple 2-layer keyboard
|
||||
runs on the first two rows and columns of a breadboard keyboard
|
||||
|
||||
| Layout | **0** | **1** |
|
||||
|:------:|:-----:|:-----:|
|
||||
| **0** | a [ | b ] |
|
||||
| **1** |normal | sym |
|
||||
|
||||
normal layer keys are a b c
|
||||
sym layer keys are brackets [ ] and num
|
||||
num layer keys are 6 7
|
||||
The num layer key is located on the sym layer
|
||||
num layer is active while holding sym+num
|
||||
|
||||
Each cell in the table's body represents a key.
|
||||
The layered keys in column 1 have two layers; one character for each layer.
|
||||
Letters 'a' and 'b' are on the normal layer. Numbers '1' and '2' are on the fn layer.
|
||||
Holding the fn key down makes it the active layer. Releasing the fn key restores the normal layer.
|
||||
*/
|
||||
// ################## GLOBAL ###################
|
||||
// ================= INCLUDES ==================
|
||||
//Keys
|
||||
#include <Code_Sc.h>
|
||||
//#include <Code_ScS.h>
|
||||
//#include <Code_Null.h>
|
||||
#include <LayerState.h>
|
||||
#include <Code_LayerLock.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[] = {14, 15};
|
||||
uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
Scanner_uC scanner(LOW, readPins, readPinCount);
|
||||
|
||||
/* =================== CODES ===================
|
||||
The CODES section instantiates six codes, one for each item in the layout.
|
||||
*/
|
||||
/* ---------------- LAYER CODE -----------------
|
||||
enum assigns layerId numbers to the layers.
|
||||
*/
|
||||
enum layers { NORMAL, SYM };
|
||||
|
||||
/* layerState keeps track of the active layer.
|
||||
*/
|
||||
LayerState layerState;
|
||||
|
||||
/*
|
||||
NORMAL=0 and FN=1. LayerState's default layerId is 0.
|
||||
The Code_LayerHold constructor has two parameters:
|
||||
1) the layerId that will be active while the key is held down
|
||||
2) a LayerState that will keep track of the active layer
|
||||
When l_fn is pressed, it tells layerState to change the active layer to 1.
|
||||
When l_fn is released, it tells layerState that layer 1 is released, and layerState restores the default layer.
|
||||
*/
|
||||
Code_LayerLock l_normal(NORMAL, layerState);
|
||||
Code_LayerLock l_sym(SYM, layerState);
|
||||
|
||||
// ---------------- SCAN CODES -----------------
|
||||
Code_Sc s_a(KEY_A);
|
||||
Code_Sc s_b(KEY_B);
|
||||
|
||||
Code_Sc s_leftBracket(KEY_LEFT_BRACE); //[ ("brace" means curly bracket {})
|
||||
Code_Sc s_rightBracket(KEY_RIGHT_BRACE); //]
|
||||
|
||||
//Code_Null code_null;
|
||||
|
||||
/* =================== KEYS ====================
|
||||
Here we pack Codes into keys.
|
||||
The Key_LayeredKeys constructor takes one array of Code pointers - one Code object per layer.
|
||||
|
||||
The Key object names in this sketch start with a "k_" followed by row-column coordinates.
|
||||
*/
|
||||
Key* const ptrsCodes_00[] = { &s_a, &s_leftBracket };
|
||||
Key_LayeredKeys k_00(ptrsCodes_00);
|
||||
|
||||
Key* const ptrsCodes_01[] = { &s_b, &s_rightBracket };
|
||||
Key_LayeredKeys k_01(ptrsCodes_01);
|
||||
|
||||
/* Key_LayeredKeys has a reference to layerState.
|
||||
Thus Key_LayeredKeys can call layerState to get the active layerId.
|
||||
*/
|
||||
LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;
|
||||
|
||||
/* HOW LAYERED OBJECTS WORK
|
||||
When a Key_LayeredKeys object is pressed, it gets the active layer id from layerState.
|
||||
It then uses the layer id as an array index to call the Code of the active layer.
|
||||
The Code object then sends its scancode over USB.
|
||||
*/
|
||||
|
||||
/* =================== ROWS ====================
|
||||
Here we pack Key pointers into row objects.
|
||||
|
||||
Codes are a kind of Key that only have one layer.
|
||||
So rows can contain a mix of codes and multi-layered keys.
|
||||
Arrays ptrsKeys_0[] and ptrsKeys_1[] contain both Code pointers and Key pointers.
|
||||
*/
|
||||
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);
|
||||
|
||||
Key* const ptrsKeys_1[] = { &l_normal, &l_sym };
|
||||
uint8_t keyCount_1 = sizeof(ptrsKeys_1)/sizeof(*ptrsKeys_1);
|
||||
Row row_1(scanner, 1, ptrsKeys_1, keyCount_1);
|
||||
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
||||
{
|
||||
Keyboard.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
row_0.process();
|
||||
row_1.process();
|
||||
scanDelay.delay();
|
||||
}
|
135
tutorials/keybrd_3c_sublayerNull/keybrd_3c_sublayerNull.ino
Normal file
135
tutorials/keybrd_3c_sublayerNull/keybrd_3c_sublayerNull.ino
Normal file
@ -0,0 +1,135 @@
|
||||
/* keybrd_3c_sublayerNull.ino
|
||||
|
||||
This sketch:
|
||||
is firmware for a simple 2-layer keyboard
|
||||
runs on the first two rows and columns of a breadboard keyboard
|
||||
|
||||
| Layout | **0** | **1** | **2** |
|
||||
|:------:|:-----:|:-----:|:-----:|
|
||||
| **0** | a - 1 | b = | c Num |
|
||||
| **1** |Normal | Sym | Enter |
|
||||
|
||||
normal layer keys are a b c
|
||||
sym layer keys are brackets [ ] and num
|
||||
num layer keys are 6 7
|
||||
The num layer key is located on the sym layer
|
||||
num layer is active while holding sym+num
|
||||
|
||||
Each cell in the table's body represents a key.
|
||||
The layered keys in column 1 have two layers; one character for each layer.
|
||||
Letters 'a' and 'b' are on the normal layer. Numbers '1' and '2' are on the fn layer.
|
||||
Holding the fn key down makes it the active layer. Releasing the fn key restores the normal layer.
|
||||
*/
|
||||
// ################## GLOBAL ###################
|
||||
// ================= INCLUDES ==================
|
||||
//Keys
|
||||
#include <Code_Sc.h>
|
||||
#include <Code_Null.h>
|
||||
#include <LayerState.h>
|
||||
#include <Code_LayerLock.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[] = {14, 15, 16};
|
||||
uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
Scanner_uC scanner(LOW, readPins, readPinCount);
|
||||
|
||||
/* =================== CODES ===================
|
||||
The CODES section instantiates six codes, one for each item in the layout.
|
||||
*/
|
||||
/* ---------------- LAYER CODE -----------------
|
||||
enum assigns layerId numbers to the layers.
|
||||
*/
|
||||
enum layers { NORMAL, SYM, NUM };
|
||||
|
||||
/* layerState keeps track of the active layer.
|
||||
*/
|
||||
LayerState layerState;
|
||||
|
||||
/*
|
||||
NORMAL=0 and FN=1. LayerState's default layerId is 0.
|
||||
The Code_LayerHold constructor has two parameters:
|
||||
1) the layerId that will be active while the key is held down
|
||||
2) a LayerState that will keep track of the active layer
|
||||
When l_fn is pressed, it tells layerState to change the active layer to 1.
|
||||
When l_fn is released, it tells layerState that layer 1 is released, and layerState restores the default layer.
|
||||
*/
|
||||
Code_LayerLock l_normal(NORMAL, layerState);
|
||||
Code_LayerLock l_sym(SYM, layerState);
|
||||
Code_LayerHold l_num(NUM, layerState);
|
||||
|
||||
// ---------------- SCAN CODES -----------------
|
||||
Code_Sc s_a(KEY_A);
|
||||
Code_Sc s_b(KEY_B);
|
||||
Code_Sc s_c(KEY_C);
|
||||
|
||||
Code_Sc s_minus(KEY_MINUS);
|
||||
Code_Sc s_equal(KEY_EQUAL);
|
||||
Code_Sc s_enter(KEY_ENTER);
|
||||
|
||||
Code_Sc s_1(KEY_1);
|
||||
Code_Null code_null;
|
||||
|
||||
/* =================== KEYS ====================
|
||||
Here we pack Codes into keys.
|
||||
The Key_LayeredKeys constructor takes one array of Code pointers - one Code object per layer.
|
||||
|
||||
The Key object names in this sketch start with a "k_" followed by row-column coordinates.
|
||||
*/
|
||||
Key* const ptrsCodes_00[] = { &s_a, &s_minus, &s_1 };
|
||||
Key_LayeredKeys k_00(ptrsCodes_00);
|
||||
|
||||
Key* const ptrsCodes_01[] = { &s_b, &s_equal, &s_equal };
|
||||
Key_LayeredKeys k_01(ptrsCodes_01);
|
||||
|
||||
Key* const ptrsCodes_02[] = { &s_c, &l_num, &code_null };
|
||||
Key_LayeredKeys k_02(ptrsCodes_02);
|
||||
|
||||
/* Key_LayeredKeys has a reference to layerState.
|
||||
Thus Key_LayeredKeys can call layerState to get the active layerId.
|
||||
*/
|
||||
LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;
|
||||
|
||||
/* HOW LAYERED OBJECTS WORK
|
||||
When a Key_LayeredKeys object is pressed, it gets the active layer id from layerState.
|
||||
It then uses the layer id as an array index to call the Code of the active layer.
|
||||
The Code object then sends its scancode over USB.
|
||||
*/
|
||||
|
||||
/* =================== ROWS ====================
|
||||
Here we pack Key pointers into row objects.
|
||||
|
||||
Codes are a kind of Key that only have one layer.
|
||||
So rows can contain a mix of codes and multi-layered keys.
|
||||
Arrays ptrsKeys_0[] and ptrsKeys_1[] contain both Code pointers and Key pointers.
|
||||
*/
|
||||
Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02 };
|
||||
uint8_t keyCount_0 = sizeof(ptrsKeys_0)/sizeof(*ptrsKeys_0);
|
||||
Row row_0(scanner, 0, ptrsKeys_0, keyCount_0);
|
||||
|
||||
Key* const ptrsKeys_1[] = { &l_normal, &l_sym, &s_enter };
|
||||
uint8_t keyCount_1 = sizeof(ptrsKeys_1)/sizeof(*ptrsKeys_1);
|
||||
Row row_1(scanner, 1, ptrsKeys_1, keyCount_1);
|
||||
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
||||
{
|
||||
Keyboard.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
row_0.process();
|
||||
row_1.process();
|
||||
scanDelay.delay();
|
||||
}
|
142
tutorials/keybrd_3d_sublayerNested/keybrd_3d_sublayerNested.ino
Normal file
142
tutorials/keybrd_3d_sublayerNested/keybrd_3d_sublayerNested.ino
Normal file
@ -0,0 +1,142 @@
|
||||
/* keybrd_3d_sublayerNested.ino
|
||||
|
||||
This sketch:
|
||||
is firmware for a simple 2-layer keyboard
|
||||
runs on the first two rows and columns of a breadboard keyboard
|
||||
|
||||
| Layout | **0** | **1** | **2** |
|
||||
|:------:|:-----:|:-----:|:-----:|
|
||||
| **0** | a - 1 | b = | c Num |
|
||||
| **1** |Normal | Sym | Enter |
|
||||
|
||||
normal layer keys are a b c
|
||||
sym layer keys are brackets [ ] and num
|
||||
num layer keys are 6 7
|
||||
The num layer key is located on the sym layer
|
||||
num layer is active while holding sym+num
|
||||
|
||||
Each cell in the table's body represents a key.
|
||||
The layered keys in column 1 have two layers; one character for each layer.
|
||||
Letters 'a' and 'b' are on the normal layer. Numbers '1' and '2' are on the fn layer.
|
||||
Holding the fn key down makes it the active layer. Releasing the fn key restores the normal layer.
|
||||
*/
|
||||
// ################## GLOBAL ###################
|
||||
// ================= INCLUDES ==================
|
||||
//Keys
|
||||
#include <Code_Sc.h>
|
||||
#include <Code_Null.h>
|
||||
#include <LayerState.h>
|
||||
#include <Code_LayerLock.h>
|
||||
#include <Code_LayerHold.h>
|
||||
#include <Key_LayeredKeys.h>
|
||||
#include <Key_LayeredScSc.h>
|
||||
|
||||
//Matrix
|
||||
#include <Row.h>
|
||||
#include <Scanner_uC.h>
|
||||
#include <ScanDelay.h>
|
||||
|
||||
// ============ SPEED CONFIGURATION ============
|
||||
ScanDelay scanDelay(9000);
|
||||
|
||||
// ================== SCANNER ==================
|
||||
uint8_t readPins[] = {14, 15, 16};
|
||||
uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
Scanner_uC scanner(LOW, readPins, readPinCount);
|
||||
|
||||
/* =================== CODES ===================
|
||||
The CODES section instantiates six codes, one for each item in the layout.
|
||||
*/
|
||||
/* ---------------- LAYER CODE -----------------
|
||||
enum assigns layerId numbers to the layers.
|
||||
*/
|
||||
enum layers { NORMAL, SYM };
|
||||
|
||||
/* layerState keeps track of the active layer.
|
||||
*/
|
||||
LayerState layerState;
|
||||
|
||||
LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;
|
||||
/*
|
||||
NORMAL=0 and FN=1. LayerState's default layerId is 0.
|
||||
The Code_LayerHold constructor has two parameters:
|
||||
1) the layerId that will be active while the key is held down
|
||||
2) a LayerState that will keep track of the active layer
|
||||
When l_fn is pressed, it tells layerState to change the active layer to 1.
|
||||
When l_fn is released, it tells layerState that layer 1 is released, and layerState restores the default layer.
|
||||
*/
|
||||
Code_LayerLock l_normal(NORMAL, layerState);
|
||||
Code_LayerLock l_sym(SYM, layerState);
|
||||
|
||||
//sublayer
|
||||
enum subLayers { SUBSYM, SUBNUM };
|
||||
|
||||
LayerState sublayerState;
|
||||
|
||||
Code_LayerHold l_num(SUBNUM, sublayerState);
|
||||
|
||||
LayerStateInterface& Key_LayeredScSc::refLayerState = sublayerState;
|
||||
|
||||
// ---------------- SCAN CODES -----------------
|
||||
Code_Sc s_a(KEY_A);
|
||||
Code_Sc s_b(KEY_B);
|
||||
Code_Sc s_c(KEY_C);
|
||||
|
||||
Code_Sc s_minus(KEY_MINUS);
|
||||
Code_Sc s_equal(KEY_EQUAL);
|
||||
Code_Sc s_enter(KEY_ENTER);
|
||||
|
||||
Code_Sc s_1(KEY_1);
|
||||
Code_Null code_null;
|
||||
|
||||
/* =================== KEYS ====================
|
||||
Here we pack Codes into keys.
|
||||
The Key_LayeredKeys constructor takes one array of Code pointers - one Code object per layer.
|
||||
|
||||
The Key object names in this sketch start with a "k_" followed by row-column coordinates.
|
||||
*/
|
||||
|
||||
Key_LayeredScSc sub_00(KEY_MINUS, KEY_1);
|
||||
Key* const ptrsCodes_00[] = { &s_a, &sub_00 };
|
||||
Key_LayeredKeys k_00(ptrsCodes_00);
|
||||
|
||||
Key* const ptrsCodes_01[] = { &s_b, &s_equal };
|
||||
Key_LayeredKeys k_01(ptrsCodes_01);
|
||||
|
||||
Key* const ptrsCodes_02[] = { &s_c, &l_num };
|
||||
Key_LayeredKeys k_02(ptrsCodes_02);
|
||||
|
||||
/* HOW LAYERED OBJECTS WORK
|
||||
When a Key_LayeredKeys object is pressed, it gets the active layer id from layerState.
|
||||
It then uses the layer id as an array index to call the Code of the active layer.
|
||||
The Code object then sends its scancode over USB.
|
||||
*/
|
||||
|
||||
/* =================== ROWS ====================
|
||||
Here we pack Key pointers into row objects.
|
||||
|
||||
Codes are a kind of Key that only have one layer.
|
||||
So rows can contain a mix of codes and multi-layered keys.
|
||||
Arrays ptrsKeys_0[] and ptrsKeys_1[] contain both Code pointers and Key pointers.
|
||||
*/
|
||||
Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02 };
|
||||
uint8_t keyCount_0 = sizeof(ptrsKeys_0)/sizeof(*ptrsKeys_0);
|
||||
Row row_0(scanner, 0, ptrsKeys_0, keyCount_0);
|
||||
|
||||
Key* const ptrsKeys_1[] = { &l_normal, &l_sym, &s_enter };
|
||||
uint8_t keyCount_1 = sizeof(ptrsKeys_1)/sizeof(*ptrsKeys_1);
|
||||
Row row_1(scanner, 1, ptrsKeys_1, keyCount_1);
|
||||
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
||||
{
|
||||
Keyboard.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
row_0.process();
|
||||
row_1.process();
|
||||
scanDelay.delay();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* keybrd_3_autoShift_annotated.ino
|
||||
/* keybrd_3b_autoShift.ino
|
||||
|
||||
This sketch:
|
||||
is a simple 2-layer keyboard with AutoShift
|
||||
@ -25,19 +25,18 @@ Holding the fn key down makes it the active layer. Releasing the fn key restore
|
||||
#include <Key_LayeredKeys.h>
|
||||
|
||||
//Matrix
|
||||
#include <Row_uC.h>
|
||||
#include <Row.h>
|
||||
#include <Scanner_uC.h>
|
||||
#include <ScanDelay.h>
|
||||
|
||||
// ============ SPEED CONFIGURATION ============
|
||||
ScanDelay scanDelay(9000);
|
||||
|
||||
// ================ ACTIVE STATE ===============
|
||||
const bool Scanner_uC::STROBE_ON = LOW;
|
||||
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||
|
||||
// =================== PINS ====================
|
||||
// ================== SCANNER ==================
|
||||
uint8_t readPins[] = {14, 15};
|
||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
Scanner_uC scanner(LOW, readPins, readPinCount);
|
||||
|
||||
// =================== CODES ===================
|
||||
// ---------------- LAYER CODE -----------------
|
||||
@ -101,10 +100,14 @@ LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;
|
||||
|
||||
// =================== ROWS ====================
|
||||
Key* const ptrsKeys_0[] = { &s_shift, &k_01 };
|
||||
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||
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 };
|
||||
Row_uC row_1(1, readPins, READ_PIN_COUNT, ptrsKeys_1);
|
||||
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);
|
||||
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
@ -1,7 +1,7 @@
|
||||
Tutorial 2 - single-layer keyboard
|
||||
=======================================
|
||||
The easiest way to learn the keyboard library is to read some simple sketches.
|
||||
[keybrd_2_single-layer_annotated.ino](keybrd_2_single-layer_annotated/keybrd_2_single-layer_annotated.ino) is a simple sketch with annotations that explain how a keybrd sketch works.
|
||||
[keybrd_2_single-layer.ino](keybrd_2_single-layer/keybrd_2_single-layer.ino) is a simple sketch with annotations that explain how a keybrd sketch works.
|
||||
The sketch will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
||||
|
||||
After reading the sketch you will be able to modify it to suite your own single-layer keyboard design.
|
||||
|
@ -35,61 +35,60 @@ Pseudo code for simple layer scheme
|
||||
The following pseudo code is of three keybrd library classes.
|
||||
It has just enough detail to show the internal workings of layer schemes.
|
||||
|
||||
**Code_Layer** objects change the active layer when pressed.
|
||||
The "layer" variable is a layer id number.
|
||||
**Code_Layer** objects change the active layer.
|
||||
When a Code_Layer object is pressed, it tells LayerState to update the active layer.
|
||||
```
|
||||
class Code_Layer
|
||||
{
|
||||
int layer;
|
||||
int layerId;
|
||||
LayerState& refLayerState;
|
||||
press() { refLayerState.setActiveLayer(layer); }
|
||||
press() { refLayerState.setActiveLayer(layerId); }
|
||||
};
|
||||
```
|
||||
|
||||
**LayerState** objects keep track of the active layer.
|
||||
**LayerState** objects keep track of the activeLayer.
|
||||
A LayerState's activeLayer is always up to date.
|
||||
```
|
||||
class LayerState
|
||||
{
|
||||
int activeLayer;
|
||||
setActiveLayer(int layer) { activeLayer = layer; }
|
||||
setActiveLayer(int layerId) { activeLayer = layerId; }
|
||||
getActiveLayer() { return activeLayer; }
|
||||
};
|
||||
```
|
||||
|
||||
**Key_LayeredKeys** objects contain an array of keys, one key for each layer.
|
||||
Key_LayeredKeys objects use layer ids as Key_LayeredKeys indexes.
|
||||
When a Key_LayeredKeys object is pressed, it gets the active layer from LayerState, and sends the corresponding key.
|
||||
Key_LayeredKeys objects use layerIds as Key_LayeredKeys indexes.
|
||||
When a Key_LayeredKeys object is pressed, it gets the active layerId from LayerState, and sends the corresponding key.
|
||||
```
|
||||
class Key_LayeredKeys
|
||||
{
|
||||
Key** ptrsKeys; //array of Key pointers, one Key pointer per layer
|
||||
LayerState& refLayerState;
|
||||
press() { layer = refLayerState.getActiveLayer();
|
||||
ptrsKeys[layer]->press(); }
|
||||
press() { layerId = refLayerState.getActiveLayer();
|
||||
ptrsKeys[layerId]->press(); }
|
||||
};
|
||||
```
|
||||
|
||||
Dependency diagram
|
||||
```
|
||||
+------------+
|
||||
| Code_Layer |
|
||||
+------------+
|
||||
|
|
||||
|setActiveLayer()
|
||||
|
|
||||
v
|
||||
+------------+
|
||||
| LayerState |
|
||||
+------------+
|
||||
^
|
||||
|
|
||||
|getActiveLayer()
|
||||
|
|
||||
+----------------------+
|
||||
| Key_LayeredKeys |
|
||||
+----------------------+
|
||||
+------------+
|
||||
| Code_Layer |
|
||||
+------------+
|
||||
|
|
||||
|setActiveLayer()
|
||||
|
|
||||
v
|
||||
+------------+
|
||||
| LayerState |
|
||||
+------------+
|
||||
^
|
||||
|
|
||||
|getActiveLayer()
|
||||
|
|
||||
+-----------------+
|
||||
| Key_LayeredKeys |
|
||||
+-----------------+
|
||||
```
|
||||
Layer-scheme classes
|
||||
--------------------
|
||||
@ -124,7 +123,7 @@ Example single-layer Code classes include:
|
||||
|
||||
Exercises
|
||||
---------
|
||||
1) Modify the keybrd_3_multi-layer.ino sketch to use two Code_LayerLock objects.
|
||||
1) Modify the keybrd_3a_multi-layer.ino sketch to use two Code_LayerLock objects.
|
||||
|
||||
| Layout | **0** | **1** |
|
||||
|:------:|:------:|:------:|
|
||||
|
@ -10,7 +10,7 @@ Two keybrd classes use AutoShift:
|
||||
* Code_ScS
|
||||
* Code_ScNS
|
||||
|
||||
The [keybrd_3_autoShift.ino](keybrd_3_autoShift/keybrd_3_autoShift.ino) sketch explains the AutoShift feature.
|
||||
The [keybrd_3b_autoShift.ino](keybrd_3b_autoShift/keybrd_3b_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,7 +18,7 @@ After reading the sketch you too will be able to automatically shifted character
|
||||
|
||||
Exercises
|
||||
---------
|
||||
1) Modify the keybrd_3_autoShift_annotated sketch to make a 3-layer keyboard with a default layer and two Code_LayerHold objects.
|
||||
1) Modify the keybrd_3b_autoShift sketch to make a 3-layer keyboard with a default layer and two Code_LayerHold objects.
|
||||
|
||||
| Layout | **0** | **1** |
|
||||
|:------:|:-----:|:-----:|
|
||||
|
Reference in New Issue
Block a user