From 9c99fd7ba7ade12a2a6460d2aa382113cf717c85 Mon Sep 17 00:00:00 2001 From: wolfv6 Date: Sat, 24 Sep 2016 22:27:06 -0600 Subject: [PATCH] update sketches --- doc/keybrd_library_developer_guide.md | 4 +- examples/keybrd_PCA9655E/keybrd_PCA9655E.ino | 6 +- src/Key.h | 1 + src/Scanner_ShiftRegsPISOMultiRow.cpp | 51 ++++++++++++++++ src/Scanner_ShiftRegsPISOMultiRow.h | 56 ++++++++++++++++++ src/Scanner_ShiftRegsPISOSingleRow.cpp | 43 ++++++++++++++ src/Scanner_ShiftRegsPISOSingleRow.h | 58 +++++++++++++++++++ ...4b_split_keyboard_with_shift_registers.ino | 4 +- .../keybrd_4c_split_keyboard_with_IOE.ino | 11 ++-- .../keybrd_5a_LED_on_uC.ino | 9 +-- 10 files changed, 225 insertions(+), 18 deletions(-) create mode 100644 src/Scanner_ShiftRegsPISOMultiRow.cpp create mode 100644 src/Scanner_ShiftRegsPISOMultiRow.h create mode 100644 src/Scanner_ShiftRegsPISOSingleRow.cpp create mode 100644 src/Scanner_ShiftRegsPISOSingleRow.h diff --git a/doc/keybrd_library_developer_guide.md b/doc/keybrd_library_developer_guide.md index dd3f158..4677e2f 100644 --- a/doc/keybrd_library_developer_guide.md +++ b/doc/keybrd_library_developer_guide.md @@ -118,7 +118,7 @@ Dependency diagram of example I/O expander matrix with LEDs / | \ / \ strobePin PortWrite PortRead Code Code_LEDLock | \ / \ | - | PortIOE readPins LED + | PortIOE readPins LED_IOE \___________________________/ \ pin @@ -138,7 +138,7 @@ This convention leads to class names that convey information about the classes i Underscore delineates base class name and sub-class name. Capital letters delineate words. Interface class names end with "Interface". -Except for Key, because sketches look nicer with short names defining Key[] arrays. +Except for Key, to reduce clutter because sketches define so many Key[] arrays. Layer-class naming conventions ------------------------------ diff --git a/examples/keybrd_PCA9655E/keybrd_PCA9655E.ino b/examples/keybrd_PCA9655E/keybrd_PCA9655E.ino index 3669f01..da86109 100644 --- a/examples/keybrd_PCA9655E/keybrd_PCA9655E.ino +++ b/examples/keybrd_PCA9655E/keybrd_PCA9655E.ino @@ -16,7 +16,7 @@ #include //right matrix -#include +#include #include // ============ SPEED CONFIGURATION ============ @@ -31,8 +31,8 @@ Scanner_uC scanner_L(HIGH, readPins, readPinCount); // =============== RIGHT SCANNER =============== const uint8_t IOE_ADDR = 0x18; -PortPCA9655E port1(IOE_ADDR, 1, 0); //for strobe -PortPCA9655E port0(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read +Port_PCA9655E port1(IOE_ADDR, 1, 0); //for strobe +Port_PCA9655E port0(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read Scanner_IOE scanner_R(HIGH, port1, port0); diff --git a/src/Key.h b/src/Key.h index 2034ab6..c41c0db 100644 --- a/src/Key.h +++ b/src/Key.h @@ -8,6 +8,7 @@ #include /* Key is an interface class +Key class name does not end in "Interface" because sketches define so many Key[] arrays. */ class Key { diff --git a/src/Scanner_ShiftRegsPISOMultiRow.cpp b/src/Scanner_ShiftRegsPISOMultiRow.cpp new file mode 100644 index 0000000..81f703d --- /dev/null +++ b/src/Scanner_ShiftRegsPISOMultiRow.cpp @@ -0,0 +1,51 @@ +#include "Scanner_ShiftRegsPISOMultiRow.h" + +/* constructor +*/ +Scanner_ShiftRegsPISOMultiRow::Scanner_ShiftRegsPISOMultiRow(const bool strobeOn, + const uint8_t slaveSelect, const uint8_t byte_count) + : strobeOn(strobeOn), strobeOff(!strobeOn), + slaveSelect(slaveSelect), byte_count(byte_count) +{ + pinMode(slaveSelect, OUTPUT); +} + +/* init() is called once for each row from Row constructor. +Configures controller to communicate with shift register matrix. +*/ +void Scanner_ShiftRegsPISOMultiRow::init(const uint8_t strobePin) +{ + pinMode(strobePin, OUTPUT); +} + +/* begin() should be called once from sketch setup(). +Initializes shift register's shift/load pin. +*/ +void Scanner_ShiftRegsPISOMultiRow::begin() +{ + digitalWrite(slaveSelect, HIGH); +} + +/* scan() strobes the row's strobePin and returns state of the shift register's input pins. +strobePin is Arduino pin number connected to this row. +Bit patterns are 1 bit per key. +*/ +read_pins_t Scanner_ShiftRegsPISOMultiRow::scan(const uint8_t strobePin) +{ + read_pins_t readState = 0; //bits, 1 means key is pressed, 0 means released + + //strobe row on + digitalWrite(strobePin, strobeOn); + delayMicroseconds(3); //time to stablize voltage + + //read all the column pins + digitalWrite(slaveSelect, LOW); //load parallel inputs to the register + digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output + SPI.transfer(&readState, byte_count); + + //strobe row off + digitalWrite(strobePin, strobeOff); + + return readState; +} + diff --git a/src/Scanner_ShiftRegsPISOMultiRow.h b/src/Scanner_ShiftRegsPISOMultiRow.h new file mode 100644 index 0000000..c8c6c75 --- /dev/null +++ b/src/Scanner_ShiftRegsPISOMultiRow.h @@ -0,0 +1,56 @@ +#ifndef ROWSCANNER_SHIFTREGSPISOMULTIROW_H +#define ROWSCANNER_SHIFTREGSPISOMULTIROW_H + +#include +#include +#include +#include +#include + +/* Scanner_ShiftRegsPISOMultiRow reads shift registers. +This was tested on 74HC165 shift registers, which are Parallel-In-Serial-Out (PISO). +Upto 4 shift registers can be in a daisy chained for a total of 32 read pins. + +Example instantiation: + Scanner_ShiftRegsPISOMultiRow scanner_R(HIGH, SS, 4); + +There are three Scanner_ShiftRegsPISOMultiRow parameters. +"strobeOn" paramter is active state HIGH or LOW. + +"slaveSelect" paramter can be any controller pin connected to shift register's SHIFT-LOAD pin. +slaveSelect pin SS (Arduino pin 10) has the fastest scan. + +"byte_count" is the number of bytes to read from shift registers (1 to 4). +byte_count should cover all the row's keys: + byte_count*8 >= row's keyCount + +Hardware setup: +Each row needs to be connected to a strobe pin from the controller. +Switche and diode in series are connected to shift-register parallel-input pins and strobed row. + +For active low: +Shift-register parallel-input pins need 10k Ohm pull-up resistors powered. +Orient diodes with cathode (banded end) towards the write pins (row) +Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin + +For active high: +Shift-register parallel-input pins need 10k pull-down resistors grounded. +Orient diodes with cathode (banded end) towards the read pins. +Controller's MISO pin is connected to shift register's serial output (QH) pin +*/ +class Scanner_ShiftRegsPISOMultiRow : public ScannerInterface +{ + private: + const bool strobeOn; //logic level of strobe on, active state HIGH or LOW + const bool strobeOff; //logic level of strobe off, complement of strobeOn + const uint8_t slaveSelect; //controller's pin number that is + // connected to shift register's SHIFT-LOAD pin + const uint8_t byte_count; //number of bytes to read from shift registers + public: + Scanner_ShiftRegsPISOMultiRow(const bool strobeOn, + const uint8_t slaveSelect, const uint8_t byte_count); + virtual void init(const uint8_t strobePin); + virtual void begin(); + virtual read_pins_t scan(const uint8_t strobePin); +}; +#endif diff --git a/src/Scanner_ShiftRegsPISOSingleRow.cpp b/src/Scanner_ShiftRegsPISOSingleRow.cpp new file mode 100644 index 0000000..60e31dc --- /dev/null +++ b/src/Scanner_ShiftRegsPISOSingleRow.cpp @@ -0,0 +1,43 @@ +#include "Scanner_ShiftRegsPISOSingleRow.h" + +/* constructor +*/ +Scanner_ShiftRegsPISOSingleRow::Scanner_ShiftRegsPISOSingleRow(const bool strobeOn, + const uint8_t slaveSelect, const uint8_t byte_count) + : slaveSelect(slaveSelect), byte_count(byte_count) +{ + pinMode(slaveSelect, OUTPUT); +} + +/* init() is called once for each row from Row constructor. +*/ +void Scanner_ShiftRegsPISOSingleRow::init(const uint8_t strobePin) +{ + //empty function +} + +/* begin() should be called once from sketch setup(). +Initializes shift register's shift/load pin. +*/ +void Scanner_ShiftRegsPISOSingleRow::begin() +{ + SPI.begin(); + digitalWrite(slaveSelect, HIGH); +} + +/* scan() returns state of the shift register's input pins. +No strobe pin is needed, the shift register is wired so the strobe is effectivley always "on". +Bit patterns are 1 bit per key. +*/ +read_pins_t Scanner_ShiftRegsPISOSingleRow::scan(const uint8_t strobePin) +{ + read_pins_t readState = 0; //bits, 1 means key is pressed, 0 means released + + //read all the column pins + digitalWrite(slaveSelect, LOW); //load parallel inputs to the register + digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output + SPI.transfer(&readState, byte_count); + + return readState; +} + diff --git a/src/Scanner_ShiftRegsPISOSingleRow.h b/src/Scanner_ShiftRegsPISOSingleRow.h new file mode 100644 index 0000000..362fdcd --- /dev/null +++ b/src/Scanner_ShiftRegsPISOSingleRow.h @@ -0,0 +1,58 @@ +#ifndef ROWSCANNER_SHIFTREGSPISOSINGLEROW_H +#define ROWSCANNER_SHIFTREGSPISOSINGLEROW_H + +#include +#include +#include +#include +#include + +/* Scanner_ShiftRegsPISOSingleRow reads shift registers. +This was tested on 74HC165 shift registers, which are Parallel-In-Serial-Out (PISO). +Upto 4 shift registers can be in a daisy chained for a total of 32 read pins. + +Example instantiation: + Row row_R0(scanner_R, 0, ptrsKeys_R0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0)); + Scanner_ShiftRegsPISOSingleRow scanner_R(HIGH, SS, 4); + +The Row "strobePin" parameter is ignored. +In the above example, the "strobePin" argument is 0, but it doesn't matter what value is given. + +There are three Scanner_ShiftRegsPISOSingleRow parameters. +"strobeOn" paramter is ignored, but should be active state HIGH or LOW required by ScannerInterface. + +"slaveSelect" paramter can be any controller pin connected to shift register's SHIFT-LOAD pin. +slaveSelect pin SS (Arduino pin 10) has the fastest scan. + +"byte_count" is the number of bytes to read from shift registers (1 to 4). +byte_count should cover all the row's keys: + byte_count*8 >= row's keyCount + +Hardware setup: +There is only one row, and it is permanently active. +Switches are connected to shift-register parallel-input pins (diodes are not needed) and row. + +For active low: +Shift-register parallel-input pins need 10k Ohm pull-up resistors powered. +Switches connect powered row to parallel-input pins. +Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin + +For active high: +Shift-register parallel-input pins need 10k pull-down resistors grounded. +Switches connect grouned row to parallel-input pins. +Controller's MISO pin is connected to shift register's serial output (QH) pin +*/ +class Scanner_ShiftRegsPISOSingleRow : public ScannerInterface +{ + private: + const uint8_t slaveSelect; //controller's pin number that is + // connected to shift register's SHIFT-LOAD pin + const uint8_t byte_count; //number of bytes to read from shift registers + public: + Scanner_ShiftRegsPISOSingleRow(const bool strobeOn, + const uint8_t slaveSelect, const uint8_t byte_count); + void init(const uint8_t strobePin); + void begin(); + virtual read_pins_t scan(const uint8_t strobePin); +}; +#endif diff --git a/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino b/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino index 4356d73..0391cd0 100644 --- a/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino +++ b/tutorials/keybrd_4b_split_keyboard_with_shift_registers/keybrd_4b_split_keyboard_with_shift_registers.ino @@ -1,9 +1,7 @@ /* tutorial_4b_split_keyboard_with_shift_registers.ino Tested on Teensy LC and two 74HC165 shift registers. -The right matrix has 2 shift registers daisy chained. - - Layout Layout + Controller Two shift registers daisy chained | Left |**0**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**| |:-----:|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----| | **0** | x | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | diff --git a/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino b/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino index 98cf93a..95a7938 100644 --- a/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino +++ b/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino @@ -4,8 +4,7 @@ This sketch: is a simple 1-layer keyboard runs on two matrices of a breadboard keyboard -This layout table shows left and right matrices: - + Controller I/O expander | Left | **0** | **1** | | Right | **0** | **1** | |:-----:|-------|-------|-|:-----:|-------|-------| | **1** | 1 | 2 | | **1** | 3 | 4 | @@ -21,7 +20,7 @@ This layout table shows left and right matrices: #include //right matrix -#include +#include #include // ============ SPEED CONFIGURATION ============ @@ -44,14 +43,14 @@ const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR p /* Normally all strobe pins are on one port, and all the read pins are on the other port. In this example, portB stobes the row while portA reads the colums. -PortMCP23S17 constructor parameters are: deviceAddr, portNum, readPins +Port_MCP23S17 constructor parameters are: deviceAddr, portNum, readPins readPins is a bit pattern, where 0=output, 1=input. In portA, the first two pins are set to input for reading. "<<" (bit shift left) and "|" (OR) are bitwise operators. Pin numbers to be read are to the right of "1<<" and delimited by "|". */ -PortMCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); -PortMCP23S17 portB(IOE_ADDR, 1, 0); +Port_MCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); +Port_MCP23S17 portB(IOE_ADDR, 1, 0); Scanner_IOE scanner_R(LOW, portB, portA); // =================== CODES =================== diff --git a/tutorials/keybrd_5a_LED_on_uC/keybrd_5a_LED_on_uC.ino b/tutorials/keybrd_5a_LED_on_uC/keybrd_5a_LED_on_uC.ino index 7c3ab41..87a62ad 100644 --- a/tutorials/keybrd_5a_LED_on_uC/keybrd_5a_LED_on_uC.ino +++ b/tutorials/keybrd_5a_LED_on_uC/keybrd_5a_LED_on_uC.ino @@ -7,7 +7,7 @@ This sketch: | Layout | **0** | **1** | |:------:|-------|-------| | **0** |CapsLck| a 1 | -| **1** | fn | b 2 | +| **1** | fn | x = | */ // ################## GLOBAL ################### @@ -63,15 +63,16 @@ For example, when o_capsLock is pressed, it sends KEY_CAPS_LOCK scancode and upd Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED_CapsLck); Code_Sc s_a(KEY_A); -Code_Sc s_b(KEY_B); +Code_Sc s_x(KEY_X); + Code_Sc s_1(KEY_1); -Code_Sc s_2(KEY_2); +Code_Sc s_equal(KEY_EQUAL); // =================== KEYS ==================== Key* const ptrsKeys_01[] = { &s_a, &s_1 }; Key_LayeredKeys k_01(ptrsKeys_01); -Key* const ptrsKeys_11[] = { &s_b, &s_2 }; +Key* const ptrsKeys_11[] = { &s_x, &s_equal }; Key_LayeredKeys k_11(ptrsKeys_11); LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;