@@ -66,12 +66,11 @@ Class inheritance diagrams | |||
Keybrd library class inheritance diagram | |||
``` | |||
________ Row ___________ | |||
/ | \ | |||
Row_uC Row_ShiftRegisters Row_IOE (todo to be added) | |||
Row | |||
Scanner_uC Scanner_Port Scanner_ShiftRegs74HC165 | |||
___ ScannerInterface ___ | |||
/ | \ | |||
Scanner_uC Scanner_IOE Scanner_ShiftRegsPISO | |||
PortIOE |
@@ -65,18 +65,6 @@ For Linux: | |||
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 | |||
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 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". |
@@ -33,14 +33,14 @@ Scanner_uC scanner_L(HIGH, readPins_L, readPinCount_L); | |||
// =============== RIGHT SCANNER =============== | |||
const uint8_t PortIOE::DEVICE_ADDR = 0x18; | |||
PortIOE port_R1(1, 0); | |||
PortWrite_PCA9655E portWrite_R1(port_R1); | |||
PortIOE port_1(1); | |||
PortWrite_PCA9655E portWrite_1(port_1); | |||
PortIOE port_R0(0, 0); | |||
//PortWrite_PCA9655E portWrite_R0(port_R0); //for LEDs | |||
PortRead_PCA9655E portRead_R0(port_R0, 1<<0 | 1<<1 ); | |||
PortIOE port_0(0); | |||
//PortWrite_PCA9655E portWrite_R0(port_0); //for LEDs | |||
PortRead_PCA9655E portRead_0(port_0, 1<<0 | 1<<1 ); | |||
Scanner_IOE scanner_R(HIGH, portWrite_R1, portRead_R0); | |||
Scanner_IOE scanner_R(HIGH, portWrite_1, portRead_0); | |||
// =================== CODES =================== | |||
Code_Sc s_a(KEY_A); |
@@ -7,7 +7,7 @@ uint8_t PortMCP23S17::transfer(const uint8_t command, const uint8_t registerAddr | |||
uint8_t portState; //bit wise | |||
digitalWrite(SS, LOW); //enable Slave Select | |||
SPI.transfer(command); //write command todo also read command? | |||
SPI.transfer(command); //write or read command | |||
SPI.transfer(registerAddr); //register address to write data to | |||
portState = SPI.transfer(data); //write data, read portState | |||
digitalWrite(SS, HIGH); //disable Slave Select |
@@ -1,7 +1,7 @@ | |||
#include "PortRead_MCP23S17.h" | |||
/* begin() is called from Scanner_IOE::begin(). | |||
Configures port to to read (input with pullup enabled). | |||
Configures read pins to input with pullup enabled. | |||
*/ | |||
void PortRead_MCP23S17::begin(const uint8_t strobeOn) | |||
{ |
@@ -1,7 +1,7 @@ | |||
#include "PortRead_PCA9655E.h" | |||
/* begin() is called from Scanner_IOE::begin(). | |||
Configures port to to read (input). | |||
Configures read pins to input. | |||
*/ | |||
void PortRead_PCA9655E::begin(const uint8_t strobeOn) | |||
{ |
@@ -1,8 +1,10 @@ | |||
#include "PortWrite_MCP23S17.h" | |||
/* begin() is called from Scanner_IOE::begin(). | |||
Initiates SPI bus and configures write pins to output. | |||
Initiates SPI bus and configures port pins to output. | |||
MCP23S17 SPI interface is 10 MHz max. | |||
The electrical limitation to bus speed is bus capacitance and the length of the wires involved. | |||
Longer wires require lower clock speeds. | |||
*/ | |||
void PortWrite_MCP23S17::begin() | |||
{ |
@@ -1,11 +1,16 @@ | |||
#include "PortWrite_PCA9655E.h" | |||
/* begin() is called from Scanner_IOE::begin(). | |||
Configures write pins to output. | |||
Initiates I2C bus and configures port pins to output. | |||
PCA9655E supports I2C SCL Clock Frequencies: 100 kHz, 400 kHz, 1000 kHz (Datasheet page 1 & 6) | |||
The electrical limitation to bus speed is bus capacitance and the length of the wires involved. | |||
Longer wires require lower clock speeds. | |||
http://playground.arduino.cc/Main/WireLibraryDetailedReference > Wire.setclock() | |||
*/ | |||
void PortWrite_PCA9655E::begin() | |||
{ | |||
Wire.begin(); | |||
Wire.begin(); //initiate I2C bus to 100 kHz | |||
//Wire.setClock(400000L); //set I2C bus to 400 kHz (have not tested 400 kHz) | |||
Wire.beginTransmission(port.DEVICE_ADDR); | |||
Wire.write(port.num + 6); //configuration byte command |
@@ -1,12 +1,12 @@ | |||
#include "Row.h" | |||
/* constructor | |||
init() is called once for each row. | |||
init() is called once for each row, to set scanner's uC strobePin to output. | |||
*/ | |||
Row::Row(ScannerInterface& refScanner, const uint8_t strobePin, | |||
Key* const ptrsKeys[], const uint8_t readPinCount) | |||
Key* const ptrsKeys[], const uint8_t keyCount) | |||
: refScanner(refScanner), strobePin(strobePin), | |||
ptrsKeys(ptrsKeys), readPinCount(readPinCount), debounced(0) | |||
ptrsKeys(ptrsKeys), keyCount(keyCount), debounced(0) | |||
{ | |||
refScanner.init(strobePin); | |||
} | |||
@@ -21,14 +21,14 @@ void Row::process() | |||
readState = refScanner.scan(strobePin); | |||
debouncedChanged = debouncer.debounce(readState, debounced); | |||
send(readPinCount, debouncedChanged); | |||
send(keyCount, debouncedChanged); | |||
} | |||
/* | |||
send() calls key's press() or release() function if key was pressed or released. | |||
Both parameters are bitwise. | |||
*/ | |||
void Row::send(const uint8_t readPinCount, const read_pins_t debouncedChanged) | |||
void Row::send(const uint8_t keyCount, const read_pins_t debouncedChanged) | |||
{ | |||
read_pins_t isFallingEdge; //bitwise, 1 means falling edge | |||
read_pins_t isRisingEdge; //bitwise, 1 means rising edge | |||
@@ -41,7 +41,7 @@ void Row::send(const uint8_t readPinCount, const read_pins_t debouncedChanged) | |||
//bit=1 if last debounced changed from 0 to 1, else bit=0 | |||
isRisingEdge = debouncedChanged & debounced; | |||
for (readMask=1, i=0; i < readPinCount; readMask<<=1, i++) //for each key in row | |||
for (readMask=1, i=0; i < keyCount; readMask<<=1, i++) //for each key in row | |||
{ | |||
//release before press avoids impossible key sequence | |||
if (readMask & isFallingEdge) //if key was released |
@@ -18,18 +18,18 @@ class Row | |||
private: | |||
virtual void keyWasPressed(); | |||
protected: | |||
void send(const uint8_t readPinCount, const read_pins_t debouncedChanged); | |||
void send(const uint8_t keyCount, const read_pins_t debouncedChanged); | |||
ScannerInterface& refScanner; | |||
const uint8_t strobePin; //pin connected to this row (details above) | |||
private: | |||
Key *const *const ptrsKeys; //array of Key pointers | |||
protected: | |||
const uint8_t readPinCount; //number of read pins | |||
const uint8_t keyCount; //number of read pins | |||
Debouncer_Samples debouncer; | |||
read_pins_t debounced; //bitwise state of keys after debouncing, 1=pressed, 0=released | |||
read_pins_t debounced; //bitwise state of keys after debouncing, 1=pressed, 0=released | |||
public: | |||
Row(ScannerInterface& refScanner, const uint8_t strobePin, | |||
Key* const ptrsKeys[], const uint8_t readPinCount); | |||
Key* const ptrsKeys[], const uint8_t keyCount); | |||
virtual void process(); | |||
}; | |||
#endif |
@@ -8,10 +8,11 @@ void Scanner_IOE::init(const uint8_t strobePin) | |||
} | |||
/* begin() should be called once from sketch setup(). | |||
Initiates communication protocal and configs ports. | |||
*/ | |||
void Scanner_IOE::begin() | |||
{ | |||
refPortWrite.begin(); //configure SPI bus | |||
refPortWrite.begin(); | |||
refPortRead.begin(strobeOn); | |||
} | |||
@@ -31,7 +31,7 @@ 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 pull-up resistors powered. | |||
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 | |||
@@ -35,7 +35,7 @@ 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 pull-up resistors powered. | |||
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 | |||
@@ -8,10 +8,7 @@ If your 8-bit AVR (Teensy 2) is running low on memory, using a smaller type save | |||
Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing. | |||
*/ | |||
/* Use a read_pins_t size that covers all read pins of all RowScanner objects i.e. | |||
For Scanner_uC, Scanner_uC::readPinCount | |||
For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::readPinCount | |||
For Scanner_IOE, cover the last 1 bit in Scanner_IOE::strobePin | |||
/* Use a read_pins_t size that covers the last 1 bit in bitwise Scanner_IOE::strobePin. | |||
*/ | |||
//typedef uint8_t read_pins_t; | |||
//typedef uint16_t read_pins_t; |