Archived
1
0

change class and variable names

This commit is contained in:
wolfv6 2016-07-12 07:23:24 -06:00
parent d5cbc3c58c
commit a5d6fb8d9e
27 changed files with 296 additions and 304 deletions

View File

@ -13,14 +13,14 @@ Debouncer and I/O expander use bit manipulation.
## Custom Row classes ## Custom Row classes
The keybrd library is flexible for designing custom Rows The keybrd library is flexible for designing custom Rows
* RowBase 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 a matrix on each hand
Row_Ext::keyWasPressed() overrides RowBase::keyWasPressed() Row_Ext::keyWasPressed() overrides Row::keyWasPressed()
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 scans the primary matrix
@ -30,14 +30,14 @@ Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock key
Class inheritance diagram Class inheritance diagram
``` ```
RowBase Row
| |
Row_Ext (override RowBase::keyWasPressed() ) Row_Ext (override Row::keyWasPressed() )
/ \ / \
Row_Ext_uC Row_Ext_ShiftRegisters (inherit Row_Ext::keyWasPressed() ) Row_Ext_uC Row_Ext_ShiftRegisters (inherit Row_Ext::keyWasPressed() )
RowScanner_PinsArray RowScanner_SPIShiftRegisters Scanner_uC Scanner_ShiftRegs74HC165
``` ```
@ -46,16 +46,16 @@ Dependency diagram
________ Row_Ext_uC[1] _______________ ________ Row_Ext_uC[1] _______________
/ \ \ / \ \
RowScanner_PinsArray[1] Debouncer_Samples[1] Key[1..*] Scanner_uC[1] Debouncer_Samples[1] Key[1..*]
/ \ | / \ |
strobePin[1] readPins[1..*] Code[1..*] strobePin[1] readPins[1..*] Code[1..*]
_____ Row_Ext_ShiftRegisters[1] ___________ _____ Row_Ext_ShiftRegisters[1] ________
/ \ \ / \ \
RowScanner_SPIShiftRegisters[1] Debouncer_Samples[1] Key[1..*] Scanner_ShiftRegs74HC165[1] Debouncer_Samples[1] Key[1..*]
/ \ | / \ |
strobePin[1] ROW_END[1] Code[1..*] strobePin[1] ROW_END[1] Code[1..*]
``` ```
@ -63,23 +63,23 @@ Dependency diagram
Keybrd library class inheritance diagram Keybrd library class inheritance diagram
``` ```
_______ RowBase ________ ________ Row ___________
/ | \ / | \
Row_uC Row_ShiftRegisters Row_IOE Row_uC Row_ShiftRegisters Row_IOE (to be added)
RowScanner_PinsArray RowScanner_PinsBitwise RowScanner_SPIShiftRegisters Scanner_uC Scanner_Port Scanner_ShiftRegs74HC165
IOExpanderPort IOEPort
RowPort StrobePort
| |
RowPort_PCA9655E (one RowPort class for each IOE type) StrobePort_PCA9655E (one StrobePort class for each IOE type)
ColPort ReadPort
| |
ColPort_PCA9655E (one ColPort class for each IOE type) ReadPort_PCA9655E (one ReadPort class for each IOE type)
____ LED ____ ____ LED ____
/ \ / \
@ -124,30 +124,30 @@ Keybrd library class inheritance diagram
Example single-layer dependency diagram with LEDs Example single-layer dependency diagram with LEDs
``` ```
___ Row_uC[1..*] ________ _ Row_uC[1..*] _
/ \ \ / | \
RowScanner_PinsArray Debouncer Keys[1..*] __ Scanner_uC Debouncer Keys[1..*] __
| \ | \
Code[1..*] Code_LEDLock[1..*] Code[1..*] Code_LEDLock[1..*]
| |
LED_PinNumber[1] LED_PinNumber[1]
``` ```
Example multi-layer dependency diagram with layer LEDs Example multi-layer dependency diagram with layer LEDs
``` ```
LayerStates[1..*] LayerStates[1..*]
________ Row_uC[1..*] _____________________/__ | \ ________ Row_uC[1..*] ___________/__ | \
/ \ \ / \ | \ / | \ / \ | \
RowScanner_PinsArray[1] Debouncer[1] Keys[1..*] / Code_Layer[1..*] LED_PinNumber[0..*] Scanner_uC[1] Debouncer[1] Keys[1..*] / Code_Layer[1..*] LED_PinNumber[0..*]
| / | /
Code[1..*] Code[1..*]
``` ```
Example secondary matrix with shift registers dependency diagram Example secondary matrix with shift registers dependency diagram
``` ```
Row_ShiftRegisters[1..*] Row_ShiftRegisters[1..*]
/ \ \ / \ \
RowScanner_ShiftRegisters Debouncer Keys[1..*] RowScanner_ShiftRegisters Debouncer Keys[1..*]
| |
@ -159,13 +159,13 @@ Example secondary matrix with I/O Expander dependency diagram with LEDs
``` ```
___ Row_IOE[1..*] _________ ___ Row_IOE[1..*] _________
/ \ \ / \ \
RowScanner_PinsBitwise[1] Debouncer[1] Keys[1..*] __ __ Scanner_Port[1] _ Debouncer[1] Keys[1..*] __
/ | \ | \ / | \ | \
RowPort[1] RowPin[1] ColPort[1] Code[1..*] Code_LEDLock[1..*] StrobePort[1] RowPin[1] ReadPort[1] Code[1..*] Code_LEDLock[1..*]
\ / \ | \ / \ |
\ / ColPins[1..*] LED[1] \ / ColPins[1..*] LED[1]
\ / \ /
IOExpanderPort[0..*] IOEPort[0..*]
``` ```
@ -240,13 +240,13 @@ Refer to it like a table of contents while reading the keybrd library.
``` ```
loop() for each row loop() for each row
RowBase::process() Row::process()
RowScanner_PinsArray::scan() strobe row on Scanner_uC::scan() strobe row on
for each readPin for each readPin
set rowState bit set rowState bit
strobe row off strobe row off
Debouncer_4Samples::debounce() debounce Debouncer_4Samples::debounce() debounce
RowBase::pressRelease() for each key in row Row::pressRelease() for each key in row
if falling edge if falling edge
Key_*::release() scanCode->release() Key_*::release() scanCode->release()
Code_*::release() Keyboard.release(scancode) Code_*::release() Keyboard.release(scancode)

View File

