move Debug variables to static
66
CONTRIBUTING.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
Contributing to keybrd
|
||||||
|
======================
|
||||||
|
We'd love for you to contribute to the keybrd project.
|
||||||
|
|
||||||
|
Improvement suggestions
|
||||||
|
-----------------------
|
||||||
|
We need to know what improvements to the keybrd library would help you create your keyboard design.
|
||||||
|
Before requesting an improvement, please check [planned_features list](doc/planned_features.md)
|
||||||
|
|
||||||
|
Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keybrd/issues).
|
||||||
|
* The issue title should start with "suggestion:" followed by a descriptive title
|
||||||
|
* Provide a use case
|
||||||
|
* Explain why the improvement is useful
|
||||||
|
* Site other product examples where this improvement exists
|
||||||
|
|
||||||
|
Bug reports
|
||||||
|
-----------
|
||||||
|
A bug report is the first step in making the keybrd library work the way it's supposed to work.
|
||||||
|
|
||||||
|
Please provide enough information so we can reproduce the bug behaviour!
|
||||||
|
* Complete sketch (copy & paste, attachment, or a link to the code)
|
||||||
|
* Screenshot or the exact text of error messages
|
||||||
|
* Describe the observed behavior and explain which behavior you expected
|
||||||
|
* Which controller your using
|
||||||
|
* Wiring details - how exactly have you connected the hardware (a photo's worth 1000 words)
|
||||||
|
* Arduino IDE version number
|
||||||
|
* keybrd library version number
|
||||||
|
* Any other information needed to reproduce the problem...
|
||||||
|
|
||||||
|
Code contributions
|
||||||
|
------------------
|
||||||
|
Unsure where to begin contributing to keybrd code?
|
||||||
|
You can start by looking through the improvement suggestions, bug reports, and [planned_features](doc/planned_features.md).
|
||||||
|
|
||||||
|
Git commit message style guide:
|
||||||
|
* Limit the first line to 72 characters summary
|
||||||
|
* Second line should be empty, followed by body of the commit message
|
||||||
|
* Use the imperative present tense (use "Add feature", not "Added feature", not "Adds feature")
|
||||||
|
* Reference an improvement suggestion or bug report
|
||||||
|
* Sometimes a bulleted list is a good format to convey the changes of a commit
|
||||||
|
|
||||||
|
User contributions
|
||||||
|
------------------
|
||||||
|
Any project requires various kinds of contributions to succeed.
|
||||||
|
A thriving project is more than a pile of code.
|
||||||
|
It's the packaging, explanation, outreach, and empathy of maintainers that make a good project great.
|
||||||
|
|
||||||
|
User Contributions can be in the form of:
|
||||||
|
* Blog - You have a fresh perspective of how the keybrd library works.
|
||||||
|
This makes you the perfect person to write an introductory blog explaining the project.
|
||||||
|
A healthy project needs the perspective of many people.
|
||||||
|
* Documentation - Suggest a clarification, simplification, correction, or other improvement.
|
||||||
|
We need the perspective of people new to the project to see these things.
|
||||||
|
Sometimes just changing a word or two makes a big difference.
|
||||||
|
* [What we currently need from keybrd users](todo geekhack) lists tasks for the keybrd project's current stage of development.
|
||||||
|
|
||||||
|
Text file documentation style guide:
|
||||||
|
* Use Markdown with a .md suffix.
|
||||||
|
* "Underline" first-level (=) and second-level (-) headings (because easier to read in plain text).
|
||||||
|
* Capitalize first letter of headings (no extra capitalization in headings).
|
||||||
|
|
||||||
|
Submitting a Pull Request
|
||||||
|
-------------------------
|
||||||
|
Pull Request is the preferred way to contribute code and documentation.
|
||||||
|
If you want to contribute some other way, please make a request in the [GitHub issues](https://github.com/wolfv6/Keybrd/issues).
|
||||||
|
|
43
README.md
@ -1,10 +1,12 @@
|
|||||||
keybrd library for creating keyboard firmware
|
keybrd library for creating keyboard firmware
|
||||||
====================================================
|
=============================================
|
||||||
keybrd library is an open source library for creating custom-keyboard firmware.
|
keybrd library is an open source library for creating custom-keyboard firmware.
|
||||||
|
The keybrd library allows keyboard designers to develop and publish their firmware simply as possible.
|
||||||
The resulting keyboard firmware is compatible with standard USB keyboard drivers.
|
The resulting keyboard firmware is compatible with standard USB keyboard drivers.
|
||||||
|
|
||||||
keybrd library can support any keyboard configuration:
|
keybrd library can support any keyboard configuration:
|
||||||
* one-piece
|
* one-piece
|
||||||
|
* split with shift registers
|
||||||
* split with I/O expander
|
* split with I/O expander
|
||||||
* single-layer
|
* single-layer
|
||||||
* multiple-layer
|
* multiple-layer
|
||||||
@ -16,35 +18,40 @@ Multiple-layer keyboards can write symbols without using the shift key:
|
|||||||
keybrd library leverages the Arduino environment to create keyboard firmware.
|
keybrd library leverages the Arduino environment to create keyboard firmware.
|
||||||
The Arduino development environment is free, and easy for novice programmers to setup and learn.
|
The Arduino development environment is free, and easy for novice programmers to setup and learn.
|
||||||
|
|
||||||
The keybrd library has been tested on the Teensy 2.0 microcontroller, MCP23018 I/O expander, and PCA9655E I/O expander.
|
The keybrd library has been tested on Teensy LC, Teensy 2.0, 74HC165 shift registers, and PCA9655E I/O expander.
|
||||||
|
|
||||||
> The public API should not be considered stable.
|
> The keybrd library is in Beta testing. The public API should not be considered stable.
|
||||||
> Currently the keybrd library is limited to 8x8 matrices, which is enough for compact split keyboards.
|
|
||||||
|
|
||||||
Example minimal keybrd sketch
|
Example minimal keybrd sketch
|
||||||
-----------------------------
|
-----------------------------
|
||||||
<!-- todo after teensy LC bb, copy and remove annotations from keybrd_single-layer_2_annotated.ino -->
|
A [minimal keybrd sketch](/tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino)
|
||||||
A [minimal keybrd sketch](tutorials/keybrd_2_single-layer_annotated/keybrd_2_single-layer_annotated.ino).
|
is 40 lines of code for a 4-key keyboard.
|
||||||
has about 50 lines of code and runs on a 4-key keyboard.
|
|
||||||
It runs on a breadboard and has rows, columns, and diodes just like the big keyboards.
|
|
||||||
The sketch is small because the keybrd library takes care of the low-level details.
|
The sketch is small because the keybrd library takes care of the low-level details.
|
||||||
|
It runs the breadboard keyboard in this picture.
|
||||||
|
|
||||||
The keybrd tutorial 1 shows how to make a breadboard keyboard.
|
<img src="tutorials/keybrd_1_breadboard/breadboard_keyboard_2x2.JPG" title="breadboard keyboard" alt="breadboard keyboard" style="height:290px;width:328px;">
|
||||||
The remaining [keybrd tutorials](tutorials) show how to create custom keybrd firmware.
|
|
||||||
|
|
||||||
Example complex keybrd sketch
|
Example complex keybrd sketch
|
||||||
-----------------------------
|
-----------------------------
|
||||||
The keybrd_DH emulates the DataHand keyboard.
|
keybrd_DH and its instantiation files contain about 800 lines of code.
|
||||||
It has 72 keys, 4 layers, 6 sub-layers, 2 matrices, 8 LEDs, and blinking LEDs.
|
It emulates the DataHand keyboard.
|
||||||
The keybrd_DH and its instantiation files contain about 800 lines of code.
|
The layout has 52 keys, 4 layers, 6 sub-layers, 2 matrices, 8 LEDs, and blinking LEDs.
|
||||||
|
|
||||||
|
[keybrd_DH_library_developer_guide.md](https://github.com/wolfv6/keybrd_DH/blob/master/doc/keybrd_DH_library_developer_guide.md)<br>
|
||||||
[mainSketch.ino](https://github.com/wolfv6/keybrd_DH/blob/master/examples/keybrd_DH/mainSketch.cpp)<br>
|
[mainSketch.ino](https://github.com/wolfv6/keybrd_DH/blob/master/examples/keybrd_DH/mainSketch.cpp)<br>
|
||||||
[instantiations_ports.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_ports.h)<br>
|
[instantiations_pins.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_pins.h)<br>
|
||||||
[instantiations_LEDs.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_LEDs.h)<br>
|
[instantiations_scancodes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_scancodes.h)<br>
|
||||||
[instantiations_codes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_codes.h)<br>
|
[instantiations_layercodes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_layercodes.h)<br>
|
||||||
[instantiations_matrix.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_matrix.h)
|
[instantiations_rows_L.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_rows_L.h)<br>
|
||||||
|
[instantiations_rows_R.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_rows_R.h)
|
||||||
|
|
||||||
|
![hweller](images/datahand.jpg "DataHand")
|
||||||
|
|
||||||
Support
|
Support
|
||||||
-------
|
-------
|
||||||
[Guides](doc) and [tutorials](tutorials) are provided.
|
[Guides](doc) and [tutorials](tutorials) are provided.
|
||||||
Please ask a questions in [issues](https://github.com/wolfv6/Keybrd/issues) if something is not clear.
|
|
||||||
|
keybrd tutorial_1 shows how to make a breadboard keyboard.
|
||||||
|
The remaining [keybrd tutorials](tutorials) show how to create custom keybrd firmware.
|
||||||
|
|
||||||
|
Please ask questions in [keybrd library for keyboard firmware](geekhack todo) thread if something is not clear.
|
||||||
|
@ -1,24 +1,34 @@
|
|||||||
# Change Log for keybrd library
|
Change Log for keybrd library
|
||||||
|
=============================
|
||||||
All notable changes to the keybrd project will be documented in this file.
|
All notable changes to the keybrd project will be documented in this file.
|
||||||
This project adheres to Semantic Versioning 2.0.0(http://semver.org/).
|
This project adheres to Semantic Versioning 2.0.0(http://semver.org/).
|
||||||
|
|
||||||
keybrd version 0.x.x is for initial development. The public API should not be considered stable.
|
keybrd version 0.x.x is for initial development.
|
||||||
keybrd version 1.0.0 will be released when the public API is stable.
|
keybrd version 1.0.0 will be released when the public API is stable.
|
||||||
|
|
||||||
## Unreleased
|
<!-- Unreleased
|
||||||
## 0.5.0 (2016-07-18)
|
------------------ -->
|
||||||
|
|
||||||
|
0.5.0 (2016-07-19)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
|
* Update tutorials
|
||||||
|
* Add tutorials for shift registers, LEDs, active high
|
||||||
|
|
||||||
* Backward incompatible changes
|
* Backward incompatible changes
|
||||||
|
* Add 32x32 matrix capability to Row_uC
|
||||||
|
* Add STROBE_ON and STROBE_OFF to scanner class, to set active state
|
||||||
* Rename classes
|
* Rename classes
|
||||||
|
|
||||||
## 0.4.1 (2016-06-21)
|
0.4.1 (2016-06-21)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
* Add config_keybrd.h for size configurations.
|
* Add config_keybrd.h for size configurations.
|
||||||
* Add RowScanner_SPI-ShiftRegisters for compact split keyboards up to 32 keys per matrix.
|
* Add RowScanner_SPI-ShiftRegisters for compact split keyboards up to 32 keys per matrix.
|
||||||
* Add LED_PinNumber for controlling indicator lights by pin number.
|
* Add LED_PinNumber for controlling indicator lights by pin number.
|
||||||
|
|
||||||
## 0.4.0 (2016-06-10)
|
0.4.0 (2016-06-10)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
* Add Row_uC
|
* Add Row_uC
|
||||||
* Add Row_IOE
|
* Add Row_IOE
|
||||||
@ -36,12 +46,14 @@ keybrd version 1.0.0 will be released when the public API is stable.
|
|||||||
* Move scanner and debouncer into their own classes.
|
* Move scanner and debouncer into their own classes.
|
||||||
* Remove Port arrays
|
* Remove Port arrays
|
||||||
|
|
||||||
## 0.3.1 (2016-06-02)
|
0.3.1 (2016-06-02)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
* Add RowBase class
|
* Add RowBase class
|
||||||
* Add Row::debounce()
|
* Add Row::debounce()
|
||||||
|
|
||||||
## 0.3.0 (2016-05-09)
|
0.3.0 (2016-05-09)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
* Add Tutorials
|
* Add Tutorials
|
||||||
|
|
||||||
@ -51,14 +63,16 @@ keybrd version 1.0.0 will be released when the public API is stable.
|
|||||||
* Moved sketches to examples directory
|
* Moved sketches to examples directory
|
||||||
* Replace Key_Layered dependency on LayerManager with LayerState class
|
* Replace Key_Layered dependency on LayerManager with LayerState class
|
||||||
|
|
||||||
## 0.2.0 (2016-02-25)
|
0.2.0 (2016-02-25)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
* Add Port classes for micro-controllers and I/O expanders
|
* Add Port classes for micro-controllers and I/O expanders
|
||||||
* Add DH_2565 sketch with DataHand layout
|
* Add DH_2565 sketch with DataHand layout
|
||||||
* Add Sticky mouse button (SMB) for DataHand layout
|
* Add Sticky mouse button (SMB) for DataHand layout
|
||||||
* Add Supporting documentation
|
* Add Supporting documentation
|
||||||
|
|
||||||
## 0.1.0 (2015-02-10)
|
0.1.0 (2015-02-10)
|
||||||
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
* The library runs on Teensy 2.0 microcontroller and MCP23018 I/O expander
|
* The library runs on Teensy 2.0 microcontroller and MCP23018 I/O expander
|
||||||
* Limited to 8x8 matrix, which is enough for compact or split keyboards
|
* Limited to 8x8 matrix, which is enough for compact or split keyboards
|
||||||
|
14
doc/PLANNED_FEATURES.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
planned_features is a view of where the keybrd project is headed.
|
||||||
|
|
||||||
|
Top priority
|
||||||
|
============
|
||||||
|
* Beta testing
|
||||||
|
* Schematics for tutorials
|
||||||
|
|
||||||
|
Medium priority
|
||||||
|
===============
|
||||||
|
* Add matrix-to-layout mapping array (to decouple key matrix from layout)
|
||||||
|
|
||||||
|
Low priority
|
||||||
|
============
|
||||||
|
* MCP23S18 I/O expander with Serial Peripheral Interface (SPI)
|
@ -1,37 +0,0 @@
|
|||||||
Teensy 2.0 Pinout Diagram
|
|
||||||
-------------------------
|
|
||||||
USB is on top in the diagram.
|
|
||||||
Inner columns are pin numbers, outer columns are port+bit pin name.
|
|
||||||
```
|
|
||||||
ground GND USB VCC +5v power
|
|
||||||
B0 0 21 F0
|
|
||||||
B1 1 20 F1
|
|
||||||
B2 2 19 F4
|
|
||||||
B3 3 18 F5
|
|
||||||
B7 4 17 F6
|
|
||||||
SCL D0 5 16 F7
|
|
||||||
SDA D1 6 15 B6
|
|
||||||
D2 7 14 B5
|
|
||||||
D3 8 13 B4
|
|
||||||
C6 9 12 D7
|
|
||||||
C7 10 11 D6 Do not use pin D6 for scanning keyboard matrix
|
|
||||||
LED on pin D6 pulls voltage down and will always return low
|
|
||||||
|
|
||||||
BOTTOM EDGE (USB on top, pins from left to right)
|
|
||||||
PIN# port+bit function
|
|
||||||
23 D5
|
|
||||||
VCC 5v power
|
|
||||||
GND ground
|
|
||||||
RST reset
|
|
||||||
22 D4
|
|
||||||
|
|
||||||
MIDDLE (below USB, pins from left to right)
|
|
||||||
PIN# port+bit function
|
|
||||||
24 E6
|
|
||||||
Ref
|
|
||||||
```
|
|
||||||
|
|
||||||
Teensy 2.0 pin assignment on https://www.pjrc.com/teensy/pinout.html
|
|
||||||
Teensy 2.0 pinout with pin numbers on http://www.pjrc.com/teensy/td_digital.html
|
|
||||||
Identifying and naming ports is useful when instantiating RowPorts and ColPorts.
|
|
||||||
Keybrd library was tested on Teensy 2.0
|
|
@ -1,5 +1,5 @@
|
|||||||
# this file specifies style for keybrd C++ and Arduino sketch .ino files
|
|
||||||
# Artistic Style is a console application for formatting C++ and Java source code
|
# Artistic Style is a console application for formatting C++ and Java source code
|
||||||
|
# this file specifies style for keybrd C++ and Arduino sketch .ino files
|
||||||
# http://sourceforge.net/projects/astyle/files/ download
|
# http://sourceforge.net/projects/astyle/files/ download
|
||||||
# http://astyle.sourceforge.net/astyle.html manual
|
# http://astyle.sourceforge.net/astyle.html manual
|
||||||
|
|
||||||
|
@ -1,31 +1,34 @@
|
|||||||
keybrd Library Developer's Guide
|
keybrd Library Developer's Guide
|
||||||
================================
|
================================
|
||||||
This guide if for maintaining and writing new classes for the keybrd library and its extension libraries.
|
This guide if for maintaining and writing new classes for the keybrd library and its extension libraries.
|
||||||
The most common reason for new classes are:
|
The most common reason for adding new classes are:
|
||||||
* Port classes for I/O expanders
|
* I/O expander classes
|
||||||
* custom layer schemes for multi-layer keyboards
|
* custom layer schemes for multi-layer keyboards
|
||||||
* experimental features
|
* experimental features
|
||||||
|
|
||||||
## Who this guide is for
|
Who this guide is for
|
||||||
|
---------------------
|
||||||
This guide is for the maintainers and developers of the keybrd library and it's extensions.
|
This guide is for the maintainers and developers of the keybrd library and it's extensions.
|
||||||
It is assumed the reader is familiar with C++ language including pointers, objects, classes, static class variables, composition, aggregation, inheritance, polymorphism, and enum.
|
It is assumed the reader is familiar with C++ language including pointers, objects, classes, static class variables, composition, aggregation, inheritance, polymorphism, and enum.
|
||||||
Debouncer and I/O expander use bit manipulation.
|
Row, Scanner, and Debouncer classes use bit manipulation.
|
||||||
|
|
||||||
## Custom Row classes
|
Custom Row classes
|
||||||
The keybrd library is flexible for designing custom Rows
|
------------------
|
||||||
|
Row classes are central to the keybrd library.
|
||||||
|
Row is an abstract base class that allows flexibility for designing derived Row classes:
|
||||||
* Row functions can be overridden in a derived class
|
* Row functions can be overridden in a derived class
|
||||||
* choice of Debouncers
|
* choice of Debouncers
|
||||||
* choice of Scanners
|
* choice of Scanners
|
||||||
|
|
||||||
this example illustrates the custom Row classes for a fictional keybrd_Ext extension library
|
This example illustrates the custom Row classes for a fictional keybrd_Ext extension library.
|
||||||
the keybrd_Ext library is for a split keyboard with a matrix on each hand
|
The keybrd_Ext library is for a split keyboard with sticky keys and a matrix on each hand.
|
||||||
|
|
||||||
Row_Ext::keyWasPressed() overrides Row::keyWasPressed()
|
Row_Ext::keyWasPressed() overrides Row::keyWasPressed()<br>
|
||||||
Row_Ext::keyWasPressed() is used to unstick sticky keys
|
Row_Ext::keyWasPressed() is used to unstick sticky keys
|
||||||
|
|
||||||
Row_Ext_uC scans the primary matrix
|
Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes.<br>
|
||||||
Row_Ext_ShiftRegisters scans the secondary matrix
|
Row_Ext_uC uses Scanner_uC to scan the primary matrix.<br>
|
||||||
Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes
|
Row_Ext_ShiftRegisters uses Scanner_ShiftRegs74HC165 to scan the secondary matrix.
|
||||||
|
|
||||||
Class inheritance diagram
|
Class inheritance diagram
|
||||||
```
|
```
|
||||||
@ -44,22 +47,23 @@ Class inheritance diagram
|
|||||||
Dependency diagram
|
Dependency diagram
|
||||||
```
|
```
|
||||||
|
|
||||||
________ Row_Ext_uC[1] _______________
|
________ Row_Ext_uC[1] ______________
|
||||||
/ \ \
|
/ | \
|
||||||
Scanner_uC[1] Debouncer_Samples[1] Key[1..*]
|
Scanner_uC[1] Debouncer_Samples[1] Key[1..*]
|
||||||
/ \ |
|
/ |
|
||||||
strobePin[1] readPins[1..*] Code[1..*]
|
strobePin[1] Code[1..*]
|
||||||
|
|
||||||
|
|
||||||
_____ Row_Ext_ShiftRegisters[1] ________
|
_________ Row_Ext_ShiftRegisters[1] ________
|
||||||
/ \ \
|
/ \ \
|
||||||
Scanner_ShiftRegs74HC165[1] Debouncer_Samples[1] Key[1..*]
|
Scanner_ShiftRegs74HC165[1] Debouncer_Samples[1] Key[1..*]
|
||||||
/ \ |
|
| |
|
||||||
strobePin[1] ROW_END[1] Code[1..*]
|
strobePin[1] Code[1..*]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Class inheritance diagrams
|
Class inheritance diagrams
|
||||||
|
--------------------------
|
||||||
|
|
||||||
Keybrd library class inheritance diagram
|
Keybrd library class inheritance diagram
|
||||||
```
|
```
|
||||||
@ -81,14 +85,14 @@ Keybrd library class inheritance diagram
|
|||||||
|
|
|
|
||||||
PortRead_PCA9655E (one PortRead class for each IOE type)
|
PortRead_PCA9655E (one PortRead class for each IOE type)
|
||||||
|
|
||||||
____ LED ____
|
_ LED _
|
||||||
/ \
|
/ \
|
||||||
LED_PinNumber LED_PCA9655E
|
LED_uC LED_PCA9655E
|
||||||
|
|
||||||
|
|
||||||
DebouncerInterface
|
DebouncerInterface
|
||||||
|
|
|
|
||||||
Debouncer_4Samples
|
Debouncer_Samples
|
||||||
|
|
||||||
ScanDelay
|
ScanDelay
|
||||||
|
|
||||||
@ -115,14 +119,15 @@ Keybrd library class inheritance diagram
|
|||||||
|__________________________________________
|
|__________________________________________
|
||||||
\ \ \ \
|
\ \ \ \
|
||||||
Code_Sc Code_Shift Code_AutoShift Code_LEDLock
|
Code_Sc Code_Shift Code_AutoShift Code_LEDLock
|
||||||
/ | \
|
/ \
|
||||||
Code_ScS Code_ScNS Code_ScNS_00
|
Code_ScS Code_ScNS
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Dependency diagrams
|
Dependency diagrams
|
||||||
|
-------------------
|
||||||
|
|
||||||
Example single-layer dependency diagram with LEDs
|
Dependency diagram of example single-layer keyboard with LEDs
|
||||||
```
|
```
|
||||||
_ Row_uC[1..*] _
|
_ Row_uC[1..*] _
|
||||||
/ | \
|
/ | \
|
||||||
@ -134,7 +139,7 @@ Example single-layer dependency diagram with LEDs
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example multi-layer dependency diagram with layer LEDs
|
Dependency diagram of example multi-layer keyboard with layer LEDs
|
||||||
```
|
```
|
||||||
LayerStates[1..*]
|
LayerStates[1..*]
|
||||||
________ Row_uC[1..*] ___________/__ | \
|
________ Row_uC[1..*] ___________/__ | \
|
||||||
@ -145,7 +150,7 @@ Example multi-layer dependency diagram with layer LEDs
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example secondary matrix with shift registers dependency diagram
|
Dependency diagram of example secondary matrix with shift registers
|
||||||
```
|
```
|
||||||
Row_ShiftRegisters[1..*]
|
Row_ShiftRegisters[1..*]
|
||||||
/ \ \
|
/ \ \
|
||||||
@ -155,7 +160,7 @@ Example secondary matrix with shift registers dependency diagram
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example secondary matrix with I/O Expander dependency diagram with LEDs
|
Dependency diagram of example secondary matrix with I/O Expander and LEDs
|
||||||
```
|
```
|
||||||
___ Row_IOE[1..*] _________
|
___ Row_IOE[1..*] _________
|
||||||
/ \ \
|
/ \ \
|
||||||
@ -169,7 +174,8 @@ Example secondary matrix with I/O Expander dependency diagram with LEDs
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Class naming conventions
|
Class naming conventions
|
||||||
|
------------------------
|
||||||
Class names start with upper case letter.
|
Class names start with upper case letter.
|
||||||
Most derived-class names start with the base class name followed by "_" and a name e.g.
|
Most derived-class names start with the base class name followed by "_" and a name e.g.
|
||||||
```
|
```
|
||||||
@ -181,7 +187,8 @@ Most derived-class names start with the base class name followed by "_" and a na
|
|||||||
This convention leads to class names that convey information about the classes inheritance.
|
This convention leads to class names that convey information about the classes inheritance.
|
||||||
Underscore delineates base class name and sub-class name. Capital letters delineate words.
|
Underscore delineates base class name and sub-class name. Capital letters delineate words.
|
||||||
|
|
||||||
## Layer-class naming conventions
|
Layer-class naming conventions
|
||||||
|
------------------------------
|
||||||
*Code_Layer* class names are concatenations of "Code_", "Layer" or layer name, and persistence.
|
*Code_Layer* class names are concatenations of "Code_", "Layer" or layer name, and persistence.
|
||||||
Example persistences are:
|
Example persistences are:
|
||||||
* "Lock" - layer remains active after the layer key is released
|
* "Lock" - layer remains active after the layer key is released
|
||||||
@ -202,7 +209,8 @@ Example Code_Layered class names:
|
|||||||
* Code_LayeredScSc
|
* Code_LayeredScSc
|
||||||
* Key_LayeredKeysArray
|
* Key_LayeredKeysArray
|
||||||
|
|
||||||
## Style guide
|
Style guide
|
||||||
|
-----------
|
||||||
Following the style guide makes it easier for the next programmer to understand your code.
|
Following the style guide makes it easier for the next programmer to understand your code.
|
||||||
* For class names, see above section "Class naming conventions".
|
* For class names, see above section "Class naming conventions".
|
||||||
* Member names use camelCase starting with lowercase letter.
|
* Member names use camelCase starting with lowercase letter.
|
||||||
@ -211,7 +219,7 @@ Following the style guide makes it easier for the next programmer to understand
|
|||||||
* Macros use ALL_CAPS_WITH_UNDERSCORE and have _MACRO suffix e.g. SAMPLE_COUNT_MACRO
|
* Macros use ALL_CAPS_WITH_UNDERSCORE and have _MACRO suffix e.g. SAMPLE_COUNT_MACRO
|
||||||
* Header guards have _H suffix e.g. #ifndef FILE_NAME_H
|
* Header guards have _H suffix e.g. #ifndef FILE_NAME_H
|
||||||
* Pointer names are prefixed with "ptr" e.g. ptrRow = &row;
|
* Pointer names are prefixed with "ptr" e.g. ptrRow = &row;
|
||||||
* Arrays names use the plural of element name e.g. Row* const = ptrsRows { &row0, &row1 };
|
* Arrays names use the plural of the element name e.g. Row* const = ptrsRows { &row0, &row1 };
|
||||||
* Pass arrays using array notation rather than pointer notation:
|
* Pass arrays using array notation rather than pointer notation:
|
||||||
```
|
```
|
||||||
void printArray(char[] array);
|
void printArray(char[] array);
|
||||||
@ -219,7 +227,7 @@ Following the style guide makes it easier for the next programmer to understand
|
|||||||
void printArray( char* array);
|
void printArray( char* array);
|
||||||
```
|
```
|
||||||
* In constructor's initialization list, use same names for fields and constructor parameters.
|
* In constructor's initialization list, use same names for fields and constructor parameters.
|
||||||
* Do not use new or malloc (making memory leaks impossible).
|
* Do not use new or malloc (make memory leaks impossible).
|
||||||
* Document class interface in .h file, above the class declaration.
|
* Document class interface in .h file, above the class declaration.
|
||||||
* Code should be self-documenting. A simple function with a good name needs no comment.
|
* Code should be self-documenting. A simple function with a good name needs no comment.
|
||||||
* Code is automatically formatted before being pushed to the keybrd repository.
|
* Code is automatically formatted before being pushed to the keybrd repository.
|
||||||
@ -231,10 +239,11 @@ Following the style guide makes it easier for the next programmer to understand
|
|||||||
|
|
||||||
<!-- http://stackoverflow.com/questions/2198241/best-practice-for-c-function-commenting -->
|
<!-- http://stackoverflow.com/questions/2198241/best-practice-for-c-function-commenting -->
|
||||||
|
|
||||||
## Trace of keybrd scan
|
Trace of keybrd scan
|
||||||
|
--------------------
|
||||||
Arduino does not have a debugger.
|
Arduino does not have a debugger.
|
||||||
So here is the next best thing; a list of functions in the order that they are called.
|
So here is the next best thing; a list of functions in the order that they are called.
|
||||||
The trace is of a single-layer keybrd scan (no LEDs and no I/O expander).
|
The trace is of a one-row single-layer keybrd scan.
|
||||||
Refer to it like a table of contents while reading the keybrd library.
|
Refer to it like a table of contents while reading the keybrd library.
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -242,9 +251,9 @@ Refer to it like a table of contents while reading the keybrd library.
|
|||||||
Row::process()
|
Row::process()
|
||||||
Scanner_uC::scan() strobe row on
|
Scanner_uC::scan() strobe row on
|
||||||
for each readPin
|
for each readPin
|
||||||
set rowState bit
|
set readState bit
|
||||||
strobe row off
|
strobe row off
|
||||||
Debouncer_4Samples::debounce() debounce
|
Debouncer_Samples::debounce() debounce
|
||||||
Row::send() for each key in row
|
Row::send() for each key in row
|
||||||
if falling edge
|
if falling edge
|
||||||
Key_*::release() scanCode->release()
|
Key_*::release() scanCode->release()
|
||||||
@ -256,7 +265,8 @@ Refer to it like a table of contents while reading the keybrd library.
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## The Arduino libraries
|
The Arduino libraries
|
||||||
|
---------------------
|
||||||
The keybrd libraries compile on the Arduino IDE and make extensive use of the following [Arduino libraries](https://www.arduino.cc/en/Reference/Libraries):
|
The keybrd libraries compile on the Arduino IDE and make extensive use of the following [Arduino libraries](https://www.arduino.cc/en/Reference/Libraries):
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
keybrd Library User's Guide
|
keybrd Library User's Guide
|
||||||
===========================
|
===========================
|
||||||
keybrd is an open source library for creating custom-keyboard firmware.
|
keybrd is a library for creating custom-keyboard firmware.
|
||||||
The resulting keyboard firmware is compatible with standard USB keyboard drivers.
|
This guide shows how to:
|
||||||
|
|
||||||
This guide shows how to
|
|
||||||
* set up the Arduino development environment
|
* set up the Arduino development environment
|
||||||
* install the keybrd library
|
* install the keybrd library
|
||||||
* compile and load keybrd firmware
|
* compile and load keybrd firmware
|
||||||
@ -11,16 +9,19 @@ This guide shows how to
|
|||||||
The Arduino development environment is free and simple as possible.
|
The Arduino development environment is free and simple as possible.
|
||||||
Its easy for novice programmers to setup and learn.
|
Its easy for novice programmers to setup and learn.
|
||||||
|
|
||||||
## Who this guide is for
|
Who this guide is for
|
||||||
|
---------------------
|
||||||
This guide is for anyone who wants to use the keybrd library to develop keyboard firmware.
|
This guide is for anyone who wants to use the keybrd library to develop keyboard firmware.
|
||||||
|
|
||||||
A reader with programming experience, but no C++ experience, would understand the tutorials well enough to modify existing keybrd sketches.
|
A reader with programming experience, but no C++ experience, would understand the tutorials well enough to modify existing keybrd sketches.
|
||||||
An experienced C++ programmer would be able to write original sketches and classes.
|
An experienced C++ programmer would be able to write original sketches and classes.
|
||||||
|
|
||||||
The library is written in the C++ language and uses pointers, objects, classes, static class variables, aggregation, inheritance, and enum.
|
The library is written in the C++ language.
|
||||||
|
keybrd sketches use keybrd classes, objects pointers, aggregation, and static class variables.
|
||||||
|
|
||||||
## Microcontroller board requirements
|
Microcontroller board requirements
|
||||||
The keybrd library works with Teensy and Arduino boards.
|
----------------------------------
|
||||||
|
The keybrd library works with Teensy and Arduino compatible boards.
|
||||||
|
|
||||||
[Teensy LC](https://www.pjrc.com/teensy/teensyLC.html) has 8K RAM, which is more than enough memory for any keyboard.
|
[Teensy LC](https://www.pjrc.com/teensy/teensyLC.html) has 8K RAM, which is more than enough memory for any keyboard.
|
||||||
|
|
||||||
@ -28,7 +29,8 @@ keybrd has been tested on the DodoHand keyboard with Teensy 2.0 and PCA9655E I/O
|
|||||||
|
|
||||||
Teensy LC is preferred over the older Teensy 2.0 for it's larger memory capacity and lower price.
|
Teensy LC is preferred over the older Teensy 2.0 for it's larger memory capacity and lower price.
|
||||||
|
|
||||||
## Getting started with Teensy, Arduino IDE, and keybrd
|
Getting started with Teensy, Arduino IDE, and keybrd
|
||||||
|
----------------------------------------------------
|
||||||
The Arduino IDE is used to
|
The Arduino IDE is used to
|
||||||
|
|
||||||
1. edit sketches
|
1. edit sketches
|
||||||
@ -43,7 +45,7 @@ Teensyduino is a software add-on for the Arduino IDE that allows it to compile t
|
|||||||
The following install and setup steps create an Arduino development environment for keybrd sketches.
|
The following install and setup steps create an Arduino development environment for keybrd sketches.
|
||||||
|
|
||||||
### Install Arduino IDE and Teensyduino
|
### Install Arduino IDE and Teensyduino
|
||||||
The following install steps are modified from the [Teensyduino download page](https://www.pjrc.com/teensy/td_download.html)
|
The following install steps are modified from the [Teensyduino download page](https://www.pjrc.com/teensy/td_download.html).
|
||||||
|
|
||||||
For Linux:
|
For Linux:
|
||||||
|
|
||||||
@ -63,37 +65,38 @@ For Linux:
|
|||||||
Run the teensyduino installer and fill the form fields:
|
Run the teensyduino installer and fill the form fields:
|
||||||
|
|
||||||
Arduino location to install Teensyduino: /opt/arduino-1.x.x
|
Arduino location to install Teensyduino: /opt/arduino-1.x.x
|
||||||
Libraries to Install: None
|
Libraries to Install: keybrd
|
||||||
|
|
||||||
4. Launch Arduino IDE from /opt/arduino-1.x.x/arduino
|
4. Launch Arduino IDE from /opt/arduino-1.x.x/arduino
|
||||||
|
|
||||||
|
<!-- todo no longer needed, delete after testing Arduino library manager
|
||||||
### Download and unpack keybrd-master.zip into your Arduino directory
|
### Download and unpack keybrd-master.zip into your Arduino directory
|
||||||
<!-- todo update after testing Arduino library manager
|
link from tutorial 8 ## Publishing
|
||||||
link from tutorial 7 ## Publishing
|
|
||||||
https://www.arduino.cc/en/Guide/Libraries
|
https://www.arduino.cc/en/Guide/Libraries
|
||||||
* Installing Additional Arduino Libraries
|
* Installing Additional Arduino Libraries
|
||||||
* Using the Library Manager
|
* Using the Library Manager
|
||||||
-->
|
|
||||||
|
|
||||||
Down load keybrd-master.zip from the [Download ZIP](https://github.com/wolfv6/keybrd) button.
|
Down load keybrd-master.zip from the [Download ZIP](https://github.com/wolfv6/keybrd) button.
|
||||||
|
|
||||||
Unpack keybrd-master.zip into your Arduino directory on your system (default location is ~/Documents/Arduino/).
|
Unpack keybrd-master.zip into your Arduino directory on your system (default location is ~/Documents/Arduino/).
|
||||||
|
-->
|
||||||
|
|
||||||
### Install keybrd library and keybrd extension libraries
|
### Install keybrd extension libraries
|
||||||
<!-- todo update after testing Arduino library manager -->
|
|
||||||
|
|
||||||
The keybrd library contains the foundation classes for creating a keyboard firmware.
|
The keybrd library contains the foundation classes for creating a keyboard firmware.
|
||||||
For emphasis, it is sometimes referred to as the "core keybrd library".
|
For emphasis, it is sometimes referred to as the "core keybrd library".
|
||||||
|
|
||||||
keybrd extension libraries contain additional classes that extend the keyboard library.
|
keybrd extension libraries contain additional classes that extend the keyboard library.
|
||||||
keybrd extension library names are prefixed with "keybrd_".
|
keybrd extension library names are prefixed with "keybrd_".
|
||||||
|
|
||||||
The Arduino IDE looks for libraries in Arduino/libraries/.
|
Instructions for installing Arduino libraries are at: http://www.arduino.cc/en/Guide/Libraries
|
||||||
For example, the DodoHand keyboard requires that the core keybrd library and the keybrd_DH extension library be installed:
|
|
||||||
* Arduino/libraries/keybrd/
|
|
||||||
* Arduino/libraries/keybrd_DH/
|
|
||||||
|
|
||||||
A keybrd extension library allows classes to be shared by multiple sketches without polluting the core keybrd library with classes that other keyboards can not use.
|
A Sketchbook is a folder that the Arduino IDE uses to store sketches and libraries.
|
||||||
|
The default location for Arduino libraries is ~/Documents/Arduino/libraries/.
|
||||||
|
|
||||||
|
For example, the DodoHand keyboard requires the core keybrd library and the keybrd_DH extension library.
|
||||||
|
After installing the libraries, my Arduino directory looks like this:
|
||||||
|
* ~/Documents/Arduino/libraries/keybrd/
|
||||||
|
* ~/Documents/Arduino/libraries/keybrd_DH/
|
||||||
|
|
||||||
### Setup Arduino IDE for compiling keybrd firmware
|
### Setup Arduino IDE for compiling keybrd firmware
|
||||||
From the Arduino IDE tool bar, select:
|
From the Arduino IDE tool bar, select:
|
||||||
@ -104,33 +107,28 @@ These are optional:
|
|||||||
* File > Preferences > Compiler warnings: All
|
* File > Preferences > Compiler warnings: All
|
||||||
* File > Preferences > check: Use external editor
|
* File > Preferences > check: Use external editor
|
||||||
|
|
||||||
A Sketchbook is a folder that the Arduino IDE uses to store sketches and libraries.
|
|
||||||
The default location for [Arduino libraries](https://www.arduino.cc/en/Guide/Libraries) is in
|
|
||||||
|
|
||||||
~/Documents/Arduino/libraries/
|
|
||||||
|
|
||||||
### Compile and load keybrd sketch
|
### Compile and load keybrd sketch
|
||||||
If it isn't already plugged in, plug the USB cable into the computer and controller.
|
If it isn't already plugged in, plug the USB cable into the computer and controller.
|
||||||
|
|
||||||
> CAUTION: It is possible to loose control of your keyboard when running a keybrd sketch.
|
> CAUTION: It is possible to loose control of your keyboard when running a keybrd sketch.
|
||||||
> If the keybrd sketch has a mouse object, it is also possible to loose control of your mouse.
|
> If the keybrd sketch has a mouse object, it is possible to loose control of your mouse too.
|
||||||
> USB keyboard protocol is capable of spewing characters and mouse commands at up to 500 per second.
|
> USB keyboard protocol is capable of spewing characters and mouse commands at up to 500 per second.
|
||||||
> Take the following precautions before uploading an untested keybrd sketch to a controller:
|
> Take the following precautions before uploading an untested keybrd sketch to a controller:
|
||||||
> * Save all files and close dangerous applications.
|
> * Save all files and close dangerous applications.
|
||||||
> * Park the cursor in an editor opened to a test file.
|
> * Park the cursor in an editor opened to a test file.
|
||||||
> That way you can immediately see if the controller starts spewing characters.
|
> That way you can immediately see if the controller starts spewing characters.
|
||||||
> * Be prepared to turn off the controller:
|
> * Be prepared to turn off the controller:
|
||||||
> turn off Teensy Loader's green "Auto" button and push Teensy's reset button
|
> turn off Teensy Loader's green "Auto" button and push Teensy's reset button or unplug Teensy USB.
|
||||||
> if that fails, unplug Teensy USB
|
|
||||||
|
|
||||||
Compile and load workflow:
|
Compile and load workflow:
|
||||||
1. Open a keybrd sketch in the Arduino IDE.
|
1. Open a keybrd sketch in the Arduino IDE.
|
||||||
2. Prepare for loosing control of keyboard and mouse.
|
2. Prepare for loosing control of keyboard and mouse.
|
||||||
3. On the Arduino IDE, click the Upload button.
|
3. On the Arduino IDE, click the Upload button.
|
||||||
4. The Teensy boot loader window opens;
|
4. The Teensy boot loader window opens
|
||||||
you might need to press and release the pushbutton on the Teensy circuit board.
|
(you might need to press and release the pushbutton on the Teensy circuit board).
|
||||||
|
|
||||||
## Example keybrd sketches
|
Example keybrd sketches
|
||||||
|
-----------------------
|
||||||
Example keybrd sketches are in the examples and tutorials directories.
|
Example keybrd sketches are in the examples and tutorials directories.
|
||||||
Extension libraries have their example sketches similarly located.
|
Extension libraries have their example sketches similarly located.
|
||||||
|
|
||||||
@ -140,18 +138,16 @@ The example sketch names use the following conventions.
|
|||||||
|
|
||||||
where
|
where
|
||||||
* **keybrd** is the library name e.g. keybrd, keybrd_DH
|
* **keybrd** is the library name e.g. keybrd, keybrd_DH
|
||||||
* **feature** is a distinguishing feature of the keybrd sketch e.g. breadboard, LED, sound, Dvorak
|
* **feature** is a distinguishing feature of the keybrd sketch e.g. keyboard name, sound, Dvorak
|
||||||
* **version** is the sketch's version number
|
* **version** is the sketch's version number (optional)
|
||||||
|
|
||||||
The first field are mandatory, the version optional.
|
Active state and diode orientation
|
||||||
|
----------------------------------
|
||||||
## Active state and diode orientation
|
|
||||||
Active state is set in the sketch by variables STROBE_ON and STROBE_OFF.
|
Active state is set in the sketch by variables STROBE_ON and STROBE_OFF.
|
||||||
The following instructions are for setting active state for a Scanner_uC class.
|
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:
|
||||||
* Use internal pull-down resistors.
|
|
||||||
* Orient diodes with cathode (banded end) towards the write pins (row)
|
* Orient diodes with cathode (banded end) towards the write pins (row)
|
||||||
* Use these two lines in the sketch:
|
* Use these two lines in the sketch:
|
||||||
```
|
```
|
||||||
@ -168,61 +164,48 @@ For active high:
|
|||||||
const bool Scanner_uC::STROBE_OFF = LOW;
|
const bool Scanner_uC::STROBE_OFF = LOW;
|
||||||
```
|
```
|
||||||
|
|
||||||
![Diode](../tutorials/keybrd_1_breadboard_images/120px-Diode_pinout_en_fr.svg.png)
|
Troubleshooting check list
|
||||||
|
--------------------------
|
||||||
Diagram is of typical through-the-hole [diode](https://en.wikipedia.org/wiki/Diode) in same alignment as diode symbol.
|
The following is a listing of items to check when a new keybrd sketch or keyboard hardware is having trouble.
|
||||||
Cross bar and band depict the cathode.
|
|
||||||
|
|
||||||
## Troubleshooting check list
|
|
||||||
The following is a listing of items to check when a new keybrd sketch or keyboard is having trouble.
|
|
||||||
|
|
||||||
Development-environment items to check:
|
Development-environment items to check:
|
||||||
* If the keyboard has an I/O expander, power cycle (replug the USB) after loading the HEX file.
|
* If the keyboard has an I/O expander, power cycle (replug the USB) after loading the HEX file.
|
||||||
* If compile error: 'KEY_A' was not declared in this scope
|
* For compile error:
|
||||||
|
```
|
||||||
From the Arduino IDE tool bar, select: Tools > USB Type > Keyboard + Mouse + Joystick
|
'KEY_A' was not declared in this scope
|
||||||
|
```
|
||||||
|
Where 'KEY_A' could be any scan code.
|
||||||
|
Fix this from the Arduino IDE tool bar: Tools > USB Type > Keyboard + Mouse + Joystick
|
||||||
|
|
||||||
Sketch items to check:
|
Sketch items to check:
|
||||||
* For each row, number of keys in Row should equal number of colPort pins.
|
* For each row, number of read pins in Row should equal number of keys.
|
||||||
In this example, row_0 has six colPort pins in ptrsColPorts, and six keys in ptrsKeys_0:
|
In this example, row_0 has 2 read pins and 2 keys:
|
||||||
```
|
```
|
||||||
ColPort_AVR colPortB(DDRB, PORTB, PINB, 1<<0 | 1<<1 | 1<<2 | 1<<3 );
|
uint8_t readPins[] = {14, 15};
|
||||||
ColPort_AVR colPortD(DDRD, PORTD, PIND, 1<<2 | 1<<3 );
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
ColPort* const ptrsColPorts[] = { &colPortB, &colPortD };
|
Key* ptrsKeys_0[] = { &s_a, &s_b };
|
||||||
const uint8_t COL_PORT_COUNT = sizeof(ptrsColPorts)/sizeof(*ptrsColPorts);
|
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||||
|
|
||||||
const Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 };
|
|
||||||
Row row_0(ptrsKeys_0, &rowPortF, 1<<0, ptrsColPorts, COL_PORT_COUNT);
|
|
||||||
```
|
|
||||||
* Some of the constructors take array-element-count arguments, make sure that the correct counts are passed to the constructors. Or use sizeof() like this example:
|
|
||||||
```
|
|
||||||
Row* const ptrsRows[] = { &row0, &row1, &row2, &row3 };
|
|
||||||
const uint8_t ROW_COUNT = sizeof(ptrsRows)/sizeof(*ptrsRows);
|
|
||||||
Matrix matrix(ptrsRows, ROW_COUNT, 1);
|
|
||||||
```
|
```
|
||||||
|
* Some of the constructors take array-element-count arguments, make sure that the correct counts are passed to the constructors. Or use sizeof() like the preceding example.
|
||||||
* For multi-layered keyboards, the number of codes in each Key_Layered should equal the number of layers.
|
* For multi-layered keyboards, the number of codes in each Key_Layered should equal the number of layers.
|
||||||
|
|
||||||
Hardware items to check:
|
Hardware items to check:
|
||||||
* Connections
|
* Connections
|
||||||
* Diode orientation
|
* Diode orientation
|
||||||
* 5 volts across power and ground
|
* 3.3 or 5 volts across power and ground
|
||||||
* To validate keyboard hardware, modify the simple single-layer keybrd sketch from the tutorial.
|
* To validate keyboard hardware, modify the simple [keybrd_1_breadboard.ino](../tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino) sketch.
|
||||||
|
|
||||||
<!-- todo after teensy LC bb, link to minimal keybrd sketch
|
Keybrd nomenclature
|
||||||
[minimal keybrd sketch](blob/master/tutorials/keybrd_2_single-layer_annotated/keybrd_2_single-layer_annotated.ino).
|
-------------------
|
||||||
-->
|
|
||||||
|
|
||||||
## Keybrd nomenclature
|
|
||||||
**[scancode](http://en.wikipedia.org/wiki/Scancode)** -
|
**[scancode](http://en.wikipedia.org/wiki/Scancode)** -
|
||||||
Is a 16-bit integer assigned to a key position on a keyboard.
|
Is a 16-bit integer assigned to a key position on a keyboard.
|
||||||
The keyboard sends a scancode to the computer for every key press and release.
|
The keyboard sends a scancode to the computer for every key press and release.
|
||||||
|
|
||||||
**[Layers](http://deskthority.net/wiki/Layer)** -
|
**[layers](http://deskthority.net/wiki/Layer)** - are key bindings provided by the keyboard firmware. For example,
|
||||||
are key bindings provided by the keyboard firmware.
|
* The classic [IBM PC keyboard](http://en.wikipedia.org/wiki/IBM_PC_keyboard) has one layer.
|
||||||
The standard [IBM PC keyboard](http://en.wikipedia.org/wiki/IBM_PC_keyboard) has one layer.
|
* Many compact keyboards have an additional [Fn layer](http://en.wikipedia.org/wiki/Fn_key).
|
||||||
Many compact keyboards have an additional [Fn layer](http://en.wikipedia.org/wiki/Fn_key).
|
* The [Neo layout](http://neo-layout.org/index_en.html) has 6 layers.
|
||||||
The [Neo layout](http://neo-layout.org/index_en.html) has 6 layers.
|
|
||||||
|
|
||||||
**Layer id** - is an integer assigned to a layer.
|
**Layer id** - is an integer assigned to a layer.
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
planned_features is a view of where the keybrd project is headed.
|
|
||||||
|
|
||||||
Top priority
|
|
||||||
============
|
|
||||||
MCP23S18 I/O expander with Serial Peripheral Interface (SPI)
|
|
||||||
|
|
||||||
Med priority
|
|
||||||
============
|
|
||||||
Add matrix-to-layout mapping array (to decouple matrix from layout)
|
|
||||||
|
|
||||||
Low priority
|
|
||||||
============
|
|
||||||
Update tutorials:
|
|
||||||
* Currently tutorial sketches are obsolete and won't compile
|
|
||||||
* Change tutorial sketches from teensy 2.0 and PCA9655E-D IOE to Teensy LC and MCP23018 IOE
|
|
||||||
|
|
||||||
Add more tutorials:
|
|
||||||
* tutorial_5_LEDs.md
|
|
||||||
* tutorial_6_mapping_matrix_to_layout.md
|
|
||||||
* tutorial_9_active_high.md
|
|
||||||
* add schematics to tutorials
|
|
@ -1,165 +0,0 @@
|
|||||||
/* keybrd_shift_reg.ino
|
|
||||||
Tested on Teensy LC and daisy chained 74HC165 shift registers
|
|
||||||
|
|
||||||
The keyboard hardware for this sketch has 4 shift registers,
|
|
||||||
with every 4th input pin connected to a pull-down resistor and matrix column, also the 31st key.
|
|
||||||
Unused input pins are not grounded, so add this line to Scanner_ShiftRegs74HC165::scan():
|
|
||||||
//clear unpowered pins (for testing on breadboard)
|
|
||||||
rowState &= 0b11110001000100010001000100010001;
|
|
||||||
|
|
||||||
Layout Layout
|
|
||||||
| Left | **0**|**1**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**|**8**|
|
|
||||||
|:-----:|------|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
||||||
| **0** |capLck| a | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
|
||||||
| **1** | b | c | | **1** | a | b | c | d | e | f | g | h | i |
|
|
||||||
*/
|
|
||||||
// ################## GLOBAL ###################
|
|
||||||
// ================= INCLUDES ==================
|
|
||||||
#include <Debug.h>
|
|
||||||
#include <ScanDelay.h>
|
|
||||||
#include <LED_uC.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
//Codes
|
|
||||||
#include <Code_Sc.h>
|
|
||||||
#include <Code_LEDLock.h>
|
|
||||||
|
|
||||||
//Matrix
|
|
||||||
#include <Row_uC.h>
|
|
||||||
#include <Row_ShiftRegisters.h>
|
|
||||||
|
|
||||||
// =============== CONFIGURATION ===============
|
|
||||||
ScanDelay scanDelay(9000);
|
|
||||||
|
|
||||||
//set left matrix for active low
|
|
||||||
const bool Scanner_uC::STROBE_ON = LOW;
|
|
||||||
const bool Scanner_uC::STROBE_OFF = HIGH;
|
|
||||||
|
|
||||||
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
|
|
||||||
|
|
||||||
//set right matrix for active low
|
|
||||||
const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW;
|
|
||||||
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH;
|
|
||||||
|
|
||||||
Debug debug;
|
|
||||||
|
|
||||||
// ================= LEFT PINS =================
|
|
||||||
uint8_t readPins[] = {14, 15};
|
|
||||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
|
||||||
|
|
||||||
// ==================== LEDs ===================
|
|
||||||
LED_uC LED1(16);
|
|
||||||
|
|
||||||
// =================== CODES ===================
|
|
||||||
Code_Sc s_a(KEY_A);
|
|
||||||
Code_Sc s_b(KEY_B);
|
|
||||||
Code_Sc s_c(KEY_C);
|
|
||||||
Code_Sc s_d(KEY_D);
|
|
||||||
Code_Sc s_e(KEY_E);
|
|
||||||
Code_Sc s_f(KEY_F);
|
|
||||||
Code_Sc s_g(KEY_G);
|
|
||||||
Code_Sc s_h(KEY_H);
|
|
||||||
Code_Sc s_i(KEY_I);
|
|
||||||
|
|
||||||
Code_Sc s_u(KEY_U);
|
|
||||||
Code_Sc s_v(KEY_V);
|
|
||||||
Code_Sc s_w(KEY_W);
|
|
||||||
Code_Sc s_x(KEY_X);
|
|
||||||
|
|
||||||
Code_Sc s_z(KEY_Z);
|
|
||||||
|
|
||||||
Code_Sc s_0(KEY_0);
|
|
||||||
Code_Sc s_1(KEY_1);
|
|
||||||
Code_Sc s_2(KEY_2);
|
|
||||||
Code_Sc s_3(KEY_3);
|
|
||||||
Code_Sc s_4(KEY_4);
|
|
||||||
Code_Sc s_5(KEY_5);
|
|
||||||
Code_Sc s_6(KEY_6);
|
|
||||||
Code_Sc s_7(KEY_7);
|
|
||||||
Code_Sc s_8(KEY_8);
|
|
||||||
|
|
||||||
Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED1);
|
|
||||||
|
|
||||||
// ================= LEFT ROWS =================
|
|
||||||
Key* ptrsKeys_L0[] = { &o_capsLock, &s_a };
|
|
||||||
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
|
||||||
|
|
||||||
Key* ptrsKeys_L1[] = { &s_b, &s_c };
|
|
||||||
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
|
||||||
|
|
||||||
// ================= RIGHT ROWS ================
|
|
||||||
//typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h
|
|
||||||
//Row_ShiftRegisters(strobePin, readPinCount, ptrsKeys[])
|
|
||||||
//the s_z are place holders and should not print
|
|
||||||
|
|
||||||
/*
|
|
||||||
//prints 0 1
|
|
||||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
|
||||||
|
|
||||||
//prints a b
|
|
||||||
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R1(9, sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1), ptrsKeys_R1);
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
//prints 0 1 2
|
|
||||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
|
||||||
&s_2, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
//prints 0 1 2 3
|
|
||||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
|
||||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
//prints 0 1 2 3 4 5
|
|
||||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
|
||||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z,
|
|
||||||
&s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//prints 0 1 2 3 3 4 5 6, microseconds_per_scan=87 with SAMPLE_COUNT 4
|
|
||||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
|
||||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z,
|
|
||||||
&s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z,
|
|
||||||
&s_6, &s_z, &s_z, &s_z, &s_3, &s_4, &s_5, &s_6 };
|
|
||||||
Row_ShiftRegisters row_R0(0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
|
||||||
|
|
||||||
//prints a b c d u v w x
|
|
||||||
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z,
|
|
||||||
&s_c, &s_z, &s_z, &s_z, &s_d, &s_z, &s_z, &s_z,
|
|
||||||
&s_e, &s_z, &s_z, &s_z, &s_f, &s_z, &s_z, &s_z,
|
|
||||||
&s_g, &s_z, &s_z, &s_z, &s_u, &s_v, &s_w, &s_x };
|
|
||||||
Row_ShiftRegisters row_R1(1, sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1), ptrsKeys_R1);
|
|
||||||
|
|
||||||
// ################### MAIN ####################
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Keyboard.begin();
|
|
||||||
SPI.begin();
|
|
||||||
row_R0.begin();
|
|
||||||
row_R1.begin();
|
|
||||||
|
|
||||||
debug.wait_for_OS(LED1, 6);
|
|
||||||
Keyboard.println(F("keybrd_shift_reg.ino"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
//left matrix
|
|
||||||
row_L0.process();
|
|
||||||
row_L1.process();
|
|
||||||
|
|
||||||
//right matrix
|
|
||||||
row_R0.process();
|
|
||||||
row_R1.process();
|
|
||||||
|
|
||||||
scanDelay.delay();
|
|
||||||
|
|
||||||
//delay(100);
|
|
||||||
//Keyboard.println("");
|
|
||||||
//debug.print_microseconds_per_scan();
|
|
||||||
}
|
|
BIN
images/datahand.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
@ -6,4 +6,4 @@ sentence=A library for creating custom-keyboard firmware.
|
|||||||
paragraph=<br>Create keyboards with any configuration:<br>one-piece, split with I/O expander, single-layer, multiple-layer
|
paragraph=<br>Create keyboards with any configuration:<br>one-piece, split with I/O expander, single-layer, multiple-layer
|
||||||
category=Device Control
|
category=Device Control
|
||||||
url=https://github.com/wolfv6/keybrd
|
url=https://github.com/wolfv6/keybrd
|
||||||
architectures=avr
|
architectures=*
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
void Debug::printMicrosecondsPerScan()
|
void Debug::printMicrosecondsPerScan()
|
||||||
{
|
{
|
||||||
|
static unsigned long nextTime = 0;
|
||||||
|
static unsigned int scanCount = 0;
|
||||||
|
|
||||||
if (millis() >= nextTime)
|
if (millis() >= nextTime)
|
||||||
{
|
{
|
||||||
Keyboard.print(1000000/scanCount); //print microseconds per scan
|
Keyboard.print(1000000/scanCount); //print microseconds per scan
|
||||||
@ -13,6 +16,9 @@ void Debug::printMicrosecondsPerScan()
|
|||||||
}
|
}
|
||||||
void Debug::printScansPerSecond()
|
void Debug::printScansPerSecond()
|
||||||
{
|
{
|
||||||
|
static unsigned long nextTime = 0;
|
||||||
|
static unsigned int scanCount = 0;
|
||||||
|
|
||||||
if (millis() >= nextTime)
|
if (millis() >= nextTime)
|
||||||
{
|
{
|
||||||
Keyboard.print(scanCount); //print scans per second
|
Keyboard.print(scanCount); //print scans per second
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
|
|
||||||
class Debug
|
class Debug
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
unsigned long nextTime = 0;
|
|
||||||
unsigned int scanCount = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void printMicrosecondsPerScan(); //print microseconds per scan every second
|
void printMicrosecondsPerScan(); //print microseconds per scan every second
|
||||||
void printScansPerSecond(); //print scans per second every second
|
void printScansPerSecond(); //print scans per second every second
|
||||||
|
@ -39,7 +39,8 @@ class Row_ShiftRegisters : public Row
|
|||||||
Debouncer_Samples debouncer;
|
Debouncer_Samples debouncer;
|
||||||
const uint8_t readPinCount; //number of read pins
|
const uint8_t readPinCount; //number of read pins
|
||||||
public:
|
public:
|
||||||
Row_ShiftRegisters(const uint8_t strobePin, const uint8_t readPinCount, Key *const ptrsKeys[])
|
Row_ShiftRegisters(const uint8_t strobePin, const uint8_t readPinCount,
|
||||||
|
Key* const ptrsKeys[])
|
||||||
: Row(ptrsKeys), scanner(strobePin, readPinCount), readPinCount(readPinCount) { }
|
: Row(ptrsKeys), scanner(strobePin, readPinCount), readPinCount(readPinCount) { }
|
||||||
void begin();
|
void begin();
|
||||||
void process();
|
void process();
|
||||||
|
@ -33,7 +33,8 @@ In addition, each row needs to be connected to a strobe pin from the controller.
|
|||||||
class Scanner_ShiftRegs74HC165
|
class Scanner_ShiftRegs74HC165
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static const uint8_t SHIFT_LOAD; //controller's pin number that is connected to shift register's SHIFT_LOAD pin
|
static const uint8_t SHIFT_LOAD; //controller's pin number that is
|
||||||
|
// connected to shift register's SHIFT_LOAD pin
|
||||||
static const bool STROBE_ON; //logic level of strobe on, active state HIGH or LOW
|
static const bool STROBE_ON; //logic level of strobe on, active state HIGH or LOW
|
||||||
static const bool STROBE_OFF; //logic level of strobe off, complement of active state
|
static const bool STROBE_OFF; //logic level of strobe off, complement of active state
|
||||||
const uint8_t strobePin; //Arduino pin number connected to this row
|
const uint8_t strobePin; //Arduino pin number connected to this row
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
// getFreeSRAM.h copied from
|
|
||||||
// http://andybrown.me.uk/2011/01/01/debugging-avr-dynamic-memory-allocation/
|
|
||||||
/*
|
|
||||||
* memdebug.h
|
|
||||||
*
|
|
||||||
* Created on: 15 Dec 2010
|
|
||||||
* Author: Andy Brown
|
|
||||||
*
|
|
||||||
* Use without attribution is permitted provided that this
|
|
||||||
* header remains intact and that these terms and conditions
|
|
||||||
* are followed:
|
|
||||||
*
|
|
||||||
* http://andybrown.me.uk/ws/terms-and-conditions
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
extern unsigned int __bss_end;
|
|
||||||
extern unsigned int __heap_start;
|
|
||||||
extern void *__brkval;
|
|
||||||
|
|
||||||
//measure and return amount of free SRAM
|
|
||||||
/*
|
|
||||||
uint16_t getFreeSRAM()
|
|
||||||
{
|
|
||||||
uint8_t newVariable;
|
|
||||||
// if heap is empty, use bss as start memory address
|
|
||||||
if ((uint16_t)__brkval == 0)
|
|
||||||
{
|
|
||||||
return (((uint16_t)&newVariable) - ((uint16_t)&__bss_end));
|
|
||||||
}
|
|
||||||
// else use heap end as the start of the memory address
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (((uint16_t)&newVariable) - ((uint16_t)__brkval));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
// uint32_t for Teensy LC
|
|
||||||
uint32_t getFreeSRAM()
|
|
||||||
{
|
|
||||||
uint8_t newVariable;
|
|
||||||
// if heap is empty, use bss as start memory address
|
|
||||||
if ((uint32_t)__brkval == 0)
|
|
||||||
{
|
|
||||||
return (((uint32_t)&newVariable) - ((uint32_t)&__bss_end));
|
|
||||||
}
|
|
||||||
// else use heap end as the start of the memory address
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (((uint32_t)&newVariable) - ((uint32_t)__brkval));
|
|
||||||
}
|
|
||||||
};
|
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
49
tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* keybrd_1_breadboard.ino
|
||||||
|
|
||||||
|
| Layout | **0** | **1** |
|
||||||
|
|:------:|-------|-------|
|
||||||
|
| **0** | 1 | a |
|
||||||
|
| **1** | b | c |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <ScanDelay.h>
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
#include <Row_uC.h>
|
||||||
|
|
||||||
|
// ============ SPEED CONFIGURATION ============
|
||||||
|
ScanDelay scanDelay(9000);
|
||||||
|
|
||||||
|
// ================ ACTIVE STATE ===============
|
||||||
|
const bool Scanner_uC::STROBE_ON = LOW;
|
||||||
|
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||||
|
|
||||||
|
// =================== PINS ====================
|
||||||
|
uint8_t readPins[] = {14, 15};
|
||||||
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
|
||||||
|
// =================== ROWS ====================
|
||||||
|
Key* ptrsKeys_0[] = { &s_1, &s_a };
|
||||||
|
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_1[] = { &s_b, &s_c };
|
||||||
|
Row_uC row_1(1, readPins, READ_PIN_COUNT, ptrsKeys_1);
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
row_0.process();
|
||||||
|
row_1.process();
|
||||||
|
scanDelay.delay();
|
||||||
|
}
|
BIN
tutorials/keybrd_1_breadboard/switch_orientation.JPG
Normal file
After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 25 KiB |
@ -14,15 +14,14 @@ This layout table shows how keys are arranged on the keyboard:
|
|||||||
The layout's row and column numbers are in the headers.
|
The layout's row and column numbers are in the headers.
|
||||||
Each cell in the table's body represents a key.
|
Each cell in the table's body represents a key.
|
||||||
|
|
||||||
The sketch is annotated with a walk-through narrative enclosed in comment blocks.
|
The following sketch is annotated with a walk-through narrative enclosed in comment blocks.
|
||||||
Each comment block explains the next one or two lines of code.
|
Each comment block explains the next one or two lines of code.
|
||||||
|
|
||||||
keybrd objects are instantiated under the "GLOBAL" heading.
|
keybrd objects are instantiated under the "GLOBAL" heading.
|
||||||
The keyboard runs at the end of the sketch, under the "MAIN" heading.
|
The keyboard runs at the end of the sketch, under the "MAIN" heading.
|
||||||
*/
|
*/
|
||||||
// ################## GLOBAL ###################
|
// ################## GLOBAL ###################
|
||||||
// ================= INCLUDES ==================
|
/* ================= INCLUDES ==================
|
||||||
/*
|
|
||||||
All the includes in this sketch are to keybrd library classes.
|
All the includes in this sketch are to keybrd library classes.
|
||||||
*/
|
*/
|
||||||
#include <ScanDelay.h>
|
#include <ScanDelay.h>
|
||||||
@ -43,7 +42,7 @@ STROBE_ON and STROBE_OFF define the logic levels for the strobe.
|
|||||||
"Active low" means that if a switch is pressed (active), the read pin is low.
|
"Active low" means that if a switch is pressed (active), the read pin is low.
|
||||||
To make this sketch active low, STROBE_ON should be LOW (tutorial 6 coveres this in more detail).
|
To make this sketch active low, STROBE_ON should be LOW (tutorial 6 coveres this in more detail).
|
||||||
*/
|
*/
|
||||||
const bool Scanner_uC::STROBE_ON = LOW; //set matrix for active low
|
const bool Scanner_uC::STROBE_ON = LOW; //set scanner for active low
|
||||||
const bool Scanner_uC::STROBE_OFF = HIGH;
|
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||||
|
|
||||||
/* ================= PINS =================
|
/* ================= PINS =================
|
||||||
@ -51,7 +50,8 @@ Micro-controller 14 and 15 are connected to the matrix columns.
|
|||||||
These readPins detect which keys are pressed while a row is strobed.
|
These readPins detect which keys are pressed while a row is strobed.
|
||||||
|
|
||||||
sizeof() is used to compute the number of array elements.
|
sizeof() is used to compute the number of array elements.
|
||||||
This eliminates the risk of forgetting to update the count after adding or removing an element.
|
This eliminates the risk of forgetting to update the count
|
||||||
|
after adding or removing an element from the array.
|
||||||
*/
|
*/
|
||||||
uint8_t readPins[] = {14, 15};
|
uint8_t readPins[] = {14, 15};
|
||||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
@ -69,11 +69,11 @@ Code_Sc s_c(KEY_C);
|
|||||||
Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT);
|
Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT);
|
||||||
|
|
||||||
/* =================== ROWS ====================
|
/* =================== ROWS ====================
|
||||||
Here we pack Code objects into row objects.
|
Here we pack Code objects into Row objects.
|
||||||
The Row objects names in this sketch start with a "row_" followed by a row number.
|
The Row objects names in this sketch start with a "row_" followed by a row number.
|
||||||
|
|
||||||
Row_uC constructor has four parameters:
|
Row_uC constructor has four parameters:
|
||||||
1) stobePin connected to the row.
|
1) strobePin connected to the row.
|
||||||
2) readPins[] connected to the colums.
|
2) readPins[] connected to the colums.
|
||||||
3) the number of readPins.
|
3) the number of readPins.
|
||||||
4) ptrsKeys[] containing all the Code objects of the row, one Code object per key.
|
4) ptrsKeys[] containing all the Code objects of the row, one Code object per key.
|
||||||
@ -95,7 +95,7 @@ void setup()
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
loop() continually scans the matrix, one row at a time.
|
loop() continually scans the matrix, one row at a time.
|
||||||
Each row object strobes the strobePin and reads the readPins.
|
Each row object strobes its strobePin and reads the readPins.
|
||||||
And when a key press is detected, the row sends the key's scancode.
|
And when a key press is detected, the row sends the key's scancode.
|
||||||
|
|
||||||
scanDelay creates time intervals between matrix scans.
|
scanDelay creates time intervals between matrix scans.
|
||||||
|
@ -11,7 +11,7 @@ This sketch:
|
|||||||
|
|
||||||
Each cell in the table's body represents a key.
|
Each cell in the table's body represents a key.
|
||||||
The layered keys in row 0 have two layers; one character for each layer.
|
The layered keys in row 0 have two layers; one character for each layer.
|
||||||
Letters 'a' and 'b' are on the normal layer. Numbers '1' and '2' are one the fn 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.
|
Holding the fn key down makes it the active layer. Releasing the fn key restores the normal layer.
|
||||||
*/
|
*/
|
||||||
// ################## GLOBAL ###################
|
// ################## GLOBAL ###################
|
||||||
@ -53,7 +53,7 @@ LayerState layerState;
|
|||||||
NORMAL=0 and FN=1. LayerState's default layer id is 0.
|
NORMAL=0 and FN=1. LayerState's default layer id is 0.
|
||||||
The Code_LayerHold constructor has two parameters:
|
The Code_LayerHold constructor has two parameters:
|
||||||
1) the layer that will be active while the key is held down.
|
1) the layer that will be active while the key is held down.
|
||||||
2) the LayerState
|
2) a LayerState
|
||||||
When l_fn is pressed, it tells layerState to change the active layer to 1.
|
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.
|
When l_fn is released, it tells layerState that layer 1 is released, and layerState restores the default layer.
|
||||||
*/
|
*/
|
||||||
@ -72,7 +72,7 @@ The Key_LayeredKeysArray constructor takes one array of Code pointers - one Code
|
|||||||
Key_LayeredKeysArray uses layer id numbers as array indexes.
|
Key_LayeredKeysArray uses layer id numbers as array indexes.
|
||||||
Thus Key_LayeredKeysArray calls the Code corresponding to the active layer id.
|
Thus Key_LayeredKeysArray calls the Code corresponding to the active layer id.
|
||||||
|
|
||||||
The Key object names in this sketch start with a "k_" followed by matrix-row-column coordinates.
|
The Key object names in this sketch start with a "k_" followed by row-column coordinates.
|
||||||
*/
|
*/
|
||||||
Key* const ptrsCodes_01[] = { &s_a, &s_1 };
|
Key* const ptrsCodes_01[] = { &s_a, &s_1 };
|
||||||
Key_LayeredKeysArray k_01(ptrsCodes_01);
|
Key_LayeredKeysArray k_01(ptrsCodes_01);
|
||||||
@ -94,8 +94,8 @@ It then uses the layer id as an array index to send the scancode for the active
|
|||||||
Here we pack Key pointers into row objects.
|
Here we pack Key pointers into row objects.
|
||||||
|
|
||||||
Codes are a kind of Key that only have one layer.
|
Codes are a kind of Key that only have one layer.
|
||||||
So rows can contain a mix of multi-layered keys and codes.
|
So rows can contain a mix of codes and multi-layered keys.
|
||||||
Arrays ptrsKeys_0[] and ptrsKeys_1[] contain both Key pointers and Code pointers.
|
Arrays ptrsKeys_0[] and ptrsKeys_1[] contain both Code pointers and Key pointers.
|
||||||
*/
|
*/
|
||||||
Key* const ptrsKeys_0[] = { &s_shift, &k_01 };
|
Key* const ptrsKeys_0[] = { &s_shift, &k_01 };
|
||||||
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
/* tutorial_4a_split_keyboard_with_shift_registers.ino
|
|
||||||
Tested on Teensy LC and two 74HC165 shift registers.
|
|
||||||
|
|
||||||
The right matrix has 2 shift registers daisy chained.
|
|
||||||
Every 4th input pin has a pull-up resistor and matrix column.
|
|
||||||
Unused input pins are powered.
|
|
||||||
|
|
||||||
Layout Layout
|
|
||||||
| Left | **0**| | Right |**0**|**1**|**2**|**3**|
|
|
||||||
|:-----:|------| |:-----:|-----|-----|-----|-----|
|
|
||||||
| **0** | x | | **0** | 0 | 1 | 2 | 3 |
|
|
||||||
| **1** | y | | **1** | a | b | c | d |
|
|
||||||
*/
|
|
||||||
// ################## GLOBAL ###################
|
|
||||||
// ================= INCLUDES ==================
|
|
||||||
//Codes
|
|
||||||
#include <Code_Sc.h>
|
|
||||||
#include <Code_LEDLock.h>
|
|
||||||
|
|
||||||
//Matrix
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <Row_uC.h>
|
|
||||||
#include <Row_ShiftRegisters.h>
|
|
||||||
#include <ScanDelay.h>
|
|
||||||
|
|
||||||
// =============== CONFIGURATION ===============
|
|
||||||
ScanDelay scanDelay(9000);
|
|
||||||
|
|
||||||
//set left matrix for active low
|
|
||||||
const bool Scanner_uC::STROBE_ON = LOW;
|
|
||||||
const bool Scanner_uC::STROBE_OFF = HIGH;
|
|
||||||
|
|
||||||
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
|
|
||||||
|
|
||||||
//set right matrix for active low
|
|
||||||
const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW;
|
|
||||||
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH;
|
|
||||||
|
|
||||||
// ================= LEFT PINS =================
|
|
||||||
uint8_t readPins[] = {14};
|
|
||||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
|
||||||
|
|
||||||
// =================== CODES ===================
|
|
||||||
Code_Sc s_a(KEY_A);
|
|
||||||
Code_Sc s_b(KEY_B);
|
|
||||||
Code_Sc s_c(KEY_C);
|
|
||||||
Code_Sc s_d(KEY_D);
|
|
||||||
|
|
||||||
Code_Sc s_x(KEY_X);
|
|
||||||
Code_Sc s_y(KEY_Y);
|
|
||||||
|
|
||||||
Code_Sc s_z(KEY_Z);
|
|
||||||
|
|
||||||
Code_Sc s_0(KEY_0);
|
|
||||||
Code_Sc s_1(KEY_1);
|
|
||||||
Code_Sc s_2(KEY_2);
|
|
||||||
Code_Sc s_3(KEY_3);
|
|
||||||
|
|
||||||
// ================= LEFT ROWS =================
|
|
||||||
Key* ptrsKeys_L0[] = { &s_x };
|
|
||||||
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
|
||||||
|
|
||||||
Key* ptrsKeys_L1[] = { &s_y };
|
|
||||||
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
|
||||||
|
|
||||||
/* ================= RIGHT ROWS ================
|
|
||||||
Instantiating a Row_ShiftRegistersis similar to instantiating a Row_uC.
|
|
||||||
|
|
||||||
The s_z are place holders where the input pins are powered; they should not send scancodes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//should send 0 1 2 3
|
|
||||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
|
||||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R0(0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
|
||||||
|
|
||||||
//should send a b c d
|
|
||||||
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z,
|
|
||||||
&s_c, &s_z, &s_z, &s_z, &s_d, &s_z, &s_z, &s_z };
|
|
||||||
Row_ShiftRegisters row_R1(1, sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1), ptrsKeys_R1);
|
|
||||||
|
|
||||||
// ################### MAIN ####################
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Keyboard.begin();
|
|
||||||
SPI.begin();
|
|
||||||
row_R0.begin();
|
|
||||||
row_R1.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
//left matrix
|
|
||||||
row_L0.process();
|
|
||||||
row_L1.process();
|
|
||||||
|
|
||||||
//right matrix
|
|
||||||
row_R0.process();
|
|
||||||
row_R1.process();
|
|
||||||
|
|
||||||
scanDelay.delay();
|
|
||||||
}
|
|
Before Width: | Height: | Size: 174 KiB |
Before Width: | Height: | Size: 219 KiB |
Before Width: | Height: | Size: 140 KiB |
@ -1,158 +0,0 @@
|
|||||||
/* keybrd_4_split_with_IOE_annotated.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:
|
|
||||||
|
|
||||||
| Left | **0** | **1** | | Right | **0** | **1** |
|
|
||||||
|:-----:|-------|-------|-|:-----:|-------|-------|
|
|
||||||
| **0** | a | b | | **0** | 1 | 2 |
|
|
||||||
| **1** | shift | c | | **1** | 3 | shift |
|
|
||||||
|
|
||||||
MARTIX NAMING CONVENTION
|
|
||||||
Since this keyboard has two matrices, we need a naming convention to distinguish the matrices.
|
|
||||||
Matrix IDs are the letters 'L' and 'R' (left and right).
|
|
||||||
Port object names and Port pointer array names end with matrix ID:
|
|
||||||
port1_R
|
|
||||||
rowPortF_L rowPort1_R
|
|
||||||
port0_R
|
|
||||||
colPortB_L colPort0_R
|
|
||||||
ptrsColPorts_L ptrsColPorts_R
|
|
||||||
COL_PORT_L_COUNT COL_PORT_R_COUNT
|
|
||||||
|
|
||||||
Key pointer array names and Row objects names end with matrix ID and row number:
|
|
||||||
ptrsKeys_L0 ptrsKeys_R0
|
|
||||||
row_L0 row_R0
|
|
||||||
|
|
||||||
Matrix object names end with matrix ID:
|
|
||||||
matrix_L matrix_R
|
|
||||||
*/
|
|
||||||
// ################## GLOBAL ###################
|
|
||||||
// ================= INCLUDES ==================
|
|
||||||
//Ports
|
|
||||||
#include <RowPort_AVR_Optic.h>
|
|
||||||
#include <ColPort_AVR.h>
|
|
||||||
#include <IOExpanderPort.h>
|
|
||||||
#include <RowPort_PCA9655E.h>
|
|
||||||
#include <ColPort_PCA9655E.h>
|
|
||||||
|
|
||||||
//Codes
|
|
||||||
#include <Code_Sc.h>
|
|
||||||
|
|
||||||
//Matrix
|
|
||||||
#include <Row.h>
|
|
||||||
#include <Matrix.h>
|
|
||||||
|
|
||||||
// ============ SPEED CONFIGURATIONS ============
|
|
||||||
const unsigned int Row::DELAY_MICROSECONDS = 1000;
|
|
||||||
|
|
||||||
// ================ LEFT PORTS =================
|
|
||||||
/*
|
|
||||||
The left matrix is scanned by a micro-controller.
|
|
||||||
*/
|
|
||||||
RowPort_AVR_Optic rowPortF_L(DDRF, PORTF);
|
|
||||||
|
|
||||||
ColPort_AVR colPortB_L(DDRB, PORTB, PINB, 1<<0 | 1<<1 );
|
|
||||||
ColPort* const ptrsColPorts_L[] = { &colPortB_L };
|
|
||||||
const uint8_t COL_PORT_L_COUNT = sizeof(ptrsColPorts_L)/sizeof(*ptrsColPorts_L);
|
|
||||||
|
|
||||||
// =============== RIGHT PORTS =================
|
|
||||||
/*
|
|
||||||
The right matrix is scanned by an I/O expander.
|
|
||||||
|
|
||||||
I/O expander I2C address is configured by hardware pins.
|
|
||||||
ADDR is a static variable of class IOExpanderPort.
|
|
||||||
*/
|
|
||||||
const uint8_t IOExpanderPort::ADDR = 0x18;
|
|
||||||
|
|
||||||
/*
|
|
||||||
The I/O expander has two ports. Each port has eight pins.
|
|
||||||
One port is connected to the matrix's rows. The other port is connected to the matrix's columns.
|
|
||||||
|
|
||||||
The IOExpanderPort constructor parameters specify the port number and initial output value.
|
|
||||||
|
|
||||||
port1_R is port 1 and has an initial output value of 0.
|
|
||||||
rowPort1_R uses port1_R.
|
|
||||||
*/
|
|
||||||
IOExpanderPort port1_R(1, 0);
|
|
||||||
RowPort_PCA9655E rowPort1_R(port1_R);
|
|
||||||
|
|
||||||
/*
|
|
||||||
port0_R is port 0 and has an initial output value of 0.
|
|
||||||
colPort0_R uses port0_R to read pin 0 and pin 1.
|
|
||||||
*/
|
|
||||||
IOExpanderPort port0_R(0, 0);
|
|
||||||
ColPort_PCA9655E colPort0_R(port0_R, 1<<0 | 1<<1 );
|
|
||||||
|
|
||||||
/*
|
|
||||||
ColPort pointers are packed into an array.
|
|
||||||
*/
|
|
||||||
ColPort* const ptrsColPorts_R[] = { &colPort0_R };
|
|
||||||
const uint8_t COL_PORT_R_COUNT = sizeof(ptrsColPorts_R)/sizeof(*ptrsColPorts_R);
|
|
||||||
|
|
||||||
// =================== CODES ===================
|
|
||||||
/*
|
|
||||||
Codes are not grouped into left and right because codes are independent of layout.
|
|
||||||
- a keyboard can have differnt layouts
|
|
||||||
- some codes may appear on both matrices
|
|
||||||
*/
|
|
||||||
Code_Sc s_shiftL(MODIFIERKEY_LEFT_SHIFT);
|
|
||||||
Code_Sc s_shiftR(MODIFIERKEY_RIGHT_SHIFT);
|
|
||||||
|
|
||||||
Code_Sc s_a(KEY_A);
|
|
||||||
Code_Sc s_b(KEY_B);
|
|
||||||
Code_Sc s_c(KEY_C);
|
|
||||||
Code_Sc s_1(KEY_1);
|
|
||||||
Code_Sc s_2(KEY_2);
|
|
||||||
Code_Sc s_3(KEY_3);
|
|
||||||
|
|
||||||
// ================ LEFT MATRIX ================
|
|
||||||
// ---------------- LEFT ROWS ------------------
|
|
||||||
Key* const ptrsKeys_L0[] = { &s_a, &s_b };
|
|
||||||
Row row_L0(rowPortF_L, 1<<0, ptrsColPorts_L, COL_PORT_L_COUNT, ptrsKeys_L0);
|
|
||||||
|
|
||||||
Key* const ptrsKeys_L1[] = { &s_c, &s_shiftL };
|
|
||||||
Row row_L1(rowPortF_L, 1<<1, ptrsColPorts_L, COL_PORT_L_COUNT, ptrsKeys_L1);
|
|
||||||
|
|
||||||
// ---------------- LEFT MATRIX ----------------
|
|
||||||
Row* const ptrsRows_L[] = { &row_L0, &row_L1 };
|
|
||||||
const uint8_t ROW_L_COUNT = sizeof(ptrsRows_L)/sizeof(*ptrsRows_L);
|
|
||||||
|
|
||||||
Matrix matrix_L(ptrsRows_L, ROW_L_COUNT, 1);
|
|
||||||
|
|
||||||
// ================ RIGHT MATRIX ===============
|
|
||||||
// ---------------- RIGHT ROWS -----------------
|
|
||||||
Key* const ptrsKeys_R0[] = { &s_1, &s_2 };
|
|
||||||
Row row_R0(rowPort1_R, 1<<0, ptrsColPorts_R, COL_PORT_R_COUNT, ptrsKeys_R0);
|
|
||||||
|
|
||||||
Key* const ptrsKeys_R1[] = { &s_3, &s_shiftR };
|
|
||||||
Row row_R1(rowPort1_R, 1<<1, ptrsColPorts_R, COL_PORT_R_COUNT, ptrsKeys_R1);
|
|
||||||
|
|
||||||
// ---------------- RIGHT MATRIX ---------------
|
|
||||||
Row* const ptrsRows_R[] = { &row_R0, &row_R1 };
|
|
||||||
const uint8_t ROW_R_COUNT = sizeof(ptrsRows_R)/sizeof(*ptrsRows_R);
|
|
||||||
|
|
||||||
Matrix matrix_R(ptrsRows_R, ROW_R_COUNT, 1);
|
|
||||||
|
|
||||||
// ################### MAIN ####################
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Call begin() for I/O expander's rowPort and colPort.
|
|
||||||
*/
|
|
||||||
rowPort1_R.begin();
|
|
||||||
colPort0_R.begin();
|
|
||||||
Keyboard.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
loop() continually scans both Matrix objects.
|
|
||||||
*/
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
matrix_L.scan();
|
|
||||||
matrix_R.scan();
|
|
||||||
}
|
|
@ -35,8 +35,8 @@ uint8_t readPins[] = {14, 15};
|
|||||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
/* ==================== LEDs ===================
|
/* ==================== LEDs ===================
|
||||||
The LED_uC constructor parameter is for an Aduino pin that is connected to an LED.
|
The LED_uC constructor parameter is for an Aduino pin number that is connected to an LED.
|
||||||
LED_uC objects are passed to other objects that want to turn the LED on or off.
|
LED objects are passed to other objects that want to turn the LED on or off.
|
||||||
In this example, the LED_uC objects are named after the states they indicate.
|
In this example, the LED_uC objects are named after the states they indicate.
|
||||||
|
|
||||||
The prtsLayerLEDs[] array contains one LED per layer, it is used to indicate the current layer.
|
The prtsLayerLEDs[] array contains one LED per layer, it is used to indicate the current layer.
|
||||||
@ -60,7 +60,7 @@ LayerState_LED layerState(prtsLayerLEDs);
|
|||||||
Code_LayerHold l_fn(FN, layerState);
|
Code_LayerHold l_fn(FN, layerState);
|
||||||
|
|
||||||
/* ---------------- SCAN CODES -----------------
|
/* ---------------- SCAN CODES -----------------
|
||||||
When a Code_LEDLock object is pressed, it sends a scancodes and updates the its LED.
|
When a Code_LEDLock object is pressed, it sends its scancode and updates the its LED.
|
||||||
Scancodes can be one of KEY_CAPS_LOCK, KEY_SCROLL_LOCK, or KEY_NUM_LOCK.
|
Scancodes can be one of KEY_CAPS_LOCK, KEY_SCROLL_LOCK, or KEY_NUM_LOCK.
|
||||||
For example, when o_capsLock is pressed, it sends KEY_CAPS_LOCK scancode and updates LED_CapsLck.
|
For example, when o_capsLock is pressed, it sends KEY_CAPS_LOCK scancode and updates LED_CapsLck.
|
||||||
*/
|
*/
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/* keybrd_6_active_high.ino
|
/* keybrd_6_active_high.ino
|
||||||
|
|
||||||
This sketch:
|
This sketch:
|
||||||
is the tutorial 2 sketch with STROBE_ON/STROBE_OFF values swapped
|
is the tutorial 1 sketch with STROBE_ON/STROBE_OFF values swapped
|
||||||
is active high 1-layer keyboard
|
is active high 1-layer keyboard
|
||||||
runs on the first two rows and columns of a active-high breadboard keyboard
|
runs on the first two rows and columns of a active-high breadboard keyboard
|
||||||
|
|
||||||
| Layout | **0** | **1** |
|
| Layout | **0** | **1** |
|
||||||
|:------:|-------|-------|
|
|:------:|-------|-------|
|
||||||
| **0** | shift | a |
|
| **0** | 1 | a |
|
||||||
| **1** | b | c |
|
| **1** | b | c |
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -35,13 +35,13 @@ uint8_t readPins[] = {14, 15};
|
|||||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
// =================== CODES ===================
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
Code_Sc s_a(KEY_A);
|
Code_Sc s_a(KEY_A);
|
||||||
Code_Sc s_b(KEY_B);
|
Code_Sc s_b(KEY_B);
|
||||||
Code_Sc s_c(KEY_C);
|
Code_Sc s_c(KEY_C);
|
||||||
Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT);
|
|
||||||
|
|
||||||
// =================== ROWS ====================
|
// =================== ROWS ====================
|
||||||
Key* ptrsKeys_0[] = { &s_shift, &s_a };
|
Key* ptrsKeys_0[] = { &s_1, &s_a };
|
||||||
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||||
|
|
||||||
Key* ptrsKeys_1[] = { &s_b, &s_c };
|
Key* ptrsKeys_1[] = { &s_b, &s_c };
|
||||||
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 198 KiB |
@ -12,4 +12,5 @@ The tutorials assume the reader:
|
|||||||
* is familiar with C++
|
* is familiar with C++
|
||||||
* is new to Arduino, firmware, controllers, and the internal workings of keyboards
|
* is new to Arduino, firmware, controllers, and the internal workings of keyboards
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
Tutorial 8 - writing your own port classes
|
Tutorial 10 - writing your own port classes
|
||||||
==========================================
|
===========================================
|
||||||
Port classes are the keybrd library's interface to microcontoller ports and I/O expander ports.
|
Port classes are the keybrd library's interface to I/O expander ports.
|
||||||
|
|
||||||
To write your own port classes:
|
To write your own port classes:
|
||||||
1) Get a copy of the controller or I/O expander datasheet.
|
1. Get a copy of the controller or I/O expander datasheet.
|
||||||
2) Study keybrd port classes that use a similar IC.
|
2. Study other keybrd Port classes.
|
||||||
3) Consider looking for other open-source keyboard code that uses the same IC e.g. TMK keyboard firmware.
|
|
||||||
4) Write your RowPort_* class to inherit from RowPort class.
|
|
||||||
5) Write your ColPort_* class to inherit from ColPort class.
|
|
||||||
|
|
||||||
Writing port classes is the most technically demanding task in the keybrd library.
|
For example, the keybrd_DH library use these keybrd classes for its PCA9655E I/O:
|
||||||
It might be faster to designing your keyboard around one of the controllers or I/O expanders that already have port classes in the keybrd library.
|
* PortWrite_PCA9655E
|
||||||
|
* PortRead_PCA9655E
|
||||||
|
* LED_PCA9655E
|
||||||
|
|
||||||
|
Debugging I/O expander code is hard because SPI or I2C protocol adds a level of indirection.
|
||||||
|
If you haven't written Arduino code for an I/O expander before, learn from an Arduiono I/O expander tutorial before attempting it here.
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -5,11 +5,11 @@ The keyboad will be used in tutorials 2 through 7.
|
|||||||
|
|
||||||
When you finish this tutorial you will have a working keyboard and understand how a key matrix works.
|
When you finish this tutorial you will have a working keyboard and understand how a key matrix works.
|
||||||
|
|
||||||
## Why a solderless breadboard keyboard is useful
|
Why a solderless breadboard keyboard is useful
|
||||||
Breadboard keyboards have row-column matrices and diodes just like the big keyboards.
|
----------------------------------------------
|
||||||
|
Breadboard keyboards have key matrices and diodes just like the big keyboards.
|
||||||
|
|
||||||
A breadboard is the easiest way to learn keyboard electronics.
|
A breadboard is the easiest way to learn keyboard electronics.
|
||||||
A novice won't get everything right the first time.
|
|
||||||
Learning is fun when mistakes are easily corrected.
|
Learning is fun when mistakes are easily corrected.
|
||||||
Compared to PCBs, breadboard keyboards make learning faster because:
|
Compared to PCBs, breadboard keyboards make learning faster because:
|
||||||
* Mistakes are easily corrected; no soldering and desoldering
|
* Mistakes are easily corrected; no soldering and desoldering
|
||||||
@ -17,38 +17,37 @@ Compared to PCBs, breadboard keyboards make learning faster because:
|
|||||||
* A small keyboard is easier to trouble shoot
|
* A small keyboard is easier to trouble shoot
|
||||||
|
|
||||||
Breadboard keyboards are useful for:
|
Breadboard keyboards are useful for:
|
||||||
* learning keyboard electronics - micro controllers, diodes, shift registers, I/O expanders
|
* learning keyboard electronics - micro controller, key matrix, diode, shift registers, I/O expander
|
||||||
* learning the firmware development workflow
|
* learning the firmware development workflow
|
||||||
* prototyping circuits before making a PCB
|
* prototyping circuits before making a PCB
|
||||||
|
|
||||||
Arduino simulation software might be another way; I haven't tried that.
|
Arduino simulation software is an alternative to breadboards; I haven't tried that.
|
||||||
|
|
||||||
## Breadboard keyboard starter kit
|
Breadboard keyboard starter kit
|
||||||
|
-------------------------------
|
||||||
The parts needed to build the tutorial Breadboard Keyboards are listed in [breadboard_keyboard_supplies.ods](breadboard_keyboard_supplies.ods).
|
The parts needed to build the tutorial Breadboard Keyboards are listed in [breadboard_keyboard_supplies.ods](breadboard_keyboard_supplies.ods).
|
||||||
|
|
||||||
The tutorials use a Teensy LC controller, but any Arduino-compatible controller should work.
|
The tutorials use a Teensy LC controller, but any Arduino-compatible controller with SRAM should work.
|
||||||
|
|
||||||
You will need two tools:
|
You will need two tools:
|
||||||
* Wire cutters (or nail clipper)
|
* Wire cutters
|
||||||
* A multi-meter for trouble shooting
|
* A multi-meter for trouble shooting
|
||||||
|
|
||||||
Wire striper and lead forming tool are optional.
|
Wire striper and lead forming tool are optional.
|
||||||
|
|
||||||
## How a breadboard works
|
How a breadboard works
|
||||||
|
----------------------
|
||||||
To understand the breadboard keyboard you will need to know the internal parts of a breadboard:
|
To understand the breadboard keyboard you will need to know the internal parts of a breadboard:
|
||||||
* bus strip
|
* bus strip
|
||||||
* terminal strip
|
* terminal strip
|
||||||
|
|
||||||
These are explained in [How to Use a Breadboard](https://learn.sparkfun.com/tutorials/how-to-use-a-breadboard)
|
These are explained in [How to Use a Breadboard](https://learn.sparkfun.com/tutorials/how-to-use-a-breadboard)
|
||||||
|
|
||||||
## How a keyboard matrix works
|
Building a basic breadboard keyboard
|
||||||
This excellent article explains how the microcontroller, matrix, switches and diodes work together:
|
------------------------------------
|
||||||
[How a Key Matrix Work](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/)
|
|
||||||
|
|
||||||
## Building a basic breadboard keyboard
|
|
||||||
The basic breadboard keyboard has 4 switches.
|
The basic breadboard keyboard has 4 switches.
|
||||||
|
|
||||||
![basic breadboard keyboard](keybrd_1_breadboard_images/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
![basic breadboard keyboard](keybrd_1_breadboard/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
||||||
|
|
||||||
A Teensy LC microcontroller in on the left.
|
A Teensy LC microcontroller in on the left.
|
||||||
A key matrix with 4 switches is to the right.
|
A key matrix with 4 switches is to the right.
|
||||||
@ -57,8 +56,7 @@ The key matrix has two two columns.
|
|||||||
Short wires connect terminal strips into matrix columns.
|
Short wires connect terminal strips into matrix columns.
|
||||||
Jumper wires connect the columns to the microcontroller.
|
Jumper wires connect the columns to the microcontroller.
|
||||||
|
|
||||||
The key matrix has two two rows.
|
Two bus strips are used as matrix rows.
|
||||||
Breadboard bus strips are matrix rows.
|
|
||||||
A jumper connects the top row to the microcontroller.
|
A jumper connects the top row to the microcontroller.
|
||||||
A short wire connects the bottom row to the microcontroller.
|
A short wire connects the bottom row to the microcontroller.
|
||||||
|
|
||||||
@ -66,9 +64,7 @@ Switch-diode pairs, in series, connect rows to columns.
|
|||||||
|
|
||||||
Tutorials 2 and 3 use the basic breadboard keyboard pictured above.
|
Tutorials 2 and 3 use the basic breadboard keyboard pictured above.
|
||||||
Tutorials 4, 5, and 6 will add more components to the basic breadboard keyboard.
|
Tutorials 4, 5, and 6 will add more components to the basic breadboard keyboard.
|
||||||
Positioning components as shown on the picture will provide space for those components.
|
Positioning components as shown in the picture will provide space for those components.
|
||||||
|
|
||||||
![pic of shift registers, LEDs, active high on one bb]
|
|
||||||
|
|
||||||
Breadboard keyboard assembly instructions:
|
Breadboard keyboard assembly instructions:
|
||||||
|
|
||||||
@ -76,39 +72,64 @@ Breadboard keyboard assembly instructions:
|
|||||||
* tactile-switch-lead
|
* tactile-switch-lead
|
||||||
* diodes (save the cut offs for steps 2, 3, and tutorial 4)
|
* diodes (save the cut offs for steps 2, 3, and tutorial 4)
|
||||||
|
|
||||||
![bend diodes](keybrd_1_breadboard_images/diodes_bend_en_masse.JPG "bend diodes")
|
![bend diodes](keybrd_1_breadboard/diodes_bend_en_masse.JPG "bend diodes")
|
||||||
|
|
||||||
![cut diodes](keybrd_1_breadboard_images/diodes_cut.JPG "cut diodes")
|
![cut diodes](keybrd_1_breadboard/diodes_cut.JPG "cut diodes")
|
||||||
|
|
||||||
2. Insert parts into the breadboard as shown in the picture.
|
2. Insert parts into the breadboard as shown in the picture.
|
||||||
* The breadboard is oriented with the red bus strips on top and blue bus strips on the bottom
|
* The breadboard is oriented with the red bus strips on top and blue bus strips on the bottom
|
||||||
(this is important because tutorials will refer to the "red bus" and the "blue bus")
|
(this is important because tutorials will refer to the "red bus" and the "blue bus")
|
||||||
* Teensy LC is positioned such that:
|
* Teensy LC is on the left
|
||||||
* terminal strips above Teensy have three holes exposed
|
|
||||||
* terminal strips below Teensy have two holes exposed
|
|
||||||
(the holes will be used in later tutorials)
|
|
||||||
* switch leads are oriented to connect diodes to columns (pictured below)
|
* switch leads are oriented to connect diodes to columns (pictured below)
|
||||||
* diode cut offs connect terminal strips into columns
|
* diode cut offs connect terminal strips into columns
|
||||||
* diodes connect to the blue bus, orient with cathode (banded end) towards the row (bus strip)
|
* diodes connect switches to blue buses, orient with cathode (banded end) towards the row (bus strip)
|
||||||
|
|
||||||
![switch orientation](keybrd_1_breadboard_images/switch_orientation.JPG "switch orientation")
|
![switch orientation](keybrd_1_breadboard/switch_orientation.JPG "switch orientation")
|
||||||
![basic breadboard keyboard overhead](keybrd_1_breadboard_images/breadboard_keyboard_2x2_overhead.JPG "basic breadboard keyboard overhead")
|
|
||||||
|
![basic breadboard keyboard overhead](keybrd_1_breadboard/breadboard_keyboard_2x2_overhead.JPG "basic breadboard keyboard overhead")
|
||||||
|
|
||||||
3. Insert jumper wires to connect Arduino pins to the matrix rows and columns.
|
3. Insert jumper wires to connect Arduino pins to the matrix rows and columns.
|
||||||
* [Teensy LC pinout diagram](https://www.pjrc.com/teensy/card6a_rev2.png).
|
* [Teensy LC pinout diagram](https://www.pjrc.com/teensy/card6a_rev2.png).
|
||||||
* row_0 is the top row, and col_0 is the left column
|
* row_0 is the top row, and col_0 is the left column
|
||||||
|
|
||||||
| Pin number | connected to |
|
| Pin number | Connects to |
|
||||||
|------------|--------------|
|
|------------|-------------|
|
||||||
| 0 | row_0 |
|
| 0 | row_0 |
|
||||||
| 1 | row_1 |
|
| 1 | row_1 |
|
||||||
| 14 | col_0 |
|
| 14 | col_0 |
|
||||||
| 15 | col_1 |
|
| 15 | col_1 |
|
||||||
|
|
||||||
## Compiling and loading the keyboard firmware
|
Compiling and loading the keyboard firmware
|
||||||
|
-------------------------------------------
|
||||||
Follow the [keybrd Library User's Guide](../doc/keybrd_library_user_guide.md) to set up the Arduino environment.
|
Follow the [keybrd Library User's Guide](../doc/keybrd_library_user_guide.md) to set up the Arduino environment.
|
||||||
|
|
||||||
Compile and load the [keybrd_2_single-layer.ino](keybrd_2_single-layer/keybrd_2_single-layer.ino) sketch into the keyboard's controller.
|
Compile and load the [keybrd_1_breadboard.ino](/tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino) sketch into the keyboard's controller.
|
||||||
|
The operating system will take 1 to 6 seconds to recognize the USB keyboard.
|
||||||
|
Then pressing the keys should type the characters 1, a, b, c.
|
||||||
|
|
||||||
<br><br>
|
How a key matrix works
|
||||||
|
----------------------
|
||||||
|
Congratulations, you have a working breadboard keyboard.
|
||||||
|
Now we fill in some details of how it all works.
|
||||||
|
|
||||||
|
This excellent article explains how key matrix, diodes, and ghosting work:
|
||||||
|
[How a Key Matrix Work](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/)
|
||||||
|
|
||||||
|
In the article:
|
||||||
|
|
||||||
|
output pins power columns and input pins detect the power on rows.
|
||||||
|
|
||||||
|
The breadboard keyboards in this series of tutorials do it the other way:
|
||||||
|
|
||||||
|
output pins power rows and input pins detect the power on columns.
|
||||||
|
|
||||||
|
The keybrd library uses the word "strobe".
|
||||||
|
Strobe pins are output pins connected to rows.
|
||||||
|
One row at a time is strobed for the purpose of reading input pins.
|
||||||
|
|
||||||
|
Exercises
|
||||||
|
---------
|
||||||
|
1) replace the diodes with wires (cutoffs) and intentionally cause ghosting.
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -4,13 +4,16 @@ 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_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.
|
||||||
The sketch will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
The sketch will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
||||||
|
|
||||||
![basic breadboard keyboard](keybrd_1_breadboard_images/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
|
||||||
|
|
||||||
Class definitions can be viewed in the [keybrd library](../src/).
|
|
||||||
After reading the sketch you will be able to modify it to suite your own single-layer keyboard design.
|
After reading the sketch you will be able to modify it to suite your own single-layer keyboard design.
|
||||||
|
|
||||||
## Exercises
|
![basic breadboard keyboard](keybrd_1_breadboard/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
||||||
1) Add a third column to the breadboard keyboard and sketch.
|
|
||||||
|
|
||||||
<br><br>
|
Exercises
|
||||||
|
---------
|
||||||
|
1) Read some of the class definitions used in the sketch.
|
||||||
|
The classes are defined in the [keybrd library](../src/).
|
||||||
|
|
||||||
|
2) Add a third column to the breadboard keyboard and sketch.
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -2,7 +2,8 @@ Tutorial 3a - multi-layer keyboard
|
|||||||
==================================
|
==================================
|
||||||
When you finish this tutorial you will be able to be able to modify a multi-layer keybrd sketch to write your very own multi-layer keyboard design.
|
When you finish this tutorial you will be able to be able to modify a multi-layer keybrd sketch to write your very own multi-layer keyboard design.
|
||||||
|
|
||||||
## Multi-layer nomenclature
|
Multi-layer nomenclature
|
||||||
|
------------------------
|
||||||
**[layers](http://deskthority.net/wiki/Layer)** - are key bindings provided by the keyboard firmware. For example,
|
**[layers](http://deskthority.net/wiki/Layer)** - are key bindings provided by the keyboard firmware. For example,
|
||||||
* The classic [IBM PC keyboard](http://en.wikipedia.org/wiki/IBM_PC_keyboard) has one layer.
|
* The classic [IBM PC keyboard](http://en.wikipedia.org/wiki/IBM_PC_keyboard) has one layer.
|
||||||
* Many compact keyboards have an additional [Fn layer](http://en.wikipedia.org/wiki/Fn_key).
|
* Many compact keyboards have an additional [Fn layer](http://en.wikipedia.org/wiki/Fn_key).
|
||||||
@ -14,11 +15,12 @@ When you finish this tutorial you will be able to be able to modify a multi-laye
|
|||||||
|
|
||||||
**layer scheme** - is a system for changing the active layer while typing (a single-layer scheme does not change layers).
|
**layer scheme** - is a system for changing the active layer while typing (a single-layer scheme does not change layers).
|
||||||
|
|
||||||
## A simple multi-layer keybrd sketch
|
A simple multi-layer keybrd sketch
|
||||||
|
----------------------------------
|
||||||
The [keybrd_3a_multi-layer.ino](keybrd_3a_multi-layer/keybrd_3a_multi-layer.ino) sketch is for a simple two-layer keyboard.
|
The [keybrd_3a_multi-layer.ino](keybrd_3a_multi-layer/keybrd_3a_multi-layer.ino) sketch is for a simple two-layer keyboard.
|
||||||
It will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
It will run on the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md).
|
||||||
|
|
||||||
![basic breadboard keyboard](keybrd_1_breadboard_images/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
![basic breadboard keyboard](keybrd_1_breadboard/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
||||||
|
|
||||||
Read the sketch annotations to understand how multi-layer keyboards work.
|
Read the sketch annotations to understand how multi-layer keyboards work.
|
||||||
The sketch uses three layer-scheme classes:
|
The sketch uses three layer-scheme classes:
|
||||||
@ -28,8 +30,9 @@ The sketch uses three layer-scheme classes:
|
|||||||
|
|
||||||
The internal workings of these three classes are revealed in the next section.
|
The internal workings of these three classes are revealed in the next section.
|
||||||
|
|
||||||
## Pseudo code for simple layer scheme
|
Pseudo code for simple layer scheme
|
||||||
The following is pseudo code of three keybrd library classes.
|
-----------------------------------
|
||||||
|
The following pseudo code is of three keybrd library classes.
|
||||||
It has just enough detail to show the internal workings of layer schemes.
|
It has just enough detail to show the internal workings of layer schemes.
|
||||||
|
|
||||||
**Key_Layer** objects change the active layer when pressed.
|
**Key_Layer** objects change the active layer when pressed.
|
||||||
@ -56,7 +59,7 @@ class LayerState
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Key_LayeredKeysArray** objects contain an array of keys, one key for each layer.
|
**Key_LayeredKeysArray** objects contain an array of keys, one key for each layer.
|
||||||
Key_LayeredKeysArray use layer ids as array indexes to send the appropriate key.
|
Key_LayeredKeysArray use layer ids as array indexes.
|
||||||
When a Key_LayeredKeysArray object is pressed, it gets the active layer from LayerState, and sends the corresponding key.
|
When a Key_LayeredKeysArray object is pressed, it gets the active layer from LayerState, and sends the corresponding key.
|
||||||
```
|
```
|
||||||
class Key_LayeredKeysArray
|
class Key_LayeredKeysArray
|
||||||
@ -88,7 +91,8 @@ Dependency diagram
|
|||||||
| Key_LayeredKeysArray |
|
| Key_LayeredKeysArray |
|
||||||
+----------------------+
|
+----------------------+
|
||||||
```
|
```
|
||||||
## Layer-scheme classes
|
Layer-scheme classes
|
||||||
|
--------------------
|
||||||
There are several layer scheme-classes to choose from.
|
There are several layer scheme-classes to choose from.
|
||||||
You can view all the class definitions in the [keybrd library](../src/).
|
You can view all the class definitions in the [keybrd library](../src/).
|
||||||
|
|
||||||
@ -105,7 +109,11 @@ Key_Layered classes include:
|
|||||||
* Code_LayeredCodeSc
|
* Code_LayeredCodeSc
|
||||||
* Code_LayeredCodeCode
|
* Code_LayeredCodeCode
|
||||||
|
|
||||||
## Single-layer Codes
|
The basic LayerState provided by the keybrd library is sufficient for implementing ordinary layer schemes.
|
||||||
|
For experimental layer schemes, you would need to create a custom LayerState class, and possibly Key_Layer and Key_Layered custom layer classes as well.
|
||||||
|
|
||||||
|
Single-layer Codes
|
||||||
|
------------------
|
||||||
Most Code objects only have one scancode or code.
|
Most Code objects only have one scancode or code.
|
||||||
Example single-layer Code classes include:
|
Example single-layer Code classes include:
|
||||||
* Code_Sc
|
* Code_Sc
|
||||||
@ -115,13 +123,15 @@ Example single-layer Code classes include:
|
|||||||
* Code_LayerHold
|
* Code_LayerHold
|
||||||
* Code_LayerLock
|
* Code_LayerLock
|
||||||
|
|
||||||
## Exercises
|
Exercises
|
||||||
|
---------
|
||||||
1) Modify the keybrd_3_multi-layer.ino sketch to use two Code_LayerLock objects.
|
1) Modify the keybrd_3_multi-layer.ino sketch to use two Code_LayerLock objects.
|
||||||
|
|
||||||
| Layout | **0** | **1** |
|
| Layout | **0** | **1** |
|
||||||
|:------:|--------|--------|
|
|:------:|:------:|:------:|
|
||||||
| **0** | a 1 | b 2 |
|
| **0** | a 1 | b 2 |
|
||||||
| **1** | layer0 | layer1 |
|
| **1** | layer0 | layer1 |
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
|
||||||
|
@ -1,24 +1,29 @@
|
|||||||
Tutorial 3b - autoShift
|
Tutorial 3b - autoShift
|
||||||
=======================
|
=======================
|
||||||
Some mulit-layer keyboards have a symbols layer that writes symbols without using the shift key:
|
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 library does this by automatically sending a MODIFIERKEY_SHIFT scancode.
|
||||||
|
|
||||||
The [keybrd_3_autoShift_annotated.ino](keybrd_3_autoShift_annotated/keybrd_3_autoShift_annotated.ino) sketch explains the AutoShift feature.
|
|
||||||
After reading the sketch you too will be able to automatically shifted characters.
|
|
||||||
|
|
||||||
Two keybrd classes use AutoShift:
|
Two keybrd classes use AutoShift:
|
||||||
* Code_ScS
|
* Code_ScS
|
||||||
* Code_ScNS
|
* Code_ScNS
|
||||||
|
|
||||||
## Exercises
|
The [keybrd_3_autoShift.ino](keybrd_3_autoShift/keybrd_3_autoShift.ino) sketch explains the AutoShift feature.
|
||||||
1) Modify the keybrd_3_autoShift_annotated sketch to make a 3-layer keyboard with two Code_LayerHold objects.
|
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.
|
||||||
|
|
||||||
|
![basic breadboard keyboard](keybrd_1_breadboard/breadboard_keyboard_2x2.JPG "basic breadboard keyboard")
|
||||||
|
|
||||||
|
Exercises
|
||||||
|
---------
|
||||||
|
1) Modify the keybrd_3_autoShift_annotated sketch to make a 3-layer keyboard with a default layer and two Code_LayerHold objects.
|
||||||
|
|
||||||
| Layout | **0** | **1** |
|
| Layout | **0** | **1** |
|
||||||
|:------:|-------|-------|
|
|:------:|:-----:|:-----:|
|
||||||
| **0** | a ! 6 | b @ 7 |
|
| **0** | a ! 6 | b @ 7 |
|
||||||
| **1** | sym | num |
|
| **1** |. sym .|. num .|
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
keybrd Tutorial 4b - split keyboard with shift registers
|
|
||||||
========================================================
|
|
||||||
When you finish this tutorial you will be able to be able to modify a 2-matrix keybrd sketch to suite your own split keyboard design.
|
|
||||||
|
|
||||||
## Overview of split keyboard with shift registers
|
|
||||||
The breadboard in the following picture models a split keyboard.
|
|
||||||
|
|
||||||
The primary matrix on the left has one column, which is read by a microcontroller pin.
|
|
||||||
The secondary matrix on the right has 4 columns, which are read by the shift register input pins.
|
|
||||||
The primary and secondary matrices share the same rows, which are strobed by micro-controller pins.
|
|
||||||
Both matrices are active low.
|
|
||||||
|
|
||||||
![breadboard keyboard with shift_registers](keybrd_4b_split_keyboard_with_shift_registers/shift_reg_front.JPG )
|
|
||||||
|
|
||||||
## Building a split keyboard with shift registers
|
|
||||||
The breadboard keyboard modifies the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
|
||||||
|
|
||||||
Add components to the breadboard as shown in the picture.
|
|
||||||
|
|
||||||
The shift register is a SN74HC165N. Details are in the SN74HC165N datasheet.
|
|
||||||
|
|
||||||
Each shift register has a small notch on one end to identify pin 1.
|
|
||||||
In the picture, 1 pins are on the right end.
|
|
||||||
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.
|
|
||||||
The breadboard doesn't have enough room for 16 columns; only 4 columns are connected to the shift registers.
|
|
||||||
Every 4th input pin is connected to a matrix column and a pull-up resistor.
|
|
||||||
Unused input pins are connected to power.
|
|
||||||
The red bus strips power the pull up resistors and unused input pins.
|
|
||||||
|
|
||||||
A decoupling capacitor between the power and ground wires dampens noise coming in through those wires.
|
|
||||||
|
|
||||||
![breadboard keyboard with shift_registers](keybrd_4b_split_keyboard_with_shift_registers/shift_reg_side.JPG )
|
|
||||||
|
|
||||||
![breadboard keyboard with shift_registers](keybrd_4b_split_keyboard_with_shift_registers/shift_reg_back.JPG )
|
|
||||||
|
|
||||||
Blue bus strips are used for strobing rows
|
|
||||||
|
|
||||||
I apologize for not having a schematic. This table should help you figure out the pictures:
|
|
||||||
|
|
||||||
<!-- todo add schematic -->
|
|
||||||
|
|
||||||
```
|
|
||||||
74HC165 left (upper half of breadboard)
|
|
||||||
NAME PIN# I/O DESCRIPTION DESTINATION PIN# CHAIN (wires flat on breadboard)
|
|
||||||
SH/LD 1 I shift or load input Teensy LC CS0 10 red wire
|
|
||||||
CLK 2 I clock input Teensy LC SCK0 13 green wire
|
|
||||||
D4 3 I parallel input pull-up resistor red bus
|
|
||||||
D5 4 I parallel input power red bus
|
|
||||||
D6 5 I parallel input power red bus
|
|
||||||
D7 6 I parallel input power red bus
|
|
||||||
/QH 7 O ~serial output Teensy LC MISO0 12
|
|
||||||
GND 8 ground gnd black wire
|
|
||||||
|
|
||||||
74HC165 right (lower half of breadboard)
|
|
||||||
NAME PIN# I/O DESCRIPTION DESTINATION CHAIN (wires flat on breadboard)
|
|
||||||
VCC 16 power pin Teensy LC 3.3V red bus
|
|
||||||
CLK INH 15 I clock inhibit gnd black wire
|
|
||||||
D3 14 I parallel input power red bus
|
|
||||||
D2 13 I parallel input power red bus
|
|
||||||
D1 12 I parallel input power red bus
|
|
||||||
D0 11 I parallel input pull-up resistor red bus
|
|
||||||
SER 10 I serial input next QH yellow wire
|
|
||||||
QH 9 O serial output previous SER yellow wire
|
|
||||||
|
|
||||||
```
|
|
||||||
## 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.
|
|
||||||
Annotations in the sketch explain the code.
|
|
||||||
|
|
||||||
## Exercises
|
|
||||||
1. Guess what happens if an unused input pin is not powered? Try it.
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
|
@ -1,70 +0,0 @@
|
|||||||
keybrd Tutorial 4 - split keyboard with I/O Expander
|
|
||||||
====================================================
|
|
||||||
When you finish this tutorial you will be able to be able to modify a 2-matrix keybrd sketch to suite your own split keyboard design.
|
|
||||||
|
|
||||||
## Overview of split keyboard with I/O Expander
|
|
||||||
The breadboard in this picture models a split keyboard.
|
|
||||||
![breadboard keyboard with 2 rows and 4 columns of keys](images/breadboard_keyboard_2x5_labeled.jpg "2x5 breadboard keyboard")
|
|
||||||
|
|
||||||
The breadboard's four bus strips are used as rows.
|
|
||||||
Two rows (blue bus strips) are connected to the microcontroller.
|
|
||||||
Two rows (red bus strips) are connected to the shift registers.
|
|
||||||
|
|
||||||
The breadboard's four bus strips are used as rows.
|
|
||||||
Two rows connect to a microcontroller, and two rows connected to a I/O expander.
|
|
||||||
|
|
||||||
The I/O expander has a small notch on one end, which identifies pin 1.
|
|
||||||
In the picture, pin 1 is on the right end.
|
|
||||||
|
|
||||||
The microcontroller and I/O expander are connected by 4 jumper wires:
|
|
||||||
* ground
|
|
||||||
* power
|
|
||||||
* Serial CLock signal (SCL)
|
|
||||||
* Serial DAta signal (SDA)
|
|
||||||
|
|
||||||
A decoupling capacitor on the power pin dampens noise coming in through the power and ground wires.
|
|
||||||
|
|
||||||
The microcontroller and I/O expander communicate via [I2C](http://en.wikipedia.org/wiki/I%C2%B2C) bus, which consists of two signals: SCL and SDA.
|
|
||||||
Two resistors pull-up voltage on the SCL and SDA.
|
|
||||||
|
|
||||||
I/O expander I2C address is configured by hardware pins.
|
|
||||||
The MCP23018 with all address pins grounded has an I2C address of ?? todo.
|
|
||||||
|
|
||||||
The I/O expander has two ports. Each port has eight pins.
|
|
||||||
One port is connected to the matrix's rows. The other port is connected to the matrix's columns.
|
|
||||||
|
|
||||||
## Building a split keyboard with I/O Expander
|
|
||||||
We will build a split keyboard adding parts to the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
|
||||||
|
|
||||||
todo add schematic
|
|
||||||
|
|
||||||
<!-- schematic with IOE power decoupling capacitor
|
|
||||||
This schematic was written by consulting the I/O expander's datasheet and using the ?? tool. -->
|
|
||||||
|
|
||||||
Continuing from the basic breadboard keyboard instructions:
|
|
||||||
|
|
||||||
<!-- At some point in the future, Markdown may support starting ordered lists at an arbitrary number. -->
|
|
||||||
|
|
||||||
4. Insert the I/O expander
|
|
||||||
|
|
||||||
5. Install I/O expander power
|
|
||||||
* ground
|
|
||||||
* power
|
|
||||||
* capacitor
|
|
||||||
|
|
||||||
6. Install I2C bus
|
|
||||||
* SCL
|
|
||||||
* SDA
|
|
||||||
* pull-up resistors on SCL and SDA
|
|
||||||
|
|
||||||
7. configure I2C address
|
|
||||||
|
|
||||||
8. Assemble key matrix as shown in the picture.
|
|
||||||
|
|
||||||
9. Connect I/O expander ports to matrix rows and columns
|
|
||||||
|
|
||||||
## Sketch for split keyboard with I/O Expander
|
|
||||||
The [keybrd_4_split_with_IOE_annotated.ino](keybrd_4_split_with_IOE_annotated/keybrd_4_split_with_IOE_annotated.ino)
|
|
||||||
sketch explains how the I/O Expander works on a keyboard.
|
|
||||||
|
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
|
94
tutorials/tutorial_5_LEDs.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
Tutorial 5 - indicator LEDs
|
||||||
|
===========================
|
||||||
|
Keyboards often have LEDs to indicate CapsLock, NumLock, and other states.
|
||||||
|
It's one of the first things we look at when a keyboard produces unexpected results.
|
||||||
|
|
||||||
|
Adding LEDs to the basic breadboard keyboard
|
||||||
|
--------------------------------------------
|
||||||
|
The breadboard keyboard modifies the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md)
|
||||||
|
|
||||||
|
Add components to the breadboard as shown in the picture.
|
||||||
|
|
||||||
|
The three clear plastic cylinders are LEDs.
|
||||||
|
LED anodes (the longer lead) are powered by 4.7k Ohm current limiting resistors connected to pins 16, 17, and 21.
|
||||||
|
LED cathodes (the shorter lead) are grounded by a common terminal strip.
|
||||||
|
|
||||||
|
!["LEDs"](keybrd_5_LEDs/LEDs_back.JPG "LEDs")
|
||||||
|
|
||||||
|
keybrd sketch for driving LEDs
|
||||||
|
------------------------------
|
||||||
|
[keybrd_5_LEDs.ino](keybrd_5_LEDs/keybrd_5_LEDs.ino) is a simple sketch with three LEDs.
|
||||||
|
The sketch will run on the above breadboard keyboard.
|
||||||
|
As usual, the sketch annotations explain the code.
|
||||||
|
|
||||||
|
LED brightness
|
||||||
|
--------------
|
||||||
|
An LED's current limiting resistor value effects the brightness of the LED.
|
||||||
|
Lets see how much visual difference resistance makes.
|
||||||
|
Replace an LED's 4.7k Ohm resistor with a 270 Ohm resistor.
|
||||||
|
|
||||||
|
It doesn't matter which end of the LED the resistor is on, the important thing is that the resistor and LED are in series.
|
||||||
|
|
||||||
|
Less resistance makes the LED brighter.
|
||||||
|
Too little resistance will burn out the LED.
|
||||||
|
Connecting an LED directly to power will destroy the LED in a bright flash (do not look directly at the LED if you try this).
|
||||||
|
|
||||||
|
2-mA LEDs are bright enough for keyboard indicator lights.
|
||||||
|
Or you can use more resistance on a 20-mA LED to make it dimmer.
|
||||||
|
|
||||||
|
LED current limiting resistor values
|
||||||
|
------------------------------------
|
||||||
|
Never connect an LED directly from ground to power. Doing so would destroy the LED.
|
||||||
|
|
||||||
|
This formula calculates the minimum resistance for maximum LED brightness:
|
||||||
|
```
|
||||||
|
output-pin Supply Voltage Vs
|
||||||
|
LED Forward Voltage Vf
|
||||||
|
Forward Current If
|
||||||
|
|
||||||
|
minimum current limiting restiance R = (Vs - Vf) / If
|
||||||
|
```
|
||||||
|
|
||||||
|
For Forward Current, use the smaller of:
|
||||||
|
* Current capacity of output pin
|
||||||
|
* Continuous Forward Current of LED
|
||||||
|
|
||||||
|
Teensy LC output-pin capacities are:
|
||||||
|
* four 20 mA pins (5, 16, 17, 21)
|
||||||
|
* nineteen 5 mA pins
|
||||||
|
* Teensy LC on-board LED is on pin 13.
|
||||||
|
It has a current-limiting resistor on the board, and does not provide enough power for another LED.
|
||||||
|
|
||||||
|
For Teensy LC 20 mA pin and the TT Electronics OVLLx8C7 LED:
|
||||||
|
```
|
||||||
|
output-pin Supply Voltage Vs = 3.3 volts
|
||||||
|
LED Forward Voltage Vf = 2.2 volts
|
||||||
|
max pin Current If = 20 mA
|
||||||
|
max LED Current If = 20 mA
|
||||||
|
|
||||||
|
minimum current limiting restiance R = (Vs - Vf) / If = 55 Ohms
|
||||||
|
```
|
||||||
|
It is safe to use more resistance.
|
||||||
|
|
||||||
|
Calculating the resistance for the Teensy LC 5 mA pin is left as an exercise.
|
||||||
|
|
||||||
|
Through-the-hole resistors have color coded bands that indicate resistance value.
|
||||||
|
https://en.wikipedia.org/wiki/Electronic_color_code#Resistor_color-coding
|
||||||
|
|
||||||
|
Exercises
|
||||||
|
---------
|
||||||
|
1) In this exercise you will calculate the minimum current limiting resistance needed for your output pin and LED.
|
||||||
|
|
||||||
|
For your micro controller, find:
|
||||||
|
* Supply Voltage coming out of the output pins
|
||||||
|
* Current (mA) capacity of the output pins
|
||||||
|
|
||||||
|
From your LED's datasheet, find:
|
||||||
|
* Forward Voltage
|
||||||
|
* Continuous Forward Current (mA)
|
||||||
|
|
||||||
|
Calculate the minimum resistance needed for your LED and Supply Voltage.
|
||||||
|
There are several "LED current limiting resistor calculators" on line.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
@ -3,52 +3,53 @@ Tutorial 6 - Active high
|
|||||||
This tutorial pulls together several concepts needed to understand active state in the context of a keyboard.
|
This tutorial pulls together several concepts needed to understand active state in the context of a keyboard.
|
||||||
Skip to the end of this tutorial if you just want to copy an active-high keyboard.
|
Skip to the end of this tutorial if you just want to copy an active-high keyboard.
|
||||||
|
|
||||||
## Pull-up resistors
|
Pull-up resistors
|
||||||
|
-----------------
|
||||||
There are many sources that explain "pull-up resistors", so I won't repeat it here.
|
There are many sources that explain "pull-up resistors", so I won't repeat it here.
|
||||||
Here is a [good tutorial on Pull-up Resistors](https://learn.sparkfun.com/tutorials/pull-up-resistors/what-is-a-pull-up-resistor).
|
Here is a [good tutorial on Pull-up Resistors](https://learn.sparkfun.com/tutorials/pull-up-resistors/what-is-a-pull-up-resistor).
|
||||||
|
|
||||||
## Active low
|
Active low
|
||||||
All the preceding breadboard keyboards in this tutorial series have used active low with internal pull-up resistors.
|
----------
|
||||||
|
All the keyboards up to this point in the tutorial series have used active low with internal pull-up resistors.
|
||||||
|
|
||||||
"Active low" means that if a switch is pressed (active state), the read pin is low.
|
"Active low" means that if a switch is pressed (active state), the read pin is low.
|
||||||
When the switch is released (inactive state), the pull-up resistor pulls the read pin high.
|
When the switch is released (inactive state), the pull-up resistor pulls the read pin high.
|
||||||
Active low requires pull-up resistors.
|
|
||||||
|
|
||||||
The following table traces the strobe current from left to right (0 is ground, 1 is power).
|
The following table traces the strobe current from left to right (0 is ground, 1 is power).
|
||||||
If the switch is closed, the strobe current passes through the switch and pulls the read pin low.
|
If the switch is closed, the strobe current passes through the switch and pulls the read pin low.
|
||||||
If the switch is open, the pull-up resistor pulls the read pin high.
|
If the switch is open, the pull-up resistor pulls the read pin high.
|
||||||
|
<br>
|
||||||
|
|
||||||
|Strobe pin on | Diode orientation | Switch position | Pull resistor | Read pin state |
|
|Strobe pin on | Diode orientation | Switch position | Pull resistor | Read pin state |
|
||||||
|:------------:|:------------------:|:---------------:|:-------------:|:---------------:|
|
|:------------:|:------------------:|:---------------:|:-------------:|:---------------:|
|
||||||
| 0 | cathode -:<- anode | close | 1 pull-up | 0 active low |
|
| 0 | cathode -:<- anode | close | 1 pull-up | 0 active low |
|
||||||
| 0 | cathode -:<- anode | open | 1 pull-up | 1 inactive high |
|
| 0 | cathode -:<- anode | open | 1 pull-up | 1 inactive high |
|
||||||
|
<br>
|
||||||
Arduino boards have internal pull-up resistors, which saves on parts and labor compared to manually adding external pull resistors.
|
Arduino boards have internal pull-up resistors, which saves on parts and labor compared to manually adding external pull resistors.
|
||||||
If you are designing a keyboard, go with active low.
|
|
||||||
|
|
||||||
To make a keyboard active low:
|
To make a keyboard active low:
|
||||||
* Use internal pull-up resistors if the IC has them
|
|
||||||
* Orient diodes with cathode (banded end) towards the write pins (row)
|
* Orient diodes with cathode (banded end) towards the write pins (row)
|
||||||
* Define strobe on and off in the sketch like this:
|
* Define strobe on and strobe off in the sketch like this:
|
||||||
```
|
```
|
||||||
const bool Scanner_uC::STROBE_ON = LOW;
|
const bool Scanner_uC::STROBE_ON = LOW;
|
||||||
const bool Scanner_uC::STROBE_OFF = HIGH;
|
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Active high
|
Active high
|
||||||
|
-----------
|
||||||
"Active high" means that if a switch is pressed (active), the read pin is high.
|
"Active high" means that if a switch is pressed (active), the read pin is high.
|
||||||
When the switch is released (inactive), the pull-down resistor pulls the read pin low.
|
When the switch is released (inactive), the pull-down resistor pulls the read pin low.
|
||||||
Active high requires pull-down resistors.
|
|
||||||
|
|
||||||
The following table traces the strobe current from left to right (0 is ground, 1 is power).
|
The following table traces the strobe current from left to right (0 is ground, 1 is power).
|
||||||
If the switch is closed, the strobe current passes through the switch and pulls the read pin high.
|
If the switch is closed, the strobe current passes through the switch and pulls the read pin high.
|
||||||
If the switch is open, the pull-up resistor pulls the read pin low.
|
If the switch is open, the pull-down resistor pulls the read pin low.
|
||||||
|
<br>
|
||||||
|
|
||||||
|Strobe pin on | Diode orientation | Switch position | Pull resistor | Read pin state |
|
|Strobe pin on | Diode orientation | Switch position | Pull resistor | Read pin state |
|
||||||
|:------------:|:------------------:|:---------------:|:-------------:|:---------------:|
|
|:------------:|:------------------:|:---------------:|:-------------:|:---------------:|
|
||||||
| 1 | anode ->:- cathode | close | 0 pull-down | 1 active high |
|
| 1 | anode ->:- cathode | close | 0 pull-down | 1 active high |
|
||||||
| 1 | anode ->:- cathode | open | 0 pull-down | 0 inactive low |
|
| 1 | anode ->:- cathode | open | 0 pull-down | 0 inactive low |
|
||||||
|
<br>
|
||||||
Arduino boards do not have internal pull-down resistors.
|
Arduino boards do not have internal pull-down resistors.
|
||||||
If you want to use active low, you will have to add external pull-down resistors to the read pins.
|
If you want to use active low, you will have to add external pull-down resistors to the read pins.
|
||||||
|
|
||||||
@ -61,7 +62,8 @@ To make a keyboard active high:
|
|||||||
const bool Scanner_uC::STROBE_OFF = LOW;
|
const bool Scanner_uC::STROBE_OFF = LOW;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Making an active-high keyboard
|
Making a breadboard keyboard active-high
|
||||||
|
----------------------------------------
|
||||||
This tutorial converts the basic breadboard keyboard from tutorial 1 to active high.
|
This tutorial converts the basic breadboard keyboard from tutorial 1 to active high.
|
||||||
By comparing the above tables, one can see what changes need to be made:
|
By comparing the above tables, one can see what changes need to be made:
|
||||||
* add external pull-down resistors to the read pins
|
* add external pull-down resistors to the read pins
|
||||||
@ -71,6 +73,9 @@ By comparing the above tables, one can see what changes need to be made:
|
|||||||
The red bus is grounded.
|
The red bus is grounded.
|
||||||
The pull-down resistors plug into the red bus and column read pins.
|
The pull-down resistors plug into the red bus and column read pins.
|
||||||
|
|
||||||
The [keybrd_6_active_highsketch.ino](keybrd_6_active_high/keybrd_6_active_high.ino) is the tutorial 2 sketch with STROBE_ON and STROBE_OFF values swapped.
|
The [keybrd_6_active_highsketch.ino](keybrd_6_active_high/keybrd_6_active_high.ino) is the tutorial 1 sketch with STROBE_ON and STROBE_OFF values swapped.
|
||||||
|
|
||||||
![pull_down_resistors.JPG](keybrd_6_active_high/pull_down_resistors.JPG "Active-high diodes and pull-down resistors")
|
![pull_down_resistors.JPG](keybrd_6_active_high/pull_down_resistors.JPG "Active-high diodes and pull-down resistors")
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
Tutorial 7a - using someone else's keybrd extension library
|
Tutorial 8a - using someone else's keybrd extension library
|
||||||
========================================================
|
===========================================================
|
||||||
The keybrd library contains the foundation classes for creating a keyboard firmware.
|
The keybrd library contains the classes needed for creating most keyboard firmware.
|
||||||
keybrd extension libraries extend the core keyboard library.
|
keybrd extension libraries extend the keyboard library with custom classes.
|
||||||
|
|
||||||
keybrd extension library names are prefixed by "keybrd_" and are listed in: todo keybrd extension libraries are not listed yet
|
keybrd extension library names are prefixed by "keybrd_" and are listed in:
|
||||||
* [Arduino Playground](http://playground.arduino.cc/Main/InterfacingWithHardware#keyb) > find "keybrd"
|
* [Arduino Playground](http://playground.arduino.cc/Main/InterfacingWithHardware#keyb) > find "keybrd"
|
||||||
* Arduino Library-Manager (Arduino IDE > Sketch > Include Library > Manage Libraries > Filter your search: keybrd)
|
* Arduino Library-Manager (Arduino IDE > Sketch > Include Library > Manage Libraries > Filter your search: keybrd)
|
||||||
|
|
||||||
Instructions for installing a library are at:
|
Instructions for installing a library on Arduino IDE are at:
|
||||||
http://www.arduino.cc/en/Guide/Libraries
|
http://www.arduino.cc/en/Guide/Libraries
|
||||||
|
|
||||||
Once a keybrd extension library is installed, it's classes can be included in a sketch.
|
Once a keybrd extension library is installed, it's classes can be included in your sketch.
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
Tutorial 7b - creating and publishing your own keybrd extension library
|
Tutorial 8b - creating and publishing your own keybrd extension library
|
||||||
=======================================================================
|
=======================================================================
|
||||||
Publishing and listing your keybrd extension library allows others to find and install your library.
|
Publishing and listing your keybrd extension library allows others to find and install your library.
|
||||||
The keybrd extension library name should start with "keybrd_" so that it is easy for people to find.
|
The keybrd extension library name should start with "keybrd_" so that it is easy for people to find.
|
||||||
|
|
||||||
The directory structure of the library depends on where it will be listed.
|
The directory structure of the library depends on where it will be listed.
|
||||||
|
|
||||||
## Publishing anywhere with listing on Arduino Playground LibraryList
|
Publishing anywhere with listing on Arduino Playground LibraryList
|
||||||
|
------------------------------------------------------------------
|
||||||
Arduino Playground LibraryList can list a library with any directory structure.
|
Arduino Playground LibraryList can list a library with any directory structure.
|
||||||
The directory structure of your keybrd extension library can be as simple as:
|
The directory structure of your keybrd extension library can be as simple as:
|
||||||
|
|
||||||
@ -33,7 +34,8 @@ Instructions for listing a library on the Arduino playgound LibraryList are at:
|
|||||||
Add your keybrd library to the Keyboard/Keypads sublist:
|
Add your keybrd library to the Keyboard/Keypads sublist:
|
||||||
http://playground.arduino.cc/Main/InterfacingWithHardware#keyb
|
http://playground.arduino.cc/Main/InterfacingWithHardware#keyb
|
||||||
|
|
||||||
## Publishing on GitHub with listing on Arduino Library-Manager and Arduino Playground LibraryList
|
Publishing on GitHub with listing on Arduino Library-Manager and Arduino Playground LibraryList
|
||||||
|
-----------------------------------------------------------------------------------------------
|
||||||
The advantage of using GitHub is that users can submit pull requests.
|
The advantage of using GitHub is that users can submit pull requests.
|
||||||
The advantage of using Arduino Library-Manager is that users can install your library through the Arduino IDE.
|
The advantage of using Arduino Library-Manager is that users can install your library through the Arduino IDE.
|
||||||
|
|
||||||
@ -61,16 +63,19 @@ Your keybrd extension library should have a library.properties file and a src fo
|
|||||||
|
|
||||||
The library.properties file is described in
|
The library.properties file is described in
|
||||||
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification
|
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification
|
||||||
|
|
||||||
Example library.properties file:
|
Example library.properties file:
|
||||||
|
```
|
||||||
name=keybrd_MyKeyboard
|
name=keybrd_MyKeyboard
|
||||||
version=1.2.3
|
version=1.2.3
|
||||||
author=Me
|
author=Me
|
||||||
maintainer=Me
|
maintainer=Me
|
||||||
sentence=An extension to the keybrd library for the My keyboard.
|
sentence=An extension to the keybrd library for the MyKeyboard.
|
||||||
paragraph=This library demonstrates my feature.
|
paragraph=This library demonstrates my feature.
|
||||||
category=Device Control
|
category=Device Control
|
||||||
url=https://github.com/Me/keybrd_MyKeyboard
|
url=https://github.com/Me/keybrd_MyKeyboard
|
||||||
architectures=Teensy LC
|
architectures=*
|
||||||
|
```
|
||||||
|
|
||||||
Instructions for listing a library on Arduino Library Manager are at:
|
Instructions for listing a library on Arduino Library Manager are at:
|
||||||
https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ
|
https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ
|
||||||
@ -80,4 +85,5 @@ After it has been accepted into the Arduino IDE Library Manager, add your librar
|
|||||||
Sign in at http://playground.arduino.cc/Main/LibraryList and add keybrd libraries to Keyboard/Keypads sublist:
|
Sign in at http://playground.arduino.cc/Main/LibraryList and add keybrd libraries to Keyboard/Keypads sublist:
|
||||||
http://playground.arduino.cc/Main/InterfacingWithHardware#keyb
|
http://playground.arduino.cc/Main/InterfacingWithHardware#keyb
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,34 +1,31 @@
|
|||||||
Tutorial 8 - breaking up a sketch into smaller files
|
Tutorial 9 - breaking up a sketch into smaller files
|
||||||
====================================================
|
====================================================
|
||||||
A keybrd sketch can become quite lengthy, which can make it harder to navigate and understand.
|
A keybrd sketch can become quite lengthy, which can make it harder to navigate and understand.
|
||||||
|
|
||||||
The keybrd_DH sketch has about 800 lines of code; 700 of which are for instantiating objects.
|
The keybrd_DH sketch has about 800 lines of code; 700 of which are for instantiating objects.
|
||||||
The object instantiations are grouped into four files located in the keybrd_DH library, and included in keybrd_DH.ino:
|
The object instantiations are grouped into six files located in the keybrd_DH library, and included in keybrd_DH.ino:
|
||||||
|
|
||||||
// ========= OBJECT INSTANTIATIONS =============
|
// ========= INSTANTIATE THE KEYBOARD ==========
|
||||||
#include <instantiations_ports.h>
|
#include "config.h"
|
||||||
#include <instantiations_LEDs.h>
|
#include <instantiations_pins.h>
|
||||||
#include <instantiations_codes.h>
|
#include <instantiations_scancodes.h>
|
||||||
#include <instantiations_matrix.h>
|
#include <instantiations_layercodes.h>
|
||||||
|
#include <instantiations_rows_L.h>
|
||||||
|
#include <instantiations_rows_R.h>
|
||||||
|
|
||||||
Splitting your code into groups of instantiations also provides organizational and reusability benefits.
|
Splitting your code into groups of instantiations also provides organizational and reusability benefits.
|
||||||
|
|
||||||
Example 1.
|
Example 1.
|
||||||
You have three versions of LED indicators you are experimenting with:
|
You have three versions of LED indicators you are experimenting with:
|
||||||
instantiations_LEDs_1.h
|
* instantiations_LEDs_1.h
|
||||||
instantiations_LEDs_2.h
|
* instantiations_LEDs_2.h
|
||||||
instantiations_LEDs_3.h
|
* instantiations_LEDs_3.h
|
||||||
|
|
||||||
Example 2.
|
Example 2.
|
||||||
You use Colemak and want QWERTY users to to try your new keyboard design.
|
You use Colemak and want QWERTY users to to try your new keyboard design.
|
||||||
So you publish your keybrd extension library with two versions of instantiations_matrix.h:
|
So you publish your keybrd extension library with two versions of instantiations_matrix.h:
|
||||||
instantiations_matrix_colemak.h
|
* instantiations_matrix_colemak.h
|
||||||
instantiations_matrix_QWERTY.h
|
* instantiations_matrix_QWERTY.h
|
||||||
|
|
||||||
Example 3.
|
|
||||||
You want to try someone else's keybrd sketch, but your controller and matrix are different.
|
|
||||||
So you replace two of your object instantiation files with your own:
|
|
||||||
instantiations_ports.h
|
|
||||||
instantiations_matrix.h
|
|
||||||
|
|
||||||
|
<br>
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/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="http://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="http://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="http://creativecommons.org/ns#" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|