2016-07-18 02:03:03 +00:00
|
|
|
/* keybrd_2_single-layer.ino
|
2016-05-09 14:05:08 +00:00
|
|
|
|
|
|
|
This sketch:
|
2016-07-18 02:03:03 +00:00
|
|
|
is firmware for a simple 1-layer keyboard
|
2016-05-09 14:05:08 +00:00
|
|
|
runs on the first two rows and columns of a breadboard keyboard
|
|
|
|
|
|
|
|
This layout table shows how keys are arranged on the keyboard:
|
|
|
|
|
|
|
|
| Layout | **0** | **1** |
|
|
|
|
|:------:|-------|-------|
|
2016-07-18 02:03:03 +00:00
|
|
|
| **0** | shift | a |
|
|
|
|
| **1** | b | c |
|
2016-05-09 14:05:08 +00:00
|
|
|
|
|
|
|
The layout's row and column numbers are in the headers.
|
|
|
|
Each cell in the table's body represents a key.
|
|
|
|
|
2016-07-18 02:26:00 +00:00
|
|
|
The following sketch is annotated with a walk-through narrative enclosed in comment blocks.
|
2016-05-09 14:05:08 +00:00
|
|
|
Each comment block explains the next one or two lines of code.
|
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
keybrd objects are instantiated under the "GLOBAL" heading.
|
|
|
|
The keyboard runs at the end of the sketch, under the "MAIN" heading.
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
|
|
|
// ################## GLOBAL ###################
|
2016-07-18 02:26:00 +00:00
|
|
|
/* ================= INCLUDES ==================
|
2016-05-09 14:05:08 +00:00
|
|
|
All the includes in this sketch are to keybrd library classes.
|
|
|
|
*/
|
2016-07-18 02:03:03 +00:00
|
|
|
#include <ScanDelay.h>
|
2016-05-09 14:05:08 +00:00
|
|
|
#include <Code_Sc.h>
|
2016-07-18 02:03:03 +00:00
|
|
|
#include <Row_uC.h>
|
2016-05-09 14:05:08 +00:00
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
/* ============ SPEED CONFIGURATION ============
|
|
|
|
ScanDelay specifies microsecond between matrix scans.
|
2016-05-09 14:05:08 +00:00
|
|
|
Keyboard switches are made of moving contacts.
|
|
|
|
When the contacts close, they bounce apart one or more times before making steady contact.
|
2016-07-18 02:03:03 +00:00
|
|
|
ScanDelay gives the switches time to debounce.
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
2016-07-18 02:03:03 +00:00
|
|
|
ScanDelay scanDelay(9000);
|
2016-05-09 14:05:08 +00:00
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
/* ================ ACTIVE STATE ===============
|
|
|
|
The read pins detect which keys are pressed while a row is strobed.
|
|
|
|
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.
|
|
|
|
To make this sketch active low, STROBE_ON should be LOW (tutorial 6 coveres this in more detail).
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
2016-07-18 02:26:00 +00:00
|
|
|
const bool Scanner_uC::STROBE_ON = LOW; //set scanner for active low
|
2016-07-18 02:03:03 +00:00
|
|
|
const bool Scanner_uC::STROBE_OFF = HIGH;
|
2016-05-09 14:05:08 +00:00
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
/* ================= PINS =================
|
2016-07-22 08:11:38 +00:00
|
|
|
Microcontroller 14 and 15 are connected to the matrix columns.
|
2016-07-18 02:03:03 +00:00
|
|
|
These readPins detect which keys are pressed while a row is strobed.
|
2016-05-09 14:05:08 +00:00
|
|
|
|
|
|
|
sizeof() is used to compute the number of array elements.
|
2016-07-18 02:26:00 +00:00
|
|
|
This eliminates the risk of forgetting to update the count
|
|
|
|
after adding or removing an element from the array.
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
2016-07-18 02:03:03 +00:00
|
|
|
uint8_t readPins[] = {14, 15};
|
|
|
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
2016-05-09 14:05:08 +00:00
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
/* =================== CODES ===================
|
|
|
|
Four Codes are instantiated, one for each key in the layout.
|
|
|
|
The Code object names in this sketch start with a "s_" prefix.
|
2016-05-09 14:05:08 +00:00
|
|
|
|
|
|
|
The Code_Sc constructor takes one scancode ("Sc" means "scancode").
|
2016-07-18 02:03:03 +00:00
|
|
|
When Code_Sc is pressed, it sends the scancode.
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
|
|
|
Code_Sc s_a(KEY_A);
|
|
|
|
Code_Sc s_b(KEY_B);
|
|
|
|
Code_Sc s_c(KEY_C);
|
|
|
|
Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT);
|
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
/* =================== ROWS ====================
|
2016-07-18 02:26:00 +00:00
|
|
|
Here we pack Code objects into Row objects.
|
2016-05-09 14:05:08 +00:00
|
|
|
The Row objects names in this sketch start with a "row_" followed by a row number.
|
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
Row_uC constructor has four parameters:
|
2016-07-18 02:26:00 +00:00
|
|
|
1) strobePin connected to the row.
|
2016-07-18 02:03:03 +00:00
|
|
|
2) readPins[] connected to the colums.
|
|
|
|
3) the number of readPins.
|
|
|
|
4) ptrsKeys[] containing all the Code objects of the row, one Code object per key.
|
2016-05-09 14:05:08 +00:00
|
|
|
|
|
|
|
*/
|
2016-07-18 02:03:03 +00:00
|
|
|
Key* ptrsKeys_0[] = { &s_shift, &s_a };
|
|
|
|
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
2016-05-09 14:05:08 +00:00
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
Key* ptrsKeys_1[] = { &s_b, &s_c };
|
|
|
|
Row_uC row_1(1, readPins, READ_PIN_COUNT, ptrsKeys_1);
|
2016-05-09 14:05:08 +00:00
|
|
|
|
2016-07-18 02:03:03 +00:00
|
|
|
/* ################### MAIN ####################
|
|
|
|
setup() is used to initialize the keyboard firmware. Keyboard.begin() should be called once.
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
Keyboard.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2016-07-18 02:03:03 +00:00
|
|
|
loop() continually scans the matrix, one row at a time.
|
2016-07-18 02:26:00 +00:00
|
|
|
Each row object strobes its strobePin and reads the readPins.
|
2016-07-18 02:03:03 +00:00
|
|
|
And when a key press is detected, the row sends the key's scancode.
|
|
|
|
|
|
|
|
scanDelay creates time intervals between matrix scans.
|
|
|
|
A debouncer uses this time interval to debounce key presses and releases.
|
2016-05-09 14:05:08 +00:00
|
|
|
*/
|
|
|
|
void loop()
|
|
|
|
{
|
2016-07-18 02:03:03 +00:00
|
|
|
row_0.process();
|
|
|
|
row_1.process();
|
|
|
|
scanDelay.delay();
|
2016-05-09 14:05:08 +00:00
|
|
|
}
|