@ -3,11 +3,11 @@ Tested on Teensy LC and daisy chained 74HC165 shift registers
The keyboard hardware for this sketch has 4 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. 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 RowScanner_SPIShiftRegisters::scan(): Unused input pins are not grounded, so add this line to Scanner_ShiftRegs74HC165::scan():
//clear unpowered pins (for testing on breadboard) //clear unpowered pins (for testing on breadboard)
rowState &= 0b11110001000100010001000100010001; //todo rowState &= 0b11110001000100010001000100010001; //todo
Layout Layout Layout
| Left | **0**|**1**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**|**8**| | 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 | | **0** |capLck| a | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
@ -32,20 +32,20 @@ Layout
ScanDelay scanDelay(9000); ScanDelay scanDelay(9000);
//active state of left matrix //active state of left matrix
const bool RowScanner_PinsArray::STROBE_ON = LOW; const bool Scanner_uC::STROBE_ON = LOW;
const bool RowScanner_PinsArray::STROBE_OFF = HIGH; const bool Scanner_uC::STROBE_OFF = HIGH;
const uint8_t RowScanner_SPIShiftRegisters::SHIFT_LOAD = 10; const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
//active state of right matrix //active state of right matrix
const bool RowScanner_SPIShiftRegisters::STROBE_ON = LOW; const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW;
const bool RowScanner_SPIShiftRegisters::STROBE_OFF = HIGH; const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH;
Debug debug; Debug debug;
// ================= LEFT PINS ================= // ================= LEFT PINS =================
uint8_t readPins[] = {14, 15}; uint8_t readPins[] = {14, 15};
uint8_t KEY_COUNT = sizeof(readPins)/sizeof(*readPins); uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
// ==================== LEDs =================== // ==================== LEDs ===================
LED_PinNumber LED1(16); LED_PinNumber LED1(16);
@ -98,48 +98,48 @@ Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED1);
// ================= LEFT ROWS ================= // ================= LEFT ROWS =================
Key* ptrsKeys_L0[] = { &o_capsLock, &s_a }; Key* ptrsKeys_L0[] = { &o_capsLock, &s_a };
Row_uC row_L0(0, readPins, ptrsKeys_L0, KEY_COUNT); Row_uC row_L0(0, readPins, ptrsKeys_L0, READ_PIN_COUNT);
Key* ptrsKeys_L1[] = { &s_b, &s_c }; Key* ptrsKeys_L1[] = { &s_b, &s_c };
Row_uC row_L1(1, readPins, ptrsKeys_L1, KEY_COUNT); Row_uC row_L1(1, readPins, ptrsKeys_L1, READ_PIN_COUNT);
// ================= RIGHT ROWS ================ // ================= RIGHT ROWS ================
//typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h //typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h
//Row_ShiftRegisters(STROBE_PIN, ptrsKeys[], KEY_COUNT) //Row_ShiftRegisters(STROBE_PIN, ptrsKeys[], READ_PIN_COUNT)
//the s_z are place holders and should not print //the s_z are place holders and should not print
/* /*
//prints 0 1 //prints 0 1
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z }; Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z };
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0); const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, ptrsKeys_R0, KEY_R0_COUNT); Row_ShiftRegisters row_R0(8, ptrsKeys_R0, READ_PIN_COUNT_R0);
//prints a b //prints a b
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z }; Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z };
const uint8_t KEY_R1_COUNT = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1); const uint8_t READ_PIN_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
Row_ShiftRegisters row_R1(9, ptrsKeys_R1, KEY_R1_COUNT); Row_ShiftRegisters row_R1(9, ptrsKeys_R1, READ_PIN_COUNT_R1);
*/ */
/* /*
//prints 0 1 2 //prints 0 1 2
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z, 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_2, &s_z, &s_z, &s_z };
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0); const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, ptrsKeys_R0, KEY_R0_COUNT); Row_ShiftRegisters row_R0(8, ptrsKeys_R0, READ_PIN_COUNT_R0);
*/ */
/* /*
//prints 0 1 2 3 //prints 0 1 2 3
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z, 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_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z };
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0); const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, ptrsKeys_R0, KEY_R0_COUNT); Row_ShiftRegisters row_R0(8, ptrsKeys_R0, READ_PIN_COUNT_R0);
*/ */
/* /*
//prints 0 1 2 3 4 5 //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, 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_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_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z };
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0); const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, ptrsKeys_R0, KEY_R0_COUNT); Row_ShiftRegisters row_R0(8, ptrsKeys_R0, READ_PIN_COUNT_R0);
*/ */
//prints 0 1 2 3 3 4 5 6, microseconds_per_scan=87 with SAMPLE_COUNT 4 //prints 0 1 2 3 3 4 5 6, microseconds_per_scan=87 with SAMPLE_COUNT 4
@ -147,16 +147,16 @@ 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_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_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 }; &s_6, &s_z, &s_z, &s_z, &s_3, &s_4, &s_5, &s_6 };
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0); const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(0, ptrsKeys_R0, KEY_R0_COUNT); Row_ShiftRegisters row_R0(0, ptrsKeys_R0, READ_PIN_COUNT_R0);
//prints a b c d u v w x //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, 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_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_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 }; &s_g, &s_z, &s_z, &s_z, &s_u, &s_v, &s_w, &s_x };
const uint8_t KEY_R1_COUNT = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1); const uint8_t READ_PIN_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
Row_ShiftRegisters row_R1(1, ptrsKeys_R1, KEY_R1_COUNT); Row_ShiftRegisters row_R1(1, ptrsKeys_R1, READ_PIN_COUNT_R1);
// ################### MAIN #################### // ################### MAIN ####################
void setup() void setup()

View File

@ -1,13 +0,0 @@
#include "ColPort.h"
uint8_t ColPort::getColPins()
{
return colPins;
}
uint8_t ColPort::getPortState()
{
//todo Keyboard.print(" portState=");
//Keyboard.print(portState);
return portState;
}

View File

