move Debug variables to static
66
CONTRIBUTING.md
Normal file
@ -0,0 +1,66 @@
|
||||
Contributing to keybrd
|
||||
======================
|
||||
We'd love for you to contribute to the keybrd project.
|
||||
|
||||
Improvement suggestions
|
||||
-----------------------
|
||||
We need to know what improvements to the keybrd library would help you create your keyboard design.
|
||||
Before requesting an improvement, please check [planned_features list](doc/planned_features.md)
|
||||
|
||||
Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keybrd/issues).
|
||||
* The issue title should start with "suggestion:" followed by a descriptive title
|
||||
* Provide a use case
|
||||
* Explain why the improvement is useful
|
||||
* Site other product examples where this improvement exists
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
A bug report is the first step in making the keybrd library work the way it's supposed to work.
|
||||
|
||||
Please provide enough information so we can reproduce the bug behaviour!
|
||||
* Complete sketch (copy & paste, attachment, or a link to the code)
|
||||
* Screenshot or the exact text of error messages
|
||||
* Describe the observed behavior and explain which behavior you expected
|
||||
* Which controller your using
|
||||
* Wiring details - how exactly have you connected the hardware (a photo's worth 1000 words)
|
||||
* Arduino IDE version number
|
||||
* keybrd library version number
|
||||
* Any other information needed to reproduce the problem...
|
||||
|
||||
Code contributions
|
||||
------------------
|
||||
Unsure where to begin contributing to keybrd code?
|
||||
You can start by looking through the improvement suggestions, bug reports, and [planned_features](doc/planned_features.md).
|
||||
|
||||
Git commit message style guide:
|
||||
* Limit the first line to 72 characters summary
|
||||
* Second line should be empty, followed by body of the commit message
|
||||
* Use the imperative present tense (use "Add feature", not "Added feature", not "Adds feature")
|
||||
* Reference an improvement suggestion or bug report
|
||||
* Sometimes a bulleted list is a good format to convey the changes of a commit
|
||||
|
||||
User contributions
|
||||
------------------
|
||||
Any project requires various kinds of contributions to succeed.
|
||||
A thriving project is more than a pile of code.
|
||||
It's the packaging, explanation, outreach, and empathy of maintainers that make a good project great.
|
||||
|
||||
User Contributions can be in the form of:
|
||||
* Blog - You have a fresh perspective of how the keybrd library works.
|
||||
This makes you the perfect person to write an introductory blog explaining the project.
|
||||
A healthy project needs the perspective of many people.
|
||||
* Documentation - Suggest a clarification, simplification, correction, or other improvement.
|
||||
We need the perspective of people new to the project to see these things.
|
||||
Sometimes just changing a word or two makes a big difference.
|
||||
* [What we currently need from keybrd users](todo geekhack) lists tasks for the keybrd project's current stage of development.
|
||||
|
||||
Text file documentation style guide:
|
||||
* Use Markdown with a .md suffix.
|
||||
* "Underline" first-level (=) and second-level (-) headings (because easier to read in plain text).
|
||||
* Capitalize first letter of headings (no extra capitalization in headings).
|
||||
|
||||
Submitting a Pull Request
|
||||
-------------------------
|
||||
Pull Request is the preferred way to contribute code and documentation.
|
||||
If you want to contribute some other way, please make a request in the [GitHub issues](https://github.com/wolfv6/Keybrd/issues).
|
||||
|
43
README.md
@ -1,10 +1,12 @@
|
||||
keybrd library for creating keyboard firmware
|
||||
====================================================
|
||||
=============================================
|
||||
keybrd library 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.
|
||||
|
||||
keybrd library can support any keyboard configuration:
|
||||
* one-piece
|
||||
* split with shift registers
|
||||
* split with I/O expander
|
||||
* single-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.
|
||||
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.
|
||||
> Currently the keybrd library is limited to 8x8 matrices, which is enough for compact split keyboards.
|
||||
> The keybrd library is in Beta testing. The public API should not be considered stable.
|
||||
|
||||
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_2_single-layer_annotated/keybrd_2_single-layer_annotated.ino).
|
||||
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.
|
||||
A [minimal keybrd sketch](/tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino)
|
||||
is 40 lines of code for a 4-key keyboard.
|
||||
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.
|
||||
The remaining [keybrd tutorials](tutorials) show how to create custom keybrd firmware.
|
||||
<img src="tutorials/keybrd_1_breadboard/breadboard_keyboard_2x2.JPG" title="breadboard keyboard" alt="breadboard keyboard" style="height:290px;width:328px;">
|
||||
|
||||
Example complex keybrd sketch
|
||||
-----------------------------
|
||||
The keybrd_DH emulates the DataHand keyboard.
|
||||
It has 72 keys, 4 layers, 6 sub-layers, 2 matrices, 8 LEDs, and blinking LEDs.
|
||||
The keybrd_DH and its instantiation files contain about 800 lines of code.
|
||||
keybrd_DH and its instantiation files contain about 800 lines of code.
|
||||
It emulates the DataHand keyboard.
|
||||
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>
|
||||
[instantiations_ports.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_ports.h)<br>
|
||||
[instantiations_LEDs.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_LEDs.h)<br>
|
||||
[instantiations_codes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_codes.h)<br>
|
||||
[instantiations_matrix.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_matrix.h)
|
||||
[instantiations_pins.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_pins.h)<br>
|
||||
[instantiations_scancodes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_scancodes.h)<br>
|
||||
[instantiations_layercodes.h](https://github.com/wolfv6/keybrd_DH/blob/master/src/instantiations_layercodes.h)<br>
|
||||
[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
|
||||
-------
|
||||
[Guides](doc) and [tutorials](tutorials) are provided.
|
||||
Please ask a questions in [issues](https://github.com/wolfv6/Keybrd/issues) if something is not clear.
|
||||
|
||||
keybrd tutorial_1 shows how to make a breadboard keyboard.
|
||||
The remaining [keybrd tutorials](tutorials) show how to create custom keybrd firmware.
|
||||
|
||||
Please ask questions in [keybrd library for keyboard firmware](geekhack todo) thread if something is not clear.
|
||||
|
@ -1,24 +1,34 @@
|
||||
# Change Log for keybrd library
|
||||
Change Log for keybrd library
|
||||
=============================
|
||||
All notable changes to the keybrd project will be documented in this file.
|
||||
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.
|
||||
|
||||
## Unreleased
|
||||
## 0.5.0 (2016-07-18)
|
||||
<!-- Unreleased
|
||||
------------------ -->
|
||||
|
||||
0.5.0 (2016-07-19)
|
||||
------------------
|
||||
* Enhancements
|
||||
* Update tutorials
|
||||
* Add tutorials for shift registers, LEDs, active high
|
||||
|
||||
* 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
|
||||
|
||||
## 0.4.1 (2016-06-21)
|
||||
0.4.1 (2016-06-21)
|
||||
------------------
|
||||
* Enhancements
|
||||
* Add config_keybrd.h for size configurations.
|
||||
* Add RowScanner_SPI-ShiftRegisters for compact split keyboards up to 32 keys per matrix.
|
||||
* Add LED_PinNumber for controlling indicator lights by pin number.
|
||||
|
||||
## 0.4.0 (2016-06-10)
|
||||
0.4.0 (2016-06-10)
|
||||
------------------
|
||||
* Enhancements
|
||||
* Add Row_uC
|
||||
* 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.
|
||||
* Remove Port arrays
|
||||
|
||||
## 0.3.1 (2016-06-02)
|
||||
0.3.1 (2016-06-02)
|
||||
------------------
|
||||
* Enhancements
|
||||
* Add RowBase class
|
||||
* Add Row::debounce()
|
||||
|
||||
## 0.3.0 (2016-05-09)
|
||||
0.3.0 (2016-05-09)
|
||||
------------------
|
||||
* Enhancements
|
||||
* 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
|
||||
* Replace Key_Layered dependency on LayerManager with LayerState class
|
||||
|
||||
## 0.2.0 (2016-02-25)
|
||||
0.2.0 (2016-02-25)
|
||||
------------------
|
||||
* Enhancements
|
||||
* Add Port classes for micro-controllers and I/O expanders
|
||||
* Add DH_2565 sketch with DataHand layout
|
||||
* Add Sticky mouse button (SMB) for DataHand layout
|
||||
* Add Supporting documentation
|
||||
|
||||
## 0.1.0 (2015-02-10)
|
||||
0.1.0 (2015-02-10)
|
||||
------------------
|
||||
* Enhancements
|
||||
* 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
|
||||
|
14
doc/PLANNED_FEATURES.md
Normal file
@ -0,0 +1,14 @@
|
||||
planned_features is a view of where the keybrd project is headed.
|
||||
|
||||
Top priority
|
||||
============
|
||||
* Beta testing
|
||||
* Schematics for tutorials
|
||||
|
||||
Medium priority
|
||||
===============
|
||||
* Add matrix-to-layout mapping array (to decouple key matrix from layout)
|
||||
|
||||
Low priority
|
||||
============
|
||||
* MCP23S18 I/O expander with Serial Peripheral Interface (SPI)
|
@ -1,37 +0,0 @@
|
||||
Teensy 2.0 Pinout Diagram
|
||||
-------------------------
|
||||
USB is on top in the diagram.
|
||||
Inner columns are pin numbers, outer columns are port+bit pin name.
|
||||
```
|
||||
ground GND USB VCC +5v power
|
||||
B0 0 21 F0
|
||||
B1 1 20 F1
|
||||
B2 2 19 F4
|
||||
B3 3 18 F5
|
||||
B7 4 17 F6
|
||||
SCL D0 5 16 F7
|
||||
SDA D1 6 15 B6
|
||||
D2 7 14 B5
|
||||
D3 8 13 B4
|
||||
C6 9 12 D7
|
||||
C7 10 11 D6 Do not use pin D6 for scanning keyboard matrix
|
||||
LED on pin D6 pulls voltage down and will always return low
|
||||
|
||||
BOTTOM EDGE (USB on top, pins from left to right)
|
||||
PIN# port+bit function
|
||||
23 D5
|
||||
VCC 5v power
|
||||
GND ground
|
||||
RST reset
|
||||
22 D4
|
||||
|
||||
MIDDLE (below USB, pins from left to right)
|
||||
PIN# port+bit function
|
||||
24 E6
|
||||
Ref
|
||||
```
|
||||
|
||||
Teensy 2.0 pin assignment on https://www.pjrc.com/teensy/pinout.html
|
||||
Teensy 2.0 pinout with pin numbers on http://www.pjrc.com/teensy/td_digital.html
|
||||
Identifying and naming ports is useful when instantiating RowPorts and ColPorts.
|
||||
Keybrd library was tested on Teensy 2.0
|
@ -1,5 +1,5 @@
|
||||
# this file specifies style for keybrd C++ and Arduino sketch .ino files
|
||||
# Artistic Style is a console application for formatting C++ and Java source code
|
||||
# this file specifies style for keybrd C++ and Arduino sketch .ino files
|
||||
# http://sourceforge.net/projects/astyle/files/ download
|
||||
# http://astyle.sourceforge.net/astyle.html manual
|
||||
|
||||
|
@ -1,36 +1,39 @@
|
||||
keybrd Library Developer's Guide
|
||||
================================
|
||||
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:
|
||||
* Port classes for I/O expanders
|
||||
The most common reason for adding new classes are:
|
||||
* I/O expander classes
|
||||
* custom layer schemes for multi-layer keyboards
|
||||
* 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.
|
||||
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
|
||||
The keybrd library is flexible for designing custom Rows
|
||||
* Row functions can be overridden in a derived class
|
||||
* choice of Debouncers
|
||||
* choice of Scanners
|
||||
Custom Row classes
|
||||
------------------
|
||||
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
|
||||
* choice of Debouncers
|
||||
* choice of Scanners
|
||||
|
||||
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
|
||||
This example illustrates the custom Row classes for a fictional keybrd_Ext extension library.
|
||||
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_uC scans the primary matrix
|
||||
Row_Ext_ShiftRegisters scans the secondary matrix
|
||||
Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes
|
||||
Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes.<br>
|
||||
Row_Ext_uC uses Scanner_uC to scan the primary matrix.<br>
|
||||
Row_Ext_ShiftRegisters uses Scanner_ShiftRegs74HC165 to scan the secondary matrix.
|
||||
|
||||
Class inheritance diagram
|
||||
```
|
||||
|
||||
Row
|
||||
Row
|
||||
|
|
||||
Row_Ext (override Row::keyWasPressed() )
|
||||
/ \
|
||||
@ -44,22 +47,23 @@ Class inheritance diagram
|
||||
Dependency diagram
|
||||
```
|
||||
|
||||
________ Row_Ext_uC[1] _______________
|
||||
/ \ \
|
||||
Scanner_uC[1] Debouncer_Samples[1] Key[1..*]
|
||||
/ \ |
|
||||
strobePin[1] readPins[1..*] Code[1..*]
|
||||
________ Row_Ext_uC[1] ______________
|
||||
/ | \
|
||||
Scanner_uC[1] Debouncer_Samples[1] Key[1..*]
|
||||
/ |
|
||||
strobePin[1] Code[1..*]
|
||||
|
||||
|
||||
_____ Row_Ext_ShiftRegisters[1] ________
|
||||
/ \ \
|
||||
_________ Row_Ext_ShiftRegisters[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
|
||||
```
|
||||
@ -71,7 +75,7 @@ Keybrd library class inheritance diagram
|
||||
Scanner_uC Scanner_Port Scanner_ShiftRegs74HC165
|
||||
|
||||
|
||||
PortIOE
|
||||
PortIOE
|
||||
|
||||
PortWrite
|
||||
|
|
||||
@ -81,14 +85,14 @@ Keybrd library class inheritance diagram
|
||||
|
|
||||
PortRead_PCA9655E (one PortRead class for each IOE type)
|
||||
|
||||
____ LED ____
|
||||
/ \
|
||||
LED_PinNumber LED_PCA9655E
|
||||
_ LED _
|
||||
/ \
|
||||
LED_uC LED_PCA9655E
|
||||
|
||||
|
||||
DebouncerInterface
|
||||
|
|
||||
Debouncer_4Samples
|
||||
Debouncer_Samples
|
||||
|
||||
ScanDelay
|
||||
|
||||
@ -115,14 +119,15 @@ Keybrd library class inheritance diagram
|
||||
|__________________________________________
|
||||
\ \ \ \
|
||||
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..*] _
|
||||
/ | \
|
||||
@ -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..*]
|
||||
________ 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..*]
|
||||
/ \ \
|
||||
@ -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..*] _________
|
||||
/ \ \
|
||||
@ -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.
|
||||
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.
|
||||
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.
|
||||
Example persistences are:
|
||||
* "Lock" - layer remains active after the layer key is released
|
||||
@ -202,7 +209,8 @@ Example Code_Layered class names:
|
||||
* Code_LayeredScSc
|
||||
* Key_LayeredKeysArray
|
||||
|
||||
## Style guide
|
||||
Style guide
|
||||
-----------
|
||||
Following the style guide makes it easier for the next programmer to understand your code.
|
||||
* For class names, see above section "Class naming conventions".
|
||||
* 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
|
||||
* Header guards have _H suffix e.g. #ifndef FILE_NAME_H
|
||||
* 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:
|
||||
```
|
||||
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);
|
||||
```
|
||||
* 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.
|
||||
* 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.
|
||||
@ -231,32 +239,34 @@ Following the style guide makes it easier for the next programmer to understand
|
||||
|
||||
<!-- 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.
|
||||
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.
|
||||
|
||||
```
|
||||
loop() for each row
|
||||
Row::process()
|
||||
Scanner_uC::scan() strobe row on
|
||||
Scanner_uC::scan() strobe row on
|
||||
for each readPin
|
||||
set rowState bit
|
||||
set readState bit
|
||||
strobe row off
|
||||
Debouncer_4Samples::debounce() debounce
|
||||
Debouncer_Samples::debounce() debounce
|
||||
Row::send() for each key in row
|
||||
if falling edge
|
||||
Key_*::release() scanCode->release()
|
||||
Code_*::release() Keyboard.release(scancode)
|
||||
if rising edge
|
||||
Key_*::press() scanCode->press()
|
||||
Code_*::press() Keyboard.press(scancode)
|
||||
if falling edge
|
||||
Key_*::release() scanCode->release()
|
||||
Code_*::release() Keyboard.release(scancode)
|
||||
if rising edge
|
||||
Key_*::press() scanCode->press()
|
||||
Code_*::press() Keyboard.press(scancode)
|
||||
scanDelay.delay();
|
||||
|
||||
```
|
||||
|
||||
## 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):
|
||||
|
||||
#include <Arduino.h>
|
||||
|
@ -1,9 +1,7 @@
|
||||
keybrd Library User's Guide
|
||||
===========================
|
||||
keybrd is an open source library for creating custom-keyboard firmware.
|
||||
The resulting keyboard firmware is compatible with standard USB keyboard drivers.
|
||||
|
||||
This guide shows how to
|
||||
keybrd is a library for creating custom-keyboard firmware.
|
||||
This guide shows how to:
|
||||
* set up the Arduino development environment
|
||||
* install the keybrd library
|
||||
* compile and load keybrd firmware
|
||||
@ -11,16 +9,19 @@ This guide shows how to
|
||||
The Arduino development environment is free and simple as possible.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
The keybrd library works with Teensy and Arduino boards.
|
||||
Microcontroller board requirements
|
||||
----------------------------------
|
||||
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.
|
||||
|
||||
@ -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.
|
||||
|
||||
## Getting started with Teensy, Arduino IDE, and keybrd
|
||||
Getting started with Teensy, Arduino IDE, and keybrd
|
||||
----------------------------------------------------
|
||||
The Arduino IDE is used to
|
||||
|
||||
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.
|
||||
|
||||
### 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:
|
||||
|
||||
@ -63,37 +65,38 @@ For Linux:
|
||||
Run the teensyduino installer and fill the form fields:
|
||||
|
||||
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
|
||||
|
||||
<!-- todo no longer needed, delete after testing Arduino library manager
|
||||
### Download and unpack keybrd-master.zip into your Arduino directory
|
||||
<!-- todo update after testing Arduino library manager
|
||||
link from tutorial 7 ## Publishing
|
||||
link from tutorial 8 ## Publishing
|
||||
https://www.arduino.cc/en/Guide/Libraries
|
||||
* Installing Additional Arduino Libraries
|
||||
* Using the Library Manager
|
||||
-->
|
||||
|
||||
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/).
|
||||
-->
|
||||
|
||||
### Install keybrd library and keybrd extension libraries
|
||||
<!-- todo update after testing Arduino library manager -->
|
||||
|
||||
### Install keybrd extension libraries
|
||||
The keybrd library contains the foundation classes for creating a keyboard firmware.
|
||||
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 library names are prefixed with "keybrd_".
|
||||
|
||||
The Arduino IDE looks for libraries in Arduino/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/
|
||||
Instructions for installing Arduino libraries are at: http://www.arduino.cc/en/Guide/Libraries
|
||||
|
||||
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
|
||||
From the Arduino IDE tool bar, select:
|
||||
@ -104,33 +107,28 @@ These are optional:
|
||||
* File > Preferences > Compiler warnings: All
|
||||
* 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
|
||||
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.
|
||||
> 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.
|
||||
> Take the following precautions before uploading an untested keybrd sketch to a controller:
|
||||
> * Save all files and close dangerous applications.
|
||||
> * Park the cursor in an editor opened to a test file.
|
||||
> That way you can immediately see if the controller starts spewing characters.
|
||||
> * Be prepared to turn off the controller:
|
||||
> turn off Teensy Loader's green "Auto" button and push Teensy's reset button
|
||||
> if that fails, unplug Teensy USB
|
||||
> turn off Teensy Loader's green "Auto" button and push Teensy's reset button or unplug Teensy USB.
|
||||
|
||||
Compile and load workflow:
|
||||
1. Open a keybrd sketch in the Arduino IDE.
|
||||
2. Prepare for loosing control of keyboard and mouse.
|
||||
3. On the Arduino IDE, click the Upload button.
|
||||
4. The Teensy boot loader window opens;
|
||||
you might need to press and release the pushbutton on the Teensy circuit board.
|
||||
4. The Teensy boot loader window opens
|
||||
(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.
|
||||
Extension libraries have their example sketches similarly located.
|
||||
|
||||
@ -140,18 +138,16 @@ The example sketch names use the following conventions.
|
||||
|
||||
where
|
||||
* **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
|
||||
* **version** is the sketch's version number
|
||||
* **feature** is a distinguishing feature of the keybrd sketch e.g. keyboard name, sound, Dvorak
|
||||
* **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.
|
||||
The following instructions are for setting active state for a Scanner_uC class.
|
||||
Scanner_ShiftRegs74HC165 and Scanner_Port classes is similar.
|
||||
The following instructions are for setting active state for a Scanner_uC class
|
||||
(Scanner_ShiftRegs74HC165 and Scanner_Port classes is similar).
|
||||
|
||||
For active low:
|
||||
* Use internal pull-down resistors.
|
||||
* Orient diodes with cathode (banded end) towards the write pins (row)
|
||||
* Use these two lines in the sketch:
|
||||
```
|
||||
@ -168,61 +164,48 @@ For active high:
|
||||
const bool Scanner_uC::STROBE_OFF = LOW;
|
||||
```
|
||||
|
||||
![Diode](../tutorials/keybrd_1_breadboard_images/120px-Diode_pinout_en_fr.svg.png)
|
||||
|
||||
Diagram is of typical through-the-hole [diode](https://en.wikipedia.org/wiki/Diode) in same alignment as diode symbol.
|
||||
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.
|
||||
Troubleshooting check list
|
||||
--------------------------
|
||||
The following is a listing of items to check when a new keybrd sketch or keyboard hardware is having trouble.
|
||||
|
||||
Development-environment items to check:
|
||||
* 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
|
||||
|
||||
From the Arduino IDE tool bar, select: Tools > USB Type > Keyboard + Mouse + Joystick
|
||||
* For compile error:
|
||||
```
|
||||
'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:
|
||||
* For each row, number of keys in Row should equal number of colPort pins.
|
||||
In this example, row_0 has six colPort pins in ptrsColPorts, and six keys in ptrsKeys_0:
|
||||
* For each row, number of read pins in Row should equal number of keys.
|
||||
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 );
|
||||
ColPort_AVR colPortD(DDRD, PORTD, PIND, 1<<2 | 1<<3 );
|
||||
uint8_t readPins[] = {14, 15};
|
||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
ColPort* const ptrsColPorts[] = { &colPortB, &colPortD };
|
||||
const uint8_t COL_PORT_COUNT = sizeof(ptrsColPorts)/sizeof(*ptrsColPorts);
|
||||
|
||||
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);
|
||||
Key* ptrsKeys_0[] = { &s_a, &s_b };
|
||||
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||
```
|
||||
* 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.
|
||||
|
||||
Hardware items to check:
|
||||
* Connections
|
||||
* Diode orientation
|
||||
* 5 volts across power and ground
|
||||
* To validate keyboard hardware, modify the simple single-layer keybrd sketch from the tutorial.
|
||||
* 3.3 or 5 volts across power and ground
|
||||
* 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
|
||||
[minimal keybrd sketch](blob/master/tutorials/keybrd_2_single-layer_annotated/keybrd_2_single-layer_annotated.ino).
|
||||
-->
|
||||
|
||||
## Keybrd nomenclature
|
||||
Keybrd nomenclature
|
||||
-------------------
|
||||
**[scancode](http://en.wikipedia.org/wiki/Scancode)** -
|
||||
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.
|
||||
|
||||
**[Layers](http://deskthority.net/wiki/Layer)** -
|
||||
are key bindings provided by the keyboard firmware.
|
||||
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).
|
||||
The [Neo layout](http://neo-layout.org/index_en.html) has 6 layers.
|
||||
**[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.
|
||||
* 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.
|
||||
|
||||
**Layer id** - is an integer assigned to a layer.
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
planned_features is a view of where the keybrd project is headed.
|
||||
|
||||
Top priority
|
||||
============
|
||||
MCP23S18 I/O expander with Serial Peripheral Interface (SPI)
|
||||
|
||||
Med priority
|
||||
============
|
||||
Add matrix-to-layout mapping array (to decouple matrix from layout)
|
||||
|
||||
Low priority
|
||||
============
|
||||
Update tutorials:
|
||||
* Currently tutorial sketches are obsolete and won't compile
|
||||
* Change tutorial sketches from teensy 2.0 and PCA9655E-D IOE to Teensy LC and MCP23018 IOE
|
||||
|
||||
Add more tutorials:
|
||||
* tutorial_5_LEDs.md
|
||||
* tutorial_6_mapping_matrix_to_layout.md
|
||||
* tutorial_9_active_high.md
|
||||
* add schematics to tutorials
|
@ -1,165 +0,0 @@
|
||||
/* keybrd_shift_reg.ino
|
||||
Tested on Teensy LC and daisy chained 74HC165 shift registers
|
||||
|
||||
The keyboard hardware for this sketch has 4 shift registers,
|
||||
with every 4th input pin connected to a pull-down resistor and matrix column, also the 31st key.
|
||||
Unused input pins are not grounded, so add this line to Scanner_ShiftRegs74HC165::scan():
|
||||
//clear unpowered pins (for testing on breadboard)
|
||||
rowState &= 0b11110001000100010001000100010001;
|
||||
|
||||
Layout Layout
|
||||
| Left | **0**|**1**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**|**8**|
|
||||
|:-----:|------|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
| **0** |capLck| a | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
| **1** | b | c | | **1** | a | b | c | d | e | f | g | h | i |
|
||||
*/
|
||||
// ################## GLOBAL ###################
|
||||
// ================= INCLUDES ==================
|
||||
#include <Debug.h>
|
||||
#include <ScanDelay.h>
|
||||
#include <LED_uC.h>
|
||||
#include <SPI.h>
|
||||
|
||||
//Codes
|
||||
#include <Code_Sc.h>
|
||||
#include <Code_LEDLock.h>
|
||||
|
||||
//Matrix
|
||||
#include <Row_uC.h>
|
||||
#include <Row_ShiftRegisters.h>
|
||||
|
||||
// =============== CONFIGURATION ===============
|
||||
ScanDelay scanDelay(9000);
|
||||
|
||||
//set left matrix for active low
|
||||
const bool Scanner_uC::STROBE_ON = LOW;
|
||||
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||
|
||||
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
|
||||
|
||||
//set right matrix for active low
|
||||
const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW;
|
||||
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH;
|
||||
|
||||
Debug debug;
|
||||
|
||||
// ================= LEFT PINS =================
|
||||
uint8_t readPins[] = {14, 15};
|
||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
// ==================== LEDs ===================
|
||||
LED_uC LED1(16);
|
||||
|
||||
// =================== CODES ===================
|
||||
Code_Sc s_a(KEY_A);
|
||||
Code_Sc s_b(KEY_B);
|
||||
Code_Sc s_c(KEY_C);
|
||||
Code_Sc s_d(KEY_D);
|
||||
Code_Sc s_e(KEY_E);
|
||||
Code_Sc s_f(KEY_F);
|
||||
Code_Sc s_g(KEY_G);
|
||||
Code_Sc s_h(KEY_H);
|
||||
Code_Sc s_i(KEY_I);
|
||||
|
||||
Code_Sc s_u(KEY_U);
|
||||
Code_Sc s_v(KEY_V);
|
||||
Code_Sc s_w(KEY_W);
|
||||
Code_Sc s_x(KEY_X);
|
||||
|
||||
Code_Sc s_z(KEY_Z);
|
||||
|
||||
Code_Sc s_0(KEY_0);
|
||||
Code_Sc s_1(KEY_1);
|
||||
Code_Sc s_2(KEY_2);
|
||||
Code_Sc s_3(KEY_3);
|
||||
Code_Sc s_4(KEY_4);
|
||||
Code_Sc s_5(KEY_5);
|
||||
Code_Sc s_6(KEY_6);
|
||||
Code_Sc s_7(KEY_7);
|
||||
Code_Sc s_8(KEY_8);
|
||||
|
||||
Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED1);
|
||||
|
||||
// ================= LEFT ROWS =================
|
||||
Key* ptrsKeys_L0[] = { &o_capsLock, &s_a };
|
||||
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
||||
|
||||
Key* ptrsKeys_L1[] = { &s_b, &s_c };
|
||||
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
||||
|
||||
// ================= RIGHT ROWS ================
|
||||
//typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h
|
||||
//Row_ShiftRegisters(strobePin, readPinCount, ptrsKeys[])
|
||||
//the s_z are place holders and should not print
|
||||
|
||||
/*
|
||||
//prints 0 1
|
||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z };
|
||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
||||
|
||||
//prints a b
|
||||
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z };
|
||||
Row_ShiftRegisters row_R1(9, sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1), ptrsKeys_R1);
|
||||
*/
|
||||
/*
|
||||
//prints 0 1 2
|
||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
||||
&s_2, &s_z, &s_z, &s_z };
|
||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
||||
*/
|
||||
/*
|
||||
//prints 0 1 2 3
|
||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z };
|
||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
||||
*/
|
||||
/*
|
||||
//prints 0 1 2 3 4 5
|
||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z,
|
||||
&s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z };
|
||||
Row_ShiftRegisters row_R0(8, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
||||
*/
|
||||
|
||||
//prints 0 1 2 3 3 4 5 6, microseconds_per_scan=87 with SAMPLE_COUNT 4
|
||||
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
|
||||
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z,
|
||||
&s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z,
|
||||
&s_6, &s_z, &s_z, &s_z, &s_3, &s_4, &s_5, &s_6 };
|
||||
Row_ShiftRegisters row_R0(0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
||||
|
||||
//prints a b c d u v w x
|
||||
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z,
|
||||
&s_c, &s_z, &s_z, &s_z, &s_d, &s_z, &s_z, &s_z,
|
||||
&s_e, &s_z, &s_z, &s_z, &s_f, &s_z, &s_z, &s_z,
|
||||
&s_g, &s_z, &s_z, &s_z, &s_u, &s_v, &s_w, &s_x };
|
||||
Row_ShiftRegisters row_R1(1, sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1), ptrsKeys_R1);
|
||||
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
||||
{
|
||||
Keyboard.begin();
|
||||
SPI.begin();
|
||||
row_R0.begin();
|
||||
row_R1.begin();
|
||||
|
||||
debug.wait_for_OS(LED1, 6);
|
||||
Keyboard.println(F("keybrd_shift_reg.ino"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//left matrix
|
||||
row_L0.process();
|
||||
row_L1.process();
|
||||
|
||||
//right matrix
|
||||
row_R0.process();
|
||||
row_R1.process();
|
||||
|
||||
scanDelay.delay();
|
||||
|
||||
//delay(100);
|
||||
//Keyboard.println("");
|
||||
//debug.print_microseconds_per_scan();
|
||||
}
|
BIN
images/datahand.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
@ -6,4 +6,4 @@ sentence=A library for creating custom-keyboard firmware.
|
||||
paragraph=<br>Create keyboards with any configuration:<br>one-piece, split with I/O expander, single-layer, multiple-layer
|
||||
category=Device Control
|
||||
url=https://github.com/wolfv6/keybrd
|
||||
architectures=avr
|
||||
architectures=*
|
||||
|
@ -8,8 +8,8 @@ Code_AutoShift can manage one or more shift keys.
|
||||
|
||||
Example initialization:
|
||||
const Code_Shift s_shift(MODIFIERKEY_LEFT_SHIFT);
|
||||
const Code_Shift *const ptrsS[] = { &s_shift };
|
||||
const Code_Shift *const *const Code_AutoShift::ptrsShifts = ptrsS;
|
||||
const Code_Shift*const ptrsS[] = { &s_shift };
|
||||
const Code_Shift*const *const Code_AutoShift::ptrsShifts = ptrsS;
|
||||
const uint8_t Code_AutoShift::shiftCount = sizeof(ptrsS)/sizeof(*ptrsS);
|
||||
The two Code_Shift pointer arrays (ptrsShifts and ptrsS) must have distinct names.
|
||||
|
||||
@ -18,14 +18,14 @@ The shift state for Code_ScS and Code_ScNS are changed and restored:
|
||||
Code_ScS object is a scancode shifted e.g. '%' in symbols layer
|
||||
Code_ScNS object is a scancode not shifted e.g. '5' in numbers layer
|
||||
|
||||
keyboards without Code_ScS and Code_ScNS can omit ptrsShifts[] array and
|
||||
keyboards without Code_ScS and Code_ScNS can omit ptrsShifts[] array and
|
||||
and place scancode MODIFIERKEY_LEFT_SHIFT directly in Code_Sc:
|
||||
Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT);
|
||||
*/
|
||||
class Code_AutoShift : public Code
|
||||
{
|
||||
private:
|
||||
static Code_Shift *const *const ptrsShifts; //array of Code_Shift pointers
|
||||
static Code_Shift*const *const ptrsShifts; //array of Code_Shift pointers
|
||||
static const uint8_t shiftCount;
|
||||
protected:
|
||||
bool isShifted() const;
|
||||
|
@ -16,14 +16,14 @@ Code_LEDLock::Code_LEDLock(const uint16_t scancode, LED& refLED)
|
||||
case KEY_SCROLL_LOCK:
|
||||
USB_LED_bit = 1<<2;
|
||||
break;
|
||||
/* guessing at these case names:
|
||||
case KEY_COMPOSE: //for separate accent keys
|
||||
USB_LED_bit = 1<<3; break;
|
||||
break;
|
||||
case KEY_KANA: //for Japanese keyboards
|
||||
USB_LED_bit = 1<<4; break;
|
||||
break;
|
||||
*/
|
||||
/* guessing at these case names:
|
||||
case KEY_COMPOSE: //for separate accent keys
|
||||
USB_LED_bit = 1<<3; break;
|
||||
break;
|
||||
case KEY_KANA: //for Japanese keyboards
|
||||
USB_LED_bit = 1<<4; break;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,12 +51,12 @@ TMK firmware, which is not Arduino, uses variable "usb_led" instead of "keyboard
|
||||
*/
|
||||
void Code_LEDLock::updateLED() const
|
||||
{
|
||||
/* KEY_SCROLL_LOCK is not working on Linux with Teensy2.0.
|
||||
This debug code prints "keyboard_leds=0" when scrollLock is pressed:
|
||||
Keyboard.print(F(" keyboard_leds="));
|
||||
Keyboard.print(keyboard_leds); //KEY_NUM_LOCK:1, KEY_CAPS_LOCK:2, KEY_SCROLL_LOCK:0
|
||||
Keyboard.print(" ");
|
||||
*/
|
||||
/* KEY_SCROLL_LOCK is not working on Linux with Teensy2.0.
|
||||
This debug code prints "keyboard_leds=0" when scrollLock is pressed:
|
||||
Keyboard.print(F(" keyboard_leds="));
|
||||
Keyboard.print(keyboard_leds); //KEY_NUM_LOCK:1, KEY_CAPS_LOCK:2, KEY_SCROLL_LOCK:0
|
||||
Keyboard.print(" ");
|
||||
*/
|
||||
if (keyboard_leds & USB_LED_bit) //if USB_LED_bit is set
|
||||
{
|
||||
refLED.off(); //LED on-off seem inverted, but it works for active low and active high
|
||||
|
@ -19,7 +19,7 @@ Output from keybrd/examples/debounce_unit_test.cpp with SAMPLE_COUNT_MACRO 4:
|
||||
isFallingEdge: 000000000000000000001
|
||||
isRisingEdge: 000000000001000000000
|
||||
There is a latency equal to SAMPLE_COUNT_MACRO, between button press and debounced signal.
|
||||
|
||||
|
||||
samples[SAMPLE_COUNT_MACRO] is a ring buffer. samplesIndex is it's current write index.
|
||||
SAMPLE_COUNT_MACRO is the number of consecutive equal samples needed to debounce.
|
||||
SAMPLE_COUNT_MACRO is a macro because it defines samples[SAMPLE_COUNT_MACRO] array size at compile time.
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
void Debug::printMicrosecondsPerScan()
|
||||
{
|
||||
static unsigned long nextTime = 0;
|
||||
static unsigned int scanCount = 0;
|
||||
|
||||
if (millis() >= nextTime)
|
||||
{
|
||||
Keyboard.print(1000000/scanCount); //print microseconds per scan
|
||||
@ -13,6 +16,9 @@ void Debug::printMicrosecondsPerScan()
|
||||
}
|
||||
void Debug::printScansPerSecond()
|
||||
{
|
||||
static unsigned long nextTime = 0;
|
||||
static unsigned int scanCount = 0;
|
||||
|
||||
if (millis() >= nextTime)
|
||||
{
|
||||
Keyboard.print(scanCount); //print scans per second
|
||||
|
@ -5,10 +5,6 @@
|
||||
|
||||
class Debug
|
||||
{
|
||||
private:
|
||||
unsigned long nextTime = 0;
|
||||
unsigned int scanCount = 0;
|
||||
|
||||
public:
|
||||
void printMicrosecondsPerScan(); //print microseconds per scan every second
|
||||
void printScansPerSecond(); //print scans per second every second
|
||||
|
@ -14,11 +14,11 @@ the Key object of the active layer is called.
|
||||
class Key_LayeredKeysArray : public Key
|
||||
{
|
||||
private:
|
||||
Key *const *const ptrsKeys; //array of Key pointers, one Key per layer
|
||||
Key*const *const ptrsKeys; //array of Key pointers, one Key per layer
|
||||
uint8_t layer; //active layer when key was pressed
|
||||
static LayerStateInterface& refLayerState;
|
||||
public:
|
||||
Key_LayeredKeysArray(Key *const ptrsKeys[]): ptrsKeys(ptrsKeys) {}
|
||||
Key_LayeredKeysArray(Key* const ptrsKeys[]): ptrsKeys(ptrsKeys) {}
|
||||
virtual void press();
|
||||
virtual void release();
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ configures column port's configuration, input, and pins.
|
||||
*/
|
||||
PortRead_PCA9655E::PortRead_PCA9655E (PortIOE& port, const uint8_t readPins)
|
||||
: PortRead(readPins), port(port),
|
||||
configurationByteCommand(port.num + 6), inputByteCommand(port.num)
|
||||
configurationByteCommand(port.num + 6), inputByteCommand(port.num)
|
||||
{}
|
||||
|
||||
void PortRead_PCA9655E::begin()
|
||||
|
@ -31,7 +31,7 @@ void Row::send(const uint8_t readPinCount, const read_pins_t debouncedChanged)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Row::keyWasPressed()
|
||||
{
|
||||
//empty in Row class. To unstick sticky keys, override keyWasPressed() in derived Row class.
|
||||
|
@ -15,10 +15,10 @@ class Row
|
||||
virtual void keyWasPressed();
|
||||
protected:
|
||||
read_pins_t debounced; //bitwise state of keys after debouncing
|
||||
// 1 means pressed, 0 means released
|
||||
// 1 means pressed, 0 means released
|
||||
void send(const uint8_t readPinCount, const read_pins_t debouncedChanged);
|
||||
public:
|
||||
Row(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
||||
Row(Key* const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
||||
virtual void process()=0;
|
||||
};
|
||||
#endif
|
||||
|
@ -39,7 +39,8 @@ class Row_ShiftRegisters : public Row
|
||||
Debouncer_Samples debouncer;
|
||||
const uint8_t readPinCount; //number of read pins
|
||||
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) { }
|
||||
void begin();
|
||||
void process();
|
||||
|
@ -33,9 +33,9 @@ class Row_uC : public Row
|
||||
const uint8_t readPinCount;
|
||||
public:
|
||||
Row_uC(const uint8_t strobePin, const uint8_t readPins[], const uint8_t readPinCount,
|
||||
Key *const ptrsKeys[])
|
||||
Key* const ptrsKeys[])
|
||||
: Row(ptrsKeys), scanner(strobePin, readPins, readPinCount),
|
||||
readPinCount(readPinCount) { }
|
||||
readPinCount(readPinCount) { }
|
||||
void process();
|
||||
};
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@ Adjust the value of DELAY_MICROSECONDS and repeat until:
|
||||
DEBOUNCE_TIME can be obtained from the switch's datasheet. Some switch bounce times are:
|
||||
Cherry MX specifies 5msec bounce time http://www.cherrycorp.com/english/switches/key/mx.htm
|
||||
hasu measured Cherry MX bounce times .3ms to 1.4ms http://geekhack.org/index.php?topic=42385.0
|
||||
Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures/MJTP_6MM.pdf
|
||||
Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures/MJTP_6MM.pdf
|
||||
|
||||
The largest allowable DELAY_MICROSECONDS is 65535 (65.535 ms).
|
||||
|
||||
|
@ -16,6 +16,6 @@ uint8_t Scanner_Port::scan()
|
||||
|
||||
//strobe off
|
||||
refPortWrite.write(strobePin, STROBE_OFF);
|
||||
|
||||
|
||||
return readState;
|
||||
}
|
||||
|
@ -33,11 +33,12 @@ In addition, each row needs to be connected to a strobe pin from the controller.
|
||||
class Scanner_ShiftRegs74HC165
|
||||
{
|
||||
private:
|
||||
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_OFF; //logic level of strobe off, complement of active state
|
||||
const uint8_t strobePin; //Arduino pin number connected to this row
|
||||
const uint8_t byte_count; //number of bytes to read from shift registers
|
||||
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_OFF; //logic level of strobe off, complement of active state
|
||||
const uint8_t strobePin; //Arduino pin number connected to this row
|
||||
const uint8_t byte_count; //number of bytes to read from shift registers
|
||||
public:
|
||||
Scanner_ShiftRegs74HC165(const uint8_t strobePin, const uint8_t readPinCount);
|
||||
virtual read_pins_t scan();
|
||||
|
@ -11,7 +11,7 @@ https://www.arduino.cc/en/Reference/Constants > Digital Pins modes: INPUT, INPUT
|
||||
/* constructor
|
||||
*/
|
||||
Scanner_uC::Scanner_uC(const uint8_t strobePin,
|
||||
const uint8_t readPins[], const uint8_t readPinCount)
|
||||
const uint8_t readPins[], const uint8_t readPinCount)
|
||||
: strobePin(strobePin), readPins(readPins), readPinCount(readPinCount)
|
||||
{
|
||||
uint8_t mode;
|
||||
|
@ -20,7 +20,7 @@ class Scanner_uC
|
||||
const uint8_t readPinCount; //number of read pins
|
||||
public:
|
||||
Scanner_uC(const uint8_t strobePin,
|
||||
const uint8_t readPins[], const uint8_t readPinCount);
|
||||
const uint8_t readPins[], const uint8_t readPinCount);
|
||||
virtual read_pins_t scan();
|
||||
};
|
||||
#endif
|
||||
|
@ -1,53 +0,0 @@
|
||||
// getFreeSRAM.h copied from
|
||||
// http://andybrown.me.uk/2011/01/01/debugging-avr-dynamic-memory-allocation/
|
||||
/*
|
||||
* memdebug.h
|
||||
*
|
||||
* Created on: 15 Dec 2010
|
||||
* Author: Andy Brown
|
||||
*
|
||||
* Use without attribution is permitted provided that this
|
||||
* header remains intact and that these terms and conditions
|
||||
* are followed:
|
||||
*
|
||||
* http://andybrown.me.uk/ws/terms-and-conditions
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
extern unsigned int __bss_end;
|
||||
extern unsigned int __heap_start;
|
||||
extern void *__brkval;
|
||||
|
||||
//measure and return amount of free SRAM
|
||||
/*
|
||||
uint16_t getFreeSRAM()
|
||||
{
|
||||
uint8_t newVariable;
|
||||
// if heap is empty, use bss as start memory address
|
||||
if ((uint16_t)__brkval == 0)
|
||||
{
|
||||
return (((uint16_t)&newVariable) - ((uint16_t)&__bss_end));
|
||||
}
|
||||
// else use heap end as the start of the memory address
|
||||
else
|
||||
{
|
||||
return (((uint16_t)&newVariable) - ((uint16_t)__brkval));
|
||||
}
|
||||
};
|
||||
*/
|
||||
// uint32_t for Teensy LC
|
||||
uint32_t getFreeSRAM()
|
||||
{
|
||||
uint8_t newVariable;
|
||||
// if heap is empty, use bss as start memory address
|
||||
if ((uint32_t)__brkval == 0)
|
||||
{
|
||||
return (((uint32_t)&newVariable) - ((uint32_t)&__bss_end));
|
||||
}
|
||||
// else use heap end as the start of the memory address
|
||||
else
|
||||
{
|
||||
return (((uint32_t)&newVariable) - ((uint32_t)__brkval));
|
||||
}
|
||||
};
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
49
tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino
Normal file
@ -0,0 +1,49 @@
|
||||
/* keybrd_1_breadboard.ino
|
||||
|
||||
| Layout | **0** | **1** |
|
||||
|:------:|-------|-------|
|
||||
| **0** | 1 | a |
|
||||
| **1** | b | c |
|
||||
*/
|
||||
// ################## GLOBAL ###################
|
||||
// ================= INCLUDES ==================
|
||||
#include <ScanDelay.h>
|
||||
#include <Code_Sc.h>
|
||||