Archived
1
0

move Debug variables to static

This commit is contained in:
wolfv6 2016-07-17 20:26:00 -06:00
parent b276d217b3
commit c9a3abd4e7
62 changed files with 642 additions and 1032 deletions

66
CONTRIBUTING.md Normal file
View 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).

View File

@ -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.

View File

@ -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
View 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)

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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.

View File

@ -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

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -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=*

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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));
}
};

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View 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();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -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.

View File

@ -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);

View File

@ -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();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

View File

@ -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();
}

View File

@ -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.
*/ */

View File

@ -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 };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View 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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.

View File

@ -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>.