@ -2,19 +2,19 @@
#define IOEXPANDERPORT_H #define IOEXPANDERPORT_H
#include <inttypes.h> #include <inttypes.h>
/* The pins of an IC's port can be split between RowPort, ColPort, and LED. /* The pins of an IC's port can be split between StrobePort, ReadPort, and LED.
IOExpanderPort contains outputVal, the value of a port's output register. IOEPort contains outputVal, the value of a port's output register.
outputVal is used for port manipulation by classes RowPort and LED. outputVal is used for port manipulation by classes StrobePort and LED.
One port's outputVal can be shared by one RowPort object and multiple LED objects. One port's outputVal can be shared by one StrobePort object and multiple LED objects.
IOExpanderPort is only used by I/O expander port classes. IOEPort is only used by I/O expander port classes.
AVR port classes do not need a similar class because PORTx is global in the Arduino library. AVR port classes do not need a similar class because PORTx is global in the Arduino library.
Instantiation Instantiation
------------ ------------
Example IOExpanderPort::ADDR initilization: Example IOEPort::ADDR initilization:
const uint8_t IOExpanderPort::ADDR = 0x18; const uint8_t IOEPort::ADDR = 0x18;
Be careful with the ADDR. Be careful with the ADDR.
Table 6 in PCA9655E datasheet lists 8-bit versions of I2C addresses. Table 6 in PCA9655E datasheet lists 8-bit versions of I2C addresses.
The Arduino Wire library uses 7-bit addresses throughout, so drop the low bit. The Arduino Wire library uses 7-bit addresses throughout, so drop the low bit.
@ -29,21 +29,21 @@ outputVal: For pins that are connected to active low rows, set outputVal bit to
Set all other outputVal bits to 0. Set all other outputVal bits to 0.
Example instantiation for port0 with active low rows on all pins: Example instantiation for port0 with active low rows on all pins:
IOExpanderPort port0(0, ~0); IOEPort port0(0, ~0);
Example instantiation for portA with active low rows on pins 0,1,2: Example instantiation for portA with active low rows on pins 0,1,2:
IOExpanderPort portA(0, 1<<0 | 1<<1 | 1<<2 ); IOEPort portA(0, 1<<0 | 1<<1 | 1<<2 );
Example instantiation for portB with active high rows on pins 0,1,2: Example instantiation for portB with active high rows on pins 0,1,2:
IOExpanderPort portB(1, 0); IOEPort portB(1, 0);
*/ */
struct IOExpanderPort struct IOEPort
{ {
static const uint8_t ADDR; //I2C address static const uint8_t ADDR; //I2C address
const uint8_t num; //port number const uint8_t num; //port number
uint8_t outputVal; //bitwise value of output register uint8_t outputVal; //bitwise value of output register
IOExpanderPort(const uint8_t portNumber, uint8_t outputVal) IOEPort(const uint8_t portNumber, uint8_t outputVal)
: num(portNumber), outputVal(outputVal) {} : num(portNumber), outputVal(outputVal) {}
}; };
#endif #endif

View File

@ -4,7 +4,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <Wire.h> #include <Wire.h>
#include <LED.h> #include <LED.h>
#include "IOExpanderPort.h" #include "IOEPort.h"
/* A LED_PCA9655E object is an PCA9655E pin that is connected to an LED indicator light. /* A LED_PCA9655E object is an PCA9655E pin that is connected to an LED indicator light.
Input/Ouput Direction configuration is set to ouput in row_Port_PCA9655E.begin() and col_Port_PCA9655E.begin(). Input/Ouput Direction configuration is set to ouput in row_Port_PCA9655E.begin() and col_Port_PCA9655E.begin().
@ -12,12 +12,12 @@ Input/Ouput Direction configuration is set to ouput in row_Port_PCA9655E.begin()
class LED_PCA9655E: public LED class LED_PCA9655E: public LED
{ {
private: private:
IOExpanderPort& port; IOEPort& port;
const uint8_t outputByteCommand; //General Purpose Input/Ouput register address const uint8_t outputByteCommand; //General Purpose Input/Ouput register address
const uint8_t pin; //bitwise pin to LED const uint8_t pin; //bitwise pin to LED
public: public:
LED_PCA9655E(IOExpanderPort& port, const uint8_t pin) LED_PCA9655E(IOEPort& port, const uint8_t pin)
: port(port), outputByteCommand(port.num + 2), pin(pin) {} : port(port), outputByteCommand(port.num + 2), pin(pin) {}
virtual void on(); virtual void on();

13
src/ReadPort.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "ReadPort.h"
uint8_t ReadPort::getColPins()
{
return readPins;
}
uint8_t ReadPort::getPortState()
{
//todo Keyboard.print(" portState=");
//Keyboard.print(portState);
return portState;
}

View File

@ -1,19 +1,19 @@
#ifndef COLPORT_H #ifndef READPORT_H
#define COLPORT_H #define READPORT_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
/* /*
ColPort is an abstract base class. ReadPort is an abstract base class.
Port classes are the keybrd library's interface to microcontoller ports or I/O expander ports. Port classes are the keybrd library's interface to microcontoller ports or I/O expander ports.
*/ */
class ColPort class ReadPort
{ {
protected: protected:
const uint8_t colPins; //bitwise pin configuration, 1 means read column const uint8_t readPins; //bitwise pin configuration, 1 means read column
uint8_t portState; //bitwise pin values, which is set in read() uint8_t portState; //bitwise pin values, which is set in read()
public: public:
ColPort(const uint8_t colPins): colPins(colPins), portState(0) {} ReadPort(const uint8_t readPins): readPins(readPins), portState(0) {}
//read port and store it's pins values in portState //read port and store it's pins values in portState
virtual void read()=0; virtual void read()=0;

View File

@ -1,24 +1,24 @@
#include "ColPort_PCA9655E.h" #include "ReadPort_PCA9655E.h"
/* /*
configures column port's configuration, input, and pins. configures column port's configuration, input, and pins.
*/ */
ColPort_PCA9655E::ColPort_PCA9655E (IOExpanderPort& port, const uint8_t colPins) ReadPort_PCA9655E::ReadPort_PCA9655E (IOEPort& port, const uint8_t readPins)
: ColPort(colPins), port(port), configurationByteCommand(port.num + 6), inputByteCommand(port.num) : ReadPort(readPins), port(port), configurationByteCommand(port.num + 6), inputByteCommand(port.num)
{} {}
void ColPort_PCA9655E::begin() void ReadPort_PCA9655E::begin()
{ {
Wire.beginTransmission(port.ADDR); Wire.beginTransmission(port.ADDR);
Wire.write(configurationByteCommand); Wire.write(configurationByteCommand);
Wire.write(colPins); //0=configure as output (for LED), 1=configure as input (for read) Wire.write(readPins); //0=configure as output (for LED), 1=configure as input (for read)
Wire.endTransmission(); Wire.endTransmission();
} }
/* /*
Saves all port-pin values to portState. Saves all port-pin values to portState.
*/ */
void ColPort_PCA9655E::read() void ReadPort_PCA9655E::read()
{ {
Wire.beginTransmission(port.ADDR); Wire.beginTransmission(port.ADDR);
Wire.write(inputByteCommand); //input immediately before requestFrom Wire.write(inputByteCommand); //input immediately before requestFrom

View File

@ -1,42 +1,42 @@
#ifndef COLPORT_PCA9655E_H #ifndef READPORT_PCA9655E_H
#define COLPORT_PCA9655E_H #define READPORT_PCA9655E_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <Wire.h> #include <Wire.h>
#include <ColPort.h> #include <ReadPort.h>
#include "IOExpanderPort.h" #include "IOEPort.h"
/* One PCA9655E I/O expander port connected to matrix columns. /* One PCA9655E I/O expander port connected to matrix columns.
PCA9655E does not have internal pull-up resistors (PCA9535E does). PCA9655E does not have internal pull-up resistors (PCA9535E does).
Instantiation Instantiation
------------ ------------
colPins parameter is port's bitwise pin configuration readPins parameter is port's bitwise pin configuration
1=configure as input (for pins connected to column) 1=configure as input (for pins connected to column)
0=configure as output (for LED or not connected to a column) 0=configure as output (for LED or not connected to a column)
Example instantiation for column port 0, with pins 2 and 3 connected to columns: Example instantiation for column port 0, with pins 2 and 3 connected to columns:
IOExpanderPort port0(0, 0); IOEPort port0(0, 0);
ColPort_PCA9655E colPort0(port0, 2<<0 | 1<<3 ); ReadPort_PCA9655E colPort0(port0, 2<<0 | 1<<3 );
Example instantiation for column port 1, with pins 2 and 3 connected to columns: Example instantiation for column port 1, with pins 2 and 3 connected to columns:
IOExpanderPort port1(1, 0); IOEPort port1(1, 0);
ColPort_PCA9655E colPort1(port1, 2<<0 | 1<<3 ); ReadPort_PCA9655E colPort1(port1, 2<<0 | 1<<3 );
colPins are read from pin 0 on up. readPins are read from pin 0 on up.
Diode orientation Diode orientation
---------------- ----------------
Rows, columns, and diode orientation are explained in Matrix.h Rows, columns, and diode orientation are explained in Matrix.h
*/ */
class ColPort_PCA9655E : public ColPort class ReadPort_PCA9655E : public ReadPort
{ {
private: private:
IOExpanderPort& port; IOEPort& port;
const uint8_t configurationByteCommand; const uint8_t configurationByteCommand;
const uint8_t inputByteCommand; const uint8_t inputByteCommand;
public: public:
//The constructor initialization list is in .cpp //The constructor initialization list is in .cpp
ColPort_PCA9655E(IOExpanderPort& port, const uint8_t colPins); ReadPort_PCA9655E(IOEPort& port, const uint8_t readPins);
void begin(); void begin();
//read port and store result in portState //read port and store result in portState

38
src/Row.cpp Normal file
View File

@ -0,0 +1,38 @@
#include "Row.h"
/*
pressRelease() calls key's press() or release() function if it was pressed or released.
Both parameters are bitwise.
*/
void Row::pressRelease(const uint8_t READ_PIN_COUNT, const read_pins_t debouncedChanged)
{
read_pins_t isFallingEdge; //bitwise, 1 means falling edge
read_pins_t isRisingEdge; //bitwise, 1 means rising edge
read_pins_t readMask; //bitwise, active read bit is 1
uint8_t i; //index for ptrsKeys[i] array
//bit=1 if last debounced changed from 1 to 0, else bit=0
isFallingEdge = debouncedChanged & ~debounced;
//bit=1 if last debounced changed from 0 to 1, else bit=0
isRisingEdge = debouncedChanged & debounced;
for (readMask=1, i=0; i < READ_PIN_COUNT; readMask<<=1, i++) //for each key in row
{
//release before press avoids impossible key sequence
if (readMask & isFallingEdge) //if key was released
{
ptrsKeys[i]->release();
}
if (readMask & isRisingEdge) //if key was pressed
{
ptrsKeys[i]->press();
keyWasPressed();
}
}
}
void Row::keyWasPressed()
{
//empty in Row class. To unstick sticky keys, override keyWasPressed() in derived class.
}

View File

@ -1,22 +1,22 @@
#ifndef ROWBASE_H #ifndef ROW_H
#define ROWBASE_H #define ROW_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>
#include <Key.h> #include <Key.h>
/* RowBase is an abstract base class. /* Row is an abstract base class.
*/ */
class RowBase class Row
{ {
private: private:
Key *const *const ptrsKeys; //array of Key pointers Key *const *const ptrsKeys; //array of Key pointers
virtual void keyWasPressed(); virtual void keyWasPressed();
protected: protected:
read_pins_t debounced; //bitwise, 1 means pressed, 0 means released read_pins_t debounced; //bitwise, 1 means pressed, 0 means released
void pressRelease(const uint8_t KEY_COUNT, const read_pins_t debouncedChanged); void pressRelease(const uint8_t READ_PIN_COUNT, const read_pins_t debouncedChanged);
public: public:
RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { } Row(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
virtual void process()=0; virtual void process()=0;
}; };
#endif #endif

View File

@ -1,38 +0,0 @@
#include "RowBase.h"
/*
pressRelease() calls key's press() or release() function if it was pressed or released.
Both parameters are bitwise.
*/
void RowBase::pressRelease(const uint8_t KEY_COUNT, const read_pins_t debouncedChanged)
{
read_pins_t isFallingEdge; //bitwise, 1 means falling edge
read_pins_t isRisingEdge; //bitwise, 1 means rising edge
read_pins_t rowMask; //bitwise, active col bit is 1
uint8_t col; //index for ptrsKeys[col] array
//bit=1 if last debounced changed from 1 to 0, else bit=0
isFallingEdge = debouncedChanged & ~debounced;
//bit=1 if last debounced changed from 0 to 1, else bit=0
isRisingEdge = debouncedChanged & debounced;
for (rowMask=1, col=0; col < KEY_COUNT; rowMask<<=1, col++) //for each key in row
{
//release before press avoids impossible key sequence
if (rowMask & isFallingEdge) //if key was released
{
ptrsKeys[col]->release();
}
if (rowMask & isRisingEdge) //if key was pressed
{
ptrsKeys[col]->press();
keyWasPressed();
}
}
}
void RowBase::keyWasPressed()
{
//empty in RowBase class. To unstick sticky keys, override keyWasPressed() in derived class.
}

View File

@ -1,25 +0,0 @@
#ifndef ROWSCANNER_PINSBITWISE_H
#define ROWSCANNER_PINSBITWISE_H
#include <Arduino.h>
#include <inttypes.h>
#include <RowPort.h>
#include <ColPort.h>
/* RowScanner_PinsBitwise uses bit manipulation to read all pins of one port.
The maximum keys per row is 8, because ports have a maximum of 8 pins each.
*/
class RowScanner_PinsBitwise
{
private:
RowPort& refRowPort; //this row's IC port
const uint8_t strobePin; //bitwise, 1 indicates IC pin connected to this row
ColPort& refColPort;
public:
RowScanner_PinsBitwise(RowPort &refRowPort, const uint8_t strobePin,
ColPort& refColPort)
: refRowPort(refRowPort), strobePin(strobePin),
refColPort(refColPort) {}
static const bool STROBE_ON; //logic level of strobe on, active state, HIGH or LOW
virtual ColPort* const scan();
};
#endif

View File

@ -4,12 +4,12 @@ void Row_ShiftRegisters::process()
{ {
//these variables are all bitwise, one bit per key //these variables are all bitwise, one bit per key
read_pins_t rowState; //1 means pressed, 0 means released read_pins_t rowState; //1 means pressed, 0 means released
uint8_t keyCount; uint8_t readPinCount;
read_pins_t debouncedChanged; //1 means debounced changed read_pins_t debouncedChanged; //1 means debounced changed
rowState = scanner.scan(keyCount); rowState = scanner.scan(readPinCount);
debouncedChanged = debouncer.debounce(rowState, debounced); debouncedChanged = debouncer.debounce(rowState, debounced);
pressRelease(keyCount, debouncedChanged); pressRelease(readPinCount, debouncedChanged);
} }
void Row_ShiftRegisters::begin() void Row_ShiftRegisters::begin()

View File

@ -1,8 +1,8 @@
#ifndef ROW_SHIFTREGISTERS_H #ifndef ROW_SHIFTREGISTERS_H
#define ROW_SHIFTREGISTERS_H #define ROW_SHIFTREGISTERS_H
#include <RowBase.h> #include <Row.h>
#include <RowScanner_SPIShiftRegisters.h> #include <Scanner_ShiftRegs74HC165.h>
#include <Debouncer_4Samples.h> #include <Debouncer_4Samples.h>
//#include <Debouncer_Not.h> //#include <Debouncer_Not.h>
@ -10,10 +10,10 @@
Instantiation Instantiation
------------- -------------
Definition of DELAY_MICROSECONDS is explained in RowBase.cpp. Definition of DELAY_MICROSECONDS is explained in Row.cpp.
Example instantiation of a row: Example instantiation of a row:
const unsigned int RowBase::DELAY_MICROSECONDS = 1000; const unsigned int Row::DELAY_MICROSECONDS = 1000;
todo todo
@ -24,15 +24,15 @@ Number of pins in colPort0 should equal number of keys in ptrsKeys_0[] array.
if a pin is missing, a key will be unresposive if a pin is missing, a key will be unresposive
if a Key pointer is missing, the keyboard will fail in an unprdictable way if a Key pointer is missing, the keyboard will fail in an unprdictable way
*/ */
class Row_ShiftRegisters : public RowBase class Row_ShiftRegisters : public Row
{ {
private: private:
RowScanner_SPIShiftRegisters scanner; Scanner_ShiftRegs74HC165 scanner;
Debouncer_4Samples debouncer; Debouncer_4Samples debouncer;
//Debouncer_Not debouncer; //passed test //Debouncer_Not debouncer; //passed test
public: public:
Row_ShiftRegisters(const uint8_t STROBE_PIN, Key *const ptrsKeys[], uint8_t KEY_COUNT) Row_ShiftRegisters(const uint8_t STROBE_PIN, Key *const ptrsKeys[], uint8_t READ_PIN_COUNT)
: RowBase(ptrsKeys), scanner(STROBE_PIN, KEY_COUNT) { } : Row(ptrsKeys), scanner(STROBE_PIN, READ_PIN_COUNT) { }
void begin(); void begin();
void process(); void process();
}; };

View File

@ -7,20 +7,10 @@ void Row_uC::process()
{ {
//these variables are all bitwise, one bit per key //these variables are all bitwise, one bit per key
read_pins_t rowState; //1 means pressed, 0 means released read_pins_t rowState; //1 means pressed, 0 means released
uint8_t keyCount; uint8_t readPinCount;
read_pins_t debouncedChanged; //1 means debounced changed read_pins_t debouncedChanged; //1 means debounced changed
rowState = scanner.scan(keyCount); rowState = scanner.scan(readPinCount);
/*
Keyboard.print(" keyCount=");
Keyboard.print(keyCount);
Keyboard.print(" rowState=");
Keyboard.print(rowState);
*/
debouncedChanged = debouncer.debounce(rowState, debounced); debouncedChanged = debouncer.debounce(rowState, debounced);
/* pressRelease(readPinCount, debouncedChanged);
Keyboard.print(" debounced=");
Keyboard.print(debounced);
*/
pressRelease(keyCount, debouncedChanged);
} }

View File

@ -1,40 +1,40 @@
#ifndef ROW_H #ifndef ROW_UC_H
#define ROW_H #define ROW_UC_H
#include <RowBase.h> #include <Row.h>
#include <RowScanner_PinsArray.h> #include <Scanner_uC.h>
#include <Debouncer_4Samples.h> #include <Debouncer_4Samples.h>
/* Row_uC is a row connected to a micro controller. /* Row_uC is a row connected to a micro controller.
Instantiation Instantiation
------------- -------------
Definition of DELAY_MICROSECONDS is explained in RowBase.cpp. Definition of DELAY_MICROSECONDS is explained in Row.cpp.
Example instantiation of a row: Example instantiation of a row:
const unsigned int RowBase::DELAY_MICROSECONDS = 1000; const unsigned int Row::DELAY_MICROSECONDS = 1000;
const bool RowScanner_PinsArray::STROBE_ON = LOW; //logic level of strobe on const bool Scanner_uC::STROBE_ON = LOW; //logic level of strobe on
const bool RowScanner_PinsArray::STROBE_OFF = HIGH; //logic level of strobe off const bool Scanner_uC::STROBE_OFF = HIGH; //logic level of strobe off
const uint8_t colPins[] = {0,1,2,3,7,8}; const uint8_t readPins[] = {0,1,2,3,7,8};
const uint8_t COL_PIN_COUNT = sizeof(colPins)/sizeof(*colPins); const uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 }; Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 };
Row_uC row_0(21, colPins, COL_PIN_COUNT, ptrsKeys_0); Row_uC row_0(21, readPins, READ_PIN_COUNT, ptrsKeys_0);
Number of colPins should equal number of keys in ptrsKeys_0[] array. Number of readPins should equal number of keys in ptrsKeys_0[] array.
if a colPin is missing, a key will be unresposive if a readPins is missing, a key will be unresposive
if a Key pointer is missing, the keyboard will fail in an unprdictable way if a Key pointer is missing, the keyboard will fail in an unprdictable way
*/ */
class Row_uC : public RowBase class Row_uC : public Row
{ {
private: private:
RowScanner_PinsArray scanner; Scanner_uC scanner;
Debouncer_4Samples debouncer; Debouncer_4Samples debouncer;
public: public:
Row_uC(const uint8_t strobePin, const uint8_t readPins[], Row_uC(const uint8_t strobePin, const uint8_t READ_PINS[],
Key *const ptrsKeys[], const uint8_t KEY_COUNT) Key *const ptrsKeys[], const uint8_t READ_PIN_COUNT)
: RowBase(ptrsKeys), scanner(strobePin, readPins, KEY_COUNT) { } : Row(ptrsKeys), scanner(strobePin, READ_PINS, READ_PIN_COUNT) { }
void process(); void process();
}; };
#endif #endif

View File

@ -1,32 +1,32 @@
#include "RowScanner_PinsBitwise.h" #include "Scanner_Port.h"
/* /*
Strobes the row and reads the columns. Strobes the row and reads the columns.
*/ */
ColPort* const RowScanner_PinsBitwise::scan() ReadPort* const Scanner_Port::scan()
{ {
//strobe row on //strobe row on
if (STROBE_ON == LOW) if (STROBE_ON == LOW)
{ {
refRowPort.setActivePinLow(strobePin); refStrobePort.setActivePinLow(strobePin);
} }
else //activeLow else //activeLow
{ {
refRowPort.setActivePinHigh(strobePin); refStrobePort.setActivePinHigh(strobePin);
} }
delayMicroseconds(3); //time to stablize voltage delayMicroseconds(3); //time to stablize voltage
//read the port pins //read the port pins
refColPort.read(); refReadPort.read();
//strobe row off //strobe row off
if (STROBE_ON == LOW) if (STROBE_ON == LOW)
{ {
refRowPort.setActivePinHigh(strobePin); refStrobePort.setActivePinHigh(strobePin);
} }
else //activeLow else //activeLow
{ {
refRowPort.setActivePinLow(strobePin); refStrobePort.setActivePinLow(strobePin);
} }
return &refColPort; return &refReadPort;
} }

25
src/Scanner_Port.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef SCANNER_PORT_H
#define SCANNER_PORT_H
#include <Arduino.h>
#include <inttypes.h>
#include <StrobePort.h>
#include <ReadPort.h>
/* Scanner_Port uses bit manipulation to read all pins of one port.
The maximum keys per row is 8, because ports have a maximum of 8 pins each.
*/
class Scanner_Port
{
private:
StrobePort& refStrobePort; //this row's IC port
const uint8_t strobePin; //bitwise, 1 indicates IC pin connected to this row
ReadPort& refReadPort;
public:
Scanner_Port(StrobePort &refStrobePort, const uint8_t strobePin,
ReadPort& refReadPort)
: refStrobePort(refStrobePort), strobePin(strobePin),
refReadPort(refReadPort) {}
static const bool STROBE_ON; //logic level of strobe on, active state, HIGH or LOW
virtual ReadPort* const scan();
};
#endif

View File

@ -1,24 +1,24 @@
#include "RowScanner_SPIShiftRegisters.h" #include "Scanner_ShiftRegs74HC165.h"
//constructor //constructor
RowScanner_SPIShiftRegisters::RowScanner_SPIShiftRegisters(const uint8_t STROBE_PIN, uint8_t KEY_COUNT) Scanner_ShiftRegs74HC165::Scanner_ShiftRegs74HC165(const uint8_t STROBE_PIN, uint8_t READ_PIN_COUNT)
: STROBE_PIN(STROBE_PIN), BYTE_COUNT(ceil (float(KEY_COUNT)/8)), KEY_COUNT(KEY_COUNT) : STROBE_PIN(STROBE_PIN), BYTE_COUNT(ceil (float(READ_PIN_COUNT)/8)), READ_PIN_COUNT(READ_PIN_COUNT)
{ {
//configure controller to communicate with shift register matrix //configure controller to communicate with shift register matrix
pinMode(STROBE_PIN, OUTPUT); pinMode(STROBE_PIN, OUTPUT);
pinMode(SHIFT_LOAD, OUTPUT); pinMode(SHIFT_LOAD, OUTPUT);
} }
void RowScanner_SPIShiftRegisters::begin() void Scanner_ShiftRegs74HC165::begin()
{ {
//initialize shift register's shift/load pin //initialize shift register's shift/load pin
digitalWrite(SHIFT_LOAD, HIGH); digitalWrite(SHIFT_LOAD, HIGH);
} }
/* /*
Sets keyCount and returns rowState. Sets readPinCount and returns rowState.
*/ */
read_pins_t RowScanner_SPIShiftRegisters::scan(uint8_t& keyCount) read_pins_t Scanner_ShiftRegs74HC165::scan(uint8_t& readPinCount)
{ {
read_pins_t rowState = 0; read_pins_t rowState = 0;
@ -34,7 +34,7 @@ read_pins_t RowScanner_SPIShiftRegisters::scan(uint8_t& keyCount)
//strobe row off //strobe row off
digitalWrite(STROBE_PIN, STROBE_OFF); digitalWrite(STROBE_PIN, STROBE_OFF);
keyCount = KEY_COUNT; readPinCount = READ_PIN_COUNT;
//for testing on breadboard, clear unpowered pins //for testing on breadboard, clear unpowered pins
rowState &= 0b11110001000100010001000100010001; //todo rowState &= 0b11110001000100010001000100010001; //todo

View File

@ -1,29 +1,29 @@
#ifndef ROWSCANNER_SPI_SHIFTREGISTERS_H #ifndef ROWSCANNER_SHIFTREGS74HC165_H
#define ROWSCANNER_SPI_SHIFTREGISTERS_H #define ROWSCANNER_SHIFTREGS74HC165_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>
#include <SPI.h> #include <SPI.h>
#include <RowPort.h> #include <StrobePort.h>
#include <ColPort.h> #include <ReadPort.h>
/* RowScanner_SPIShiftRegisters reads shift registers. /* Scanner_ShiftRegs74HC165 reads shift registers.
shift registers 74HC165 is Parallel-In-Serial-Out (PISO) shift registers 74HC165 is Parallel-In-Serial-Out (PISO)
Upto 4 shift registers can be in a daisy chained. Upto 4 shift registers can be in a daisy chained.
In sketch: In sketch:
const uint8_t RowScanner_SPIShiftRegisters::SHIFT_LOAD = 10; const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
call begin() from setup() call begin() from setup()
For active low: For active low:
const bool RowScanner_SPIShiftRegisters::STROBE_ON = LOW; const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW;
const bool RowScanner_SPIShiftRegisters::STROBE_OFF = HIGH; const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH;
//shift register parallel input pins have 10k pull-down resistors powered //shift register parallel input pins have 10k pull-down resistors powered
//controller's MISO pin is connected to shift register's complementary serial output (/QH) pin //controller's MISO pin is connected to shift register's complementary serial output (/QH) pin
For active high: For active high:
const bool RowScanner_SPIShiftRegisters::STROBE_ON = HIGH; const bool Scanner_ShiftRegs74HC165::STROBE_ON = HIGH;
const bool RowScanner_SPIShiftRegisters::STROBE_OFF = LOW; const bool Scanner_ShiftRegs74HC165::STROBE_OFF = LOW;
//shift register parallel input pins have 10k pull-down resistors grounded //shift register parallel input pins have 10k pull-down resistors grounded
//controller's MISO pin is connected to shift register's serial output (QH) pin //controller's MISO pin is connected to shift register's serial output (QH) pin
@ -36,7 +36,7 @@ The two parts of a split keyboard can be connected by one of:
* Ethernet cable (has 8 wires, good for 3 rows) * Ethernet cable (has 8 wires, good for 3 rows)
*/ */
class RowScanner_SPIShiftRegisters 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
@ -44,10 +44,10 @@ class RowScanner_SPIShiftRegisters
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 STROBE_PIN; //Arduino pin number connected to this row const uint8_t STROBE_PIN; //Arduino pin number connected to this row
const uint8_t BYTE_COUNT; //number of bytes to read from shift registers const uint8_t BYTE_COUNT; //number of bytes to read from shift registers
uint8_t KEY_COUNT; uint8_t READ_PIN_COUNT;
public: public:
RowScanner_SPIShiftRegisters(const uint8_t STROBE_PIN, uint8_t KEY_COUNT); Scanner_ShiftRegs74HC165(const uint8_t STROBE_PIN, uint8_t READ_PIN_COUNT);
virtual read_pins_t scan(uint8_t& KEY_COUNT); virtual read_pins_t scan(uint8_t& READ_PIN_COUNT);
void begin(); void begin();
}; };
#endif #endif

View File

@ -1,8 +1,8 @@
#include "RowScanner_PinsArray.h" #include "Scanner_uC.h"
/* constructor /* constructor
*/ */
RowScanner_PinsArray::RowScanner_PinsArray(const uint8_t STROBE_PIN, Scanner_uC::Scanner_uC(const uint8_t STROBE_PIN,
const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT) const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT)
: STROBE_PIN(STROBE_PIN), READ_PINS(READ_PINS), READ_PIN_COUNT(READ_PIN_COUNT) : STROBE_PIN(STROBE_PIN), READ_PINS(READ_PINS), READ_PIN_COUNT(READ_PIN_COUNT)
{ {
@ -20,7 +20,7 @@ RowScanner_PinsArray::RowScanner_PinsArray(const uint8_t STROBE_PIN,
mode = INPUT; //requires external pull-down resistor mode = INPUT; //requires external pull-down resistor
} }
//configure cols //configure read pins
for (uint8_t i=0; i < READ_PIN_COUNT; i++) for (uint8_t i=0; i < READ_PIN_COUNT; i++)
{ {
pinMode(READ_PINS[i], mode); pinMode(READ_PINS[i], mode);
@ -28,7 +28,7 @@ RowScanner_PinsArray::RowScanner_PinsArray(const uint8_t STROBE_PIN,
} }
/* scan() Strobes the row and reads the columns. /* scan() Strobes the row and reads the columns.
Sets KEY_COUNT and returns rowState. Sets READ_PIN_COUNT and returns rowState.
https://www.arduino.cc/en/Tutorial/DigitalPins https://www.arduino.cc/en/Tutorial/DigitalPins
https://www.arduino.cc/en/Reference/PinMode https://www.arduino.cc/en/Reference/PinMode
@ -36,26 +36,28 @@ https://www.arduino.cc/en/Reference/DigitalWrite
https://www.arduino.cc/en/Reference/DigitalRead https://www.arduino.cc/en/Reference/DigitalRead
https://www.arduino.cc/en/Reference/Constants > Digital Pins modes: INPUT, INPUT_PULLUP, and OUTPUT https://www.arduino.cc/en/Reference/Constants > Digital Pins modes: INPUT, INPUT_PULLUP, and OUTPUT
*/ */
read_pins_t RowScanner_PinsArray::scan(uint8_t& keyCount) read_pins_t Scanner_uC::scan(uint8_t& readPinCount)
{ {
read_pins_t rowState = 0; //bitwise, one col per bit, 1 means key is pressed read_pins_t rowState = 0; //bitwise, one col per bit, 1 means key is pressed
read_pins_t rowMask = 1; //bitwise, one col per bit, active col bit is 1 read_pins_t readMask = 1; //bitwise, one col per bit, active col bit is 1
//strobe row on
digitalWrite(STROBE_PIN, STROBE_ON); digitalWrite(STROBE_PIN, STROBE_ON);
delayMicroseconds(3); //time to stablize voltage delayMicroseconds(3); //time to stablize voltage
//read all the column pins //read all the read pins
for (uint8_t i=0; i < READ_PIN_COUNT; i++) for (uint8_t i=0; i < READ_PIN_COUNT; i++)
{ {
if ( digitalRead(READ_PINS[i]) == STROBE_ON ) if ( digitalRead(READ_PINS[i]) == STROBE_ON )
{ {
rowState |= rowMask; rowState |= readMask;
} }
rowMask <<= 1; readMask <<= 1;
} }
//strobe row off
digitalWrite(STROBE_PIN, STROBE_OFF); digitalWrite(STROBE_PIN, STROBE_OFF);
keyCount = READ_PIN_COUNT; readPinCount = READ_PIN_COUNT;
return rowState; return rowState;
} }

View File

@ -1,15 +1,15 @@
#ifndef ROWSCANNER_PINSARRAY_H #ifndef SCANNER_UC_H
#define ROWSCANNER_PINSARRAY_H #define SCANNER_UC_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>
#include <RowPort.h> #include <StrobePort.h>
#include <ColPort.h> #include <ReadPort.h>
/* RowScanner_PinsArray class uses Arduino pin numbers (not port pin numbers). /* Scanner_uC class uses Arduino pin numbers (not port pin numbers).
Constructor is in RowScanner_PinsArray.cpp Constructor is in Scanner_uC.cpp
*/ */
class RowScanner_PinsArray class Scanner_uC
{ {
private: private:
static const bool STROBE_ON; //logic level of strobe on, HIGH or LOW static const bool STROBE_ON; //logic level of strobe on, HIGH or LOW
@ -18,9 +18,9 @@ class RowScanner_PinsArray
const uint8_t* const READ_PINS; //array of read pin numbers const uint8_t* const READ_PINS; //array of read pin numbers
const uint8_t READ_PIN_COUNT; //number of read pins const uint8_t READ_PIN_COUNT; //number of read pins
public: public:
RowScanner_PinsArray(const uint8_t STROBE_PIN, Scanner_uC(const uint8_t STROBE_PIN,
const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT); //todo rename READ_PIN_COUNT to KEY_COUNT ?? const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT); //todo rename READ_PIN_COUNT to READ_PIN_COUNT ??
virtual read_pins_t scan(uint8_t& KEY_COUNT); virtual read_pins_t scan(uint8_t& READ_PIN_COUNT);
}; };
#endif #endif

View File

@ -1,13 +1,13 @@
#ifndef ROWPORT_H #ifndef STROBEPORT_H
#define ROWPORT_H #define STROBEPORT_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
/* /*
RowPort is an abstract base class. StrobePort is an abstract base class.
Port classes are the keybrd library's interface to microcontoller ports or I/O expander ports. Port classes are the keybrd library's interface to microcontoller ports or I/O expander ports.
*/ */
class RowPort class StrobePort
{ {
public: public:
virtual void setActivePinHigh(const uint8_t activePin)=0; virtual void setActivePinHigh(const uint8_t activePin)=0;

View File

@ -1,12 +1,12 @@
#include "RowPort_PCA9655E.h" #include "StrobePort_PCA9655E.h"
/* /*
configures column port's configuration and output. configures column port's configuration and output.
*/ */
RowPort_PCA9655E::RowPort_PCA9655E(IOExpanderPort& port) StrobePort_PCA9655E::StrobePort_PCA9655E(IOEPort& port)
: port(port), configurationByteCommand(port.num + 6), outputByteCommand(port.num + 2) {} : port(port), configurationByteCommand(port.num + 6), outputByteCommand(port.num + 2) {}
void RowPort_PCA9655E::begin() void StrobePort_PCA9655E::begin()
{ {
Wire.beginTransmission(port.ADDR); Wire.beginTransmission(port.ADDR);
Wire.write(configurationByteCommand); Wire.write(configurationByteCommand);
@ -18,7 +18,7 @@ void RowPort_PCA9655E::begin()
sets activePin pin output to low, does not reset the other pins because they might be used by LEDs. sets activePin pin output to low, does not reset the other pins because they might be used by LEDs.
activePin is port mask, where active pin is 1. activePin is port mask, where active pin is 1.
*/ */
void RowPort_PCA9655E::setActivePinLow(const uint8_t activePin) void StrobePort_PCA9655E::setActivePinLow(const uint8_t activePin)
{ {
Wire.beginTransmission(port.ADDR); Wire.beginTransmission(port.ADDR);
Wire.write(outputByteCommand); Wire.write(outputByteCommand);
@ -30,7 +30,7 @@ void RowPort_PCA9655E::setActivePinLow(const uint8_t activePin)
sets activePin pin output to high. sets activePin pin output to high.
activePin is port mask, where active pin is 1. activePin is port mask, where active pin is 1.
*/ */
void RowPort_PCA9655E::setActivePinHigh(const uint8_t activePin) void StrobePort_PCA9655E::setActivePinHigh(const uint8_t activePin)
{ {
Wire.beginTransmission(port.ADDR); Wire.beginTransmission(port.ADDR);
Wire.write(outputByteCommand); Wire.write(outputByteCommand);

View File

@ -1,10 +1,10 @@
#ifndef ROWPORT_PCA9655E_H #ifndef STROBEPORT_PCA9655E_H
#define ROWPORT_PCA9655E_H #define STROBEPORT_PCA9655E_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <Wire.h> #include <Wire.h>
#include <RowPort.h> #include <StrobePort.h>
#include "IOExpanderPort.h" #include "IOEPort.h"
/* One PCA9655E I/O expander port connected to matrix rows. /* One PCA9655E I/O expander port connected to matrix rows.
@ -14,12 +14,12 @@ This should normally be called only once.
Instantiation Instantiation
------------ ------------
Example instantiation for row port 0: Example instantiation for row port 0:
IOExpanderPort port0(0, 0); IOEPort port0(0, 0);
RowPort_PCA9655E rowPort0(port0); StrobePort_PCA9655E rowPort0(port0);
Example instantiation for row port 1: Example instantiation for row port 1:
IOExpanderPort port1(1, 0); IOEPort port1(1, 0);
RowPort_PCA9655E rowPort1(port1); StrobePort_PCA9655E rowPort1(port1);
Diode orientation Diode orientation
---------------- ----------------
@ -32,16 +32,16 @@ PCA9655E data sheet
http://www.onsemi.com/pub_link/Collateral/PCA9655E-D.PDF http://www.onsemi.com/pub_link/Collateral/PCA9655E-D.PDF
*/ */
class RowPort_PCA9655E : public RowPort class StrobePort_PCA9655E : public StrobePort
{ {
private: private:
IOExpanderPort& port; IOEPort& port;
const uint8_t configurationByteCommand; const uint8_t configurationByteCommand;
const uint8_t outputByteCommand; const uint8_t outputByteCommand;
public: public:
//The constructor initialization list is in .cpp //The constructor initialization list is in .cpp
RowPort_PCA9655E(IOExpanderPort& port); StrobePort_PCA9655E(IOEPort& port);
void begin(); void begin();
virtual void setActivePinLow(const uint8_t activePin); //activePin is a port mask virtual void setActivePinLow(const uint8_t activePin); //activePin is a port mask

View File

@ -9,9 +9,9 @@ Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing.
*/ */
/* Uncomment a typedef read_pins_t size that covers all col pins of all RowScanner objects i.e. /* Uncomment a typedef read_pins_t size that covers all col pins of all RowScanner objects i.e.
For RowScanner_PinsArray, RowScanner_PinsArray::READ_PIN_COUNT For Scanner_uC, Scanner_uC::READ_PIN_COUNT
For RowScanner_SPIShiftRegisters, RowScanner_SPIShiftRegisters::KEY_COUNT For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::READ_PIN_COUNT
For RowScanner_PinsBitwise, cover the last 1 bit in RowScanner_PinsBitwise::strobePin For Scanner_Port, cover the last 1 bit in Scanner_Port::strobePin
*/ */
//typedef uint8_t read_pins_t; //typedef uint8_t read_pins_t;
//typedef uint16_t read_pins_t; //typedef uint16_t read_pins_t;