add config_keybrd.h with typedef read_pins_t, read_pins_mask_t
This commit is contained in:
parent
04ab6ebe72
commit
48a3a41db1
@ -7,10 +7,17 @@ keybrd version 1.0.0 will be released when the public API is stable.
|
|||||||
|
|
||||||
## [Unreleased][unreleased]
|
## [Unreleased][unreleased]
|
||||||
|
|
||||||
|
## [0.3.2] - 2016-06-21
|
||||||
|
### Added
|
||||||
|
config_keybrd.h for size configurations.
|
||||||
|
RowScanner_SPI-ShiftRegisters for compact split keyboards up to 32 keys per matrix.
|
||||||
|
LED_PinNumber for controlling indicator lights by pin number.
|
||||||
|
|
||||||
## [0.3.2] - 2016-06-10
|
## [0.3.2] - 2016-06-10
|
||||||
### Changed
|
### Changed
|
||||||
* Changed uC from scanning port arrays to scanning Arduino pins.
|
* Changed uC from scanning port arrays to scanning Arduino pins, thereby adding support for:
|
||||||
Thereby added support for Arduino boards, Teensy 3, and Teensy LC micro controllers.
|
Arduino boards, Teensy 3, and Teensy LC micro controllers
|
||||||
|
up to 31x31 matrix capability
|
||||||
* Changed IOE from scanning port arrays to scanning single ports.
|
* Changed IOE from scanning port arrays to scanning single ports.
|
||||||
* Moved scanner and debouncer into their own classes.
|
* Moved scanner and debouncer into their own classes.
|
||||||
|
|
||||||
|
@ -2,16 +2,14 @@ planned_features is a view of where the keybrd project is headed.
|
|||||||
|
|
||||||
Top priority
|
Top priority
|
||||||
============
|
============
|
||||||
Add support for shift registers, for compact split keyboards up to 32 keys per matrix.
|
MCP23S18 I/O expander with Serial Peripheral Interface (SPI)
|
||||||
|
|
||||||
Med priority
|
Med priority
|
||||||
============
|
============
|
||||||
Add 16x16 matrix capability (currently limited to 8x8 matrices)
|
Add matrix-to-layout mapping array (to decouple matrix from layout)
|
||||||
|
|
||||||
Low priority
|
Low priority
|
||||||
============
|
============
|
||||||
Add matrix-to-layout mapping array (to decouple matrix from layout)
|
|
||||||
|
|
||||||
Update tutorials:
|
Update tutorials:
|
||||||
* Currently tutorial sketches are obsolete and won't compile
|
* 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
|
* Change tutorial sketches from teensy 2.0 and PCA9655E-D IOE to Teensy LC and MCP23018 IOE
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
#ifndef DEBOUNCERINTERFACE_H
|
#ifndef DEBOUNCERINTERFACE_H
|
||||||
#define DEBOUNCERINTERFACE_H
|
#define DEBOUNCERINTERFACE_H
|
||||||
|
|
||||||
|
#include <config_keybrd.h>
|
||||||
|
|
||||||
/* DebouncerInterface is an interface class.
|
/* DebouncerInterface is an interface class.
|
||||||
debounce() takes rawSignal and returns debounced signal. Signals are bitwise.
|
debounce() takes rawSignal and returns debounced signal. Signals are bitwise.
|
||||||
*/
|
*/
|
||||||
class DebouncerInterface
|
class DebouncerInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual uint8_t debounce(const uint8_t rawSignal, uint8_t& debounced)=0;
|
virtual read_pins_t debounce(const read_pins_t rawSignal, read_pins_t& debounced)=0;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,10 +4,10 @@ where each sample contains the switch states for a row of switches, one bit per
|
|||||||
|
|
||||||
Debounce uses Dr. Marty's debounce algorithm from
|
Debounce uses Dr. Marty's debounce algorithm from
|
||||||
http://drmarty.blogspot.com.br/2009/05/best-switch-debounce-routine-ever.html
|
http://drmarty.blogspot.com.br/2009/05/best-switch-debounce-routine-ever.html
|
||||||
I2C and TWI protocols do not include any Packet Error Checking (PEC).
|
SPI, I2C, and TWI protocols do not include any Packet Error Checking (PEC).
|
||||||
The goal of Marty's debounce routine is to reject spurious signals,
|
The goal of Marty's debounce routine is to reject spurious signals,
|
||||||
which is useful when connecting split keyboards with a cable using I2C or TWI.
|
which is useful when connecting split keyboards with a cable using SPI, I2C, or TWI.
|
||||||
Was tested on split keyboard with 3-meter long telephone wire to I/O expander
|
This class was tested on split keyboard with a 3-meter long telephone wire to I/O expander.
|
||||||
|
|
||||||
Dr. Marty's debounce algorithm:
|
Dr. Marty's debounce algorithm:
|
||||||
Periodically read samples and update the state when a number consecutive sample bits are equal.
|
Periodically read samples and update the state when a number consecutive sample bits are equal.
|
||||||
@ -23,11 +23,11 @@ There is a latency equal to SAMPLE_COUNT, between button press and debounced sig
|
|||||||
samples[SAMPLE_COUNT] is a ring buffer. samplesIndex is it's current write index.
|
samples[SAMPLE_COUNT] is a ring buffer. samplesIndex is it's current write index.
|
||||||
SAMPLE_COUNT is the number of consecutive equal samples needed to debounce.
|
SAMPLE_COUNT is the number of consecutive equal samples needed to debounce.
|
||||||
SAMPLE_COUNT is a macro because it defines samples[SAMPLE_COUNT] array size at compile time.
|
SAMPLE_COUNT is a macro because it defines samples[SAMPLE_COUNT] array size at compile time.
|
||||||
SAMPLE_COUNT should be at lease 1.
|
SAMPLE_COUNT is defined in config_keybrd.h and should be at lease 1.
|
||||||
|
|
||||||
SAMPLE_COUNT = 4 is very reliable for a keyboard.
|
SAMPLE_COUNT = 4 is very reliable for a keyboard.
|
||||||
Keyboards with a long I2C wire or in environment with strong electromagnetic interference (EMI)
|
Split keyboards with a long connecting wire or in environment with
|
||||||
may need a larger SAMPLE_COUNT for reliability.
|
strong electromagnetic interference (EMI) may need a larger SAMPLE_COUNT for reliability.
|
||||||
*/
|
*/
|
||||||
#include "Debouncer_4Samples.h"
|
#include "Debouncer_4Samples.h"
|
||||||
|
|
||||||
@ -35,11 +35,11 @@ may need a larger SAMPLE_COUNT for reliability.
|
|||||||
For parameters, 1 means pressed, 0 means released.
|
For parameters, 1 means pressed, 0 means released.
|
||||||
For return, 1 means debounced changed.
|
For return, 1 means debounced changed.
|
||||||
*/
|
*/
|
||||||
uint8_t Debouncer_4Samples::debounce(const uint8_t rawSignal, uint8_t& debounced)
|
read_pins_t Debouncer_4Samples::debounce(const read_pins_t rawSignal, read_pins_t& debounced)
|
||||||
{
|
{
|
||||||
uint8_t previousDebounced; //bitwise, 1 means pressed, 0 means released
|
read_pins_t previousDebounced; //bitwise, 1 means pressed, 0 means released
|
||||||
uint8_t all_1 = ~0; //bitwise
|
read_pins_t all_1 = ~0; //bitwise
|
||||||
uint8_t all_0 = 0; //bitwise
|
read_pins_t all_0 = 0; //bitwise
|
||||||
|
|
||||||
samples[samplesIndex] = rawSignal; //insert rawSignal into samples[] ring buffer
|
samples[samplesIndex] = rawSignal; //insert rawSignal into samples[] ring buffer
|
||||||
|
|
||||||
|
@ -2,21 +2,20 @@
|
|||||||
#define DEBOUNCER_4SAMPLES_H
|
#define DEBOUNCER_4SAMPLES_H
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <config_keybrd.h>
|
||||||
#include <DebouncerInterface.h>
|
#include <DebouncerInterface.h>
|
||||||
|
|
||||||
#define SAMPLE_COUNT 4 //number of consecutive equal bits needed to change a debounced bit
|
|
||||||
|
|
||||||
/* Debouncer_4Samples
|
/* Debouncer_4Samples
|
||||||
Configuration: #define SAMPLE_COUNT in this header file.
|
Configuration: #define SAMPLE_COUNT in config_keybrd.h
|
||||||
*/
|
*/
|
||||||
class Debouncer_4Samples : public DebouncerInterface
|
class Debouncer_4Samples : public DebouncerInterface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint8_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings
|
read_pins_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings
|
||||||
uint8_t samplesIndex; //samples[] current write index
|
uint8_t samplesIndex; //samples[] current write index
|
||||||
public:
|
public:
|
||||||
Debouncer_4Samples(): samplesIndex(0) {}
|
Debouncer_4Samples(): samplesIndex(0) {}
|
||||||
virtual uint8_t debounce(const uint8_t rawSignal, uint8_t& debounced);
|
virtual read_pins_t debounce(const read_pins_t rawSignal, read_pins_t& debounced);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ process() scans the row and calls any newly pressed or released keys.
|
|||||||
void RowBase::process()
|
void RowBase::process()
|
||||||
{
|
{
|
||||||
//these variables are all bitwise, one bit per key
|
//these variables are all bitwise, one bit per key
|
||||||
uint8_t rowState; //1 means pressed, 0 means released
|
read_pins_t rowState; //1 means pressed, 0 means released
|
||||||
uint16_t rowEnd; //1 bit marks positioned after last key of row
|
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row
|
||||||
uint8_t debouncedChanged; //1 means debounced changed
|
read_pins_t debouncedChanged; //1 means debounced changed
|
||||||
|
|
||||||
wait();
|
wait();
|
||||||
rowState = scan(rowEnd);
|
rowState = scan(rowEnd);
|
||||||
@ -56,11 +56,11 @@ pressRelease() calls key's press() or release() function if it was pressed or re
|
|||||||
Both parameters are bitwise.
|
Both parameters are bitwise.
|
||||||
rowEnd bit marks positioned immediatly after last key of row.
|
rowEnd bit marks positioned immediatly after last key of row.
|
||||||
*/
|
*/
|
||||||
void RowBase::pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged)
|
void RowBase::pressRelease(const read_pins_mask_t rowEnd, const read_pins_t debouncedChanged)
|
||||||
{
|
{
|
||||||
uint8_t isFallingEdge; //1 means falling edge
|
read_pins_t isFallingEdge; //bitwise, 1 means falling edge
|
||||||
uint8_t isRisingEdge; //1 means rising edge
|
read_pins_t isRisingEdge; //bitwise, 1 means rising edge
|
||||||
uint16_t rowMask; //bitwise, active col bit is 1 (same type as rowEnd)
|
read_pins_t rowMask; //bitwise, active col bit is 1 (same type as rowEnd)
|
||||||
uint8_t col; //index for ptrsKeys[col] array
|
uint8_t col; //index for ptrsKeys[col] array
|
||||||
|
|
||||||
//bit=1 if last debounced changed from 1 to 0, else bit=0
|
//bit=1 if last debounced changed from 1 to 0, else bit=0
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define ROWBASE_H
|
#define ROWBASE_H
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <config_keybrd.h>
|
||||||
#include <Key.h>
|
#include <Key.h>
|
||||||
|
|
||||||
/* RowBase is an abstract base class.
|
/* RowBase is an abstract base class.
|
||||||
@ -14,14 +15,14 @@ class RowBase
|
|||||||
|
|
||||||
virtual void keyWasPressed();
|
virtual void keyWasPressed();
|
||||||
protected:
|
protected:
|
||||||
uint8_t debounced; //bitwise, 1 means pressed, 0 means released
|
read_pins_t debounced; //bitwise, 1 means pressed, 0 means released
|
||||||
|
|
||||||
void wait();
|
void wait();
|
||||||
void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged);
|
void pressRelease(const read_pins_mask_t rowEnd, const read_pins_t debouncedChanged);
|
||||||
public:
|
public:
|
||||||
RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
||||||
virtual void process();
|
virtual void process();
|
||||||
virtual uint8_t scan(uint16_t& rowEnd)=0;
|
virtual read_pins_t scan(read_pins_mask_t& rowEnd)=0;
|
||||||
virtual uint8_t debounce(const uint8_t rowState, uint8_t& debounced)=0;
|
virtual read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced)=0;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <config_keybrd.h>
|
||||||
|
|
||||||
class RowScannerInterface
|
class RowScannerInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual uint8_t scan(uint16_t& rowEnd)=0;
|
virtual read_pins_t scan(read_pins_mask_t& rowEnd)=0;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -39,9 +39,9 @@ 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
|
||||||
*/
|
*/
|
||||||
uint8_t RowScanner_PinsArray::scan(uint16_t& rowEnd)
|
read_pins_t RowScanner_PinsArray::scan(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
uint8_t rowState = 0;
|
read_pins_t rowState = 0; //bitwise
|
||||||
rowEnd = 1;
|
rowEnd = 1;
|
||||||
|
|
||||||
//strobe row on
|
//strobe row on
|
||||||
|
@ -2,11 +2,14 @@
|
|||||||
#define ROWSCANNER_PINSARRAY_H
|
#define ROWSCANNER_PINSARRAY_H
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <config_keybrd.h>
|
||||||
#include <RowScannerInterface.h>
|
#include <RowScannerInterface.h>
|
||||||
#include <RowPort.h>
|
#include <RowPort.h>
|
||||||
#include <ColPort.h>
|
#include <ColPort.h>
|
||||||
|
|
||||||
/* RowScanner_PinsArray class uses Arduino pin numbers (not port pin numbers).
|
/* RowScanner_PinsArray class uses Arduino pin numbers (not port pin numbers).
|
||||||
|
The maximum keys per row is 31, because Arduino's largest type is 32 bits and rowEnd consumes the last bit.
|
||||||
|
Constructor is in RowScanner_PinsArray.cpp
|
||||||
*/
|
*/
|
||||||
class RowScanner_PinsArray : public RowScannerInterface
|
class RowScanner_PinsArray : public RowScannerInterface
|
||||||
{
|
{
|
||||||
@ -18,8 +21,8 @@ class RowScanner_PinsArray : public RowScannerInterface
|
|||||||
public:
|
public:
|
||||||
RowScanner_PinsArray(const uint8_t strobePin,
|
RowScanner_PinsArray(const uint8_t strobePin,
|
||||||
const uint8_t readPins[], const uint8_t READ_PIN_COUNT);
|
const uint8_t readPins[], const uint8_t READ_PIN_COUNT);
|
||||||
virtual uint8_t scan(uint16_t& rowEnd);
|
virtual read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||||
uint8_t getRowState(uint16_t& rowEnd);
|
//read_pins_t getRowState(read_pins_mask_t& rowEnd);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Strobes the row and reads the columns.
|
Strobes the row and reads the columns.
|
||||||
Sets rowEnd and returns rowState.
|
Sets rowEnd and returns rowState.
|
||||||
*/
|
*/
|
||||||
uint8_t RowScanner_PinsBitwise::scan(uint16_t& rowEnd)
|
read_pins_t RowScanner_PinsBitwise::scan(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
//strobe row on
|
//strobe row on
|
||||||
if (activeHigh)
|
if (activeHigh)
|
||||||
@ -39,7 +39,7 @@ rowEnd is a bitwise row mask, one col per bit, where active col bit is 1.
|
|||||||
At end of function, 1 bit marks place immediatly after last key of row.
|
At end of function, 1 bit marks place immediatly after last key of row.
|
||||||
rowEnd is a larger type than portMask so that it can not overflow.
|
rowEnd is a larger type than portMask so that it can not overflow.
|
||||||
*/
|
*/
|
||||||
uint8_t RowScanner_PinsBitwise::getRowState(uint16_t& rowEnd)
|
uint8_t RowScanner_PinsBitwise::getRowState(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed
|
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed
|
||||||
uint8_t portMask; //bitwise, 1 bit is a colPortState position
|
uint8_t portMask; //bitwise, 1 bit is a colPortState position
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <ColPort.h>
|
#include <ColPort.h>
|
||||||
|
|
||||||
/* RowScanner_PinsBitwise uses bit manipulation to read all pins of one port.
|
/* 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 : public RowScannerInterface
|
class RowScanner_PinsBitwise : public RowScannerInterface
|
||||||
{
|
{
|
||||||
@ -20,7 +21,7 @@ class RowScanner_PinsBitwise : public RowScannerInterface
|
|||||||
: refRowPort(refRowPort), strobePin(strobePin),
|
: refRowPort(refRowPort), strobePin(strobePin),
|
||||||
refColPort(refColPort) {}
|
refColPort(refColPort) {}
|
||||||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh
|
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh
|
||||||
virtual uint8_t scan(uint16_t& rowEnd);
|
virtual read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||||
uint8_t getRowState(uint16_t& rowEnd);
|
uint8_t getRowState(read_pins_mask_t& rowEnd);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,10 +9,10 @@ void RowScanner_SPIShiftRegisters::begin()
|
|||||||
/*
|
/*
|
||||||
Sets rowEnd and returns rowState.
|
Sets rowEnd and returns rowState.
|
||||||
*/
|
*/
|
||||||
uint8_t RowScanner_SPIShiftRegisters::scan(uint16_t& rowEnd)
|
read_pins_t RowScanner_SPIShiftRegisters::scan(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
//todo rowEnd, rowState, return int size depend on BYTE_COUNT, like in send()
|
//todo rowEnd, rowState, return int size depend on BYTE_COUNT, like in send()
|
||||||
uint8_t rowState;
|
read_pins_t rowState = 0;
|
||||||
|
|
||||||
digitalWrite(SS, LOW);
|
digitalWrite(SS, LOW);
|
||||||
digitalWrite(SS, HIGH);
|
digitalWrite(SS, HIGH);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <ColPort.h>
|
#include <ColPort.h>
|
||||||
|
|
||||||
/* RowScanner_SPIShiftRegisters reads all shift registers in a daisy chain.
|
/* RowScanner_SPIShiftRegisters reads all shift registers in a daisy chain.
|
||||||
|
The maximum keys per row is 31, because Arduino's largest type is 32 bits and rowEnd consumes the last bit.
|
||||||
//todo delete: Assumes only one row of shift registers is connected (no Slave Select).
|
//todo delete: Assumes only one row of shift registers is connected (no Slave Select).
|
||||||
*/
|
*/
|
||||||
class RowScanner_SPIShiftRegisters : public RowScannerInterface
|
class RowScanner_SPIShiftRegisters : public RowScannerInterface
|
||||||
@ -17,9 +18,9 @@ class RowScanner_SPIShiftRegisters : public RowScannerInterface
|
|||||||
const uint8_t BYTE_COUNT; //number of shift registers
|
const uint8_t BYTE_COUNT; //number of shift registers
|
||||||
const uint8_t KEY_COUNT; //number of keys in row
|
const uint8_t KEY_COUNT; //number of keys in row
|
||||||
public:
|
public:
|
||||||
RowScanner_SPIShiftRegisters(const uint8_t SS, uint8_t BYTE_COUNT, uint16_t KEY_COUNT)
|
RowScanner_SPIShiftRegisters(const uint8_t SS, uint8_t BYTE_COUNT, uint8_t KEY_COUNT)
|
||||||
: SS(SS), BYTE_COUNT(BYTE_COUNT), KEY_COUNT(KEY_COUNT) {}
|
: SS(SS), BYTE_COUNT(BYTE_COUNT), KEY_COUNT(KEY_COUNT) {}
|
||||||
virtual uint8_t scan(uint16_t& rowEnd);
|
virtual read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||||
void begin();
|
void begin();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "Row_IOE.h"
|
#include "Row_IOE.h"
|
||||||
|
|
||||||
uint8_t Row_IOE::scan(uint16_t& rowEnd)
|
read_pins_t Row_IOE::scan(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
return scanner.scan(rowEnd);
|
return scanner.scan(rowEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Row_IOE::debounce(const uint8_t rowState, uint8_t& debounced)
|
read_pins_t Row_IOE::debounce(const read_pins_t rowState, read_pins_t& debounced)
|
||||||
{
|
{
|
||||||
return debouncer.debounce(rowState, debounced);
|
return debouncer.debounce(rowState, debounced);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class Row_IOE : public RowBase
|
|||||||
Row_IOE( RowPort& refRowPort, const uint8_t strobePin,
|
Row_IOE( RowPort& refRowPort, const uint8_t strobePin,
|
||||||
ColPort& refColPort, Key *const ptrsKeys[])
|
ColPort& refColPort, Key *const ptrsKeys[])
|
||||||
: RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { }
|
: RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { }
|
||||||
uint8_t scan(uint16_t& rowEnd);
|
read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||||
uint8_t debounce(const uint8_t rowState, uint8_t& debounced);
|
read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,12 +5,12 @@ void Row_ShiftRegisters::begin()
|
|||||||
scanner.begin();
|
scanner.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Row_ShiftRegisters::scan(uint16_t& rowEnd)
|
read_pins_t Row_ShiftRegisters::scan(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
return scanner.scan(rowEnd);
|
return scanner.scan(rowEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Row_ShiftRegisters::debounce(const uint8_t rowState, uint8_t& debounced)
|
read_pins_t Row_ShiftRegisters::debounce(const read_pins_t rowState, read_pins_t& debounced)
|
||||||
{
|
{
|
||||||
return debouncer.debounce(rowState, debounced);
|
return debouncer.debounce(rowState, debounced);
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,10 @@ class Row_ShiftRegisters : public RowBase
|
|||||||
RowScanner_SPIShiftRegisters scanner;
|
RowScanner_SPIShiftRegisters scanner;
|
||||||
Debouncer_4Samples debouncer;
|
Debouncer_4Samples debouncer;
|
||||||
public:
|
public:
|
||||||
Row_ShiftRegisters(const uint8_t SS, uint8_t BYTE_COUNT, Key *const ptrsKeys[], uint16_t KEY_COUNT)
|
Row_ShiftRegisters(const uint8_t SS, uint8_t BYTE_COUNT, Key *const ptrsKeys[], uint8_t KEY_COUNT)
|
||||||
: RowBase(ptrsKeys), scanner(SS, BYTE_COUNT, KEY_COUNT) { }
|
: RowBase(ptrsKeys), scanner(SS, BYTE_COUNT, KEY_COUNT) { }
|
||||||
void begin();
|
void begin();
|
||||||
uint8_t scan(uint16_t& rowEnd);
|
read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||||
uint8_t debounce(const uint8_t rowState, uint8_t& debounced);
|
read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "Row_uC.h"
|
#include "Row_uC.h"
|
||||||
|
|
||||||
uint8_t Row_uC::scan(uint16_t& rowEnd)
|
read_pins_t Row_uC::scan(read_pins_mask_t& rowEnd)
|
||||||
{
|
{
|
||||||
return scanner.scan(rowEnd);
|
return scanner.scan(rowEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Row_uC::debounce(const uint8_t rowState, uint8_t& debounced)
|
read_pins_t Row_uC::debounce(const read_pins_t rowState, read_pins_t& debounced)
|
||||||
{
|
{
|
||||||
return debouncer.debounce(rowState, debounced);
|
return debouncer.debounce(rowState, debounced);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class Row_uC : public RowBase
|
|||||||
Row_uC(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT,
|
Row_uC(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT,
|
||||||
Key *const ptrsKeys[])
|
Key *const ptrsKeys[])
|
||||||
: RowBase(ptrsKeys), scanner(strobePin, readPins, READ_PIN_COUNT) { }
|
: RowBase(ptrsKeys), scanner(strobePin, readPins, READ_PIN_COUNT) { }
|
||||||
uint8_t scan(uint16_t& rowEnd);
|
read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||||
uint8_t debounce(const uint8_t rowState, uint8_t& debounced);
|
read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
35
src/config_keybrd.h
Normal file
35
src/config_keybrd.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef CONFIG_KEYBRD_H
|
||||||
|
#define CONFIG_KEYBRD_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/* size of read_pins_t and read_pins_mask_t depends on the maximum number of pins scanned by RowScanner.
|
||||||
|
By default, read_pins_t and read_pins_mask_t are set to the largest type.
|
||||||
|
If your 8-bit AVR is running low on memory, using a smaller type saves SRAM.
|
||||||
|
Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Uncomment a typedef read_pins_t that covers all col pins of the RowScanner object with the most col pins i.e.
|
||||||
|
For RowScanner_PinsArray, RowScanner_PinsArray::READ_PIN_COUNT
|
||||||
|
For RowScanner_SPIShiftRegisters, RowScanner_SPIShiftRegisters::KEY_COUNT
|
||||||
|
For RowScanner_PinsBitwise, cover the last 1 bit in RowScanner_PinsBitwise::strobePin
|
||||||
|
*/
|
||||||
|
typedef uint8_t read_pins_t;
|
||||||
|
//typedef uint16_t read_pins_t;
|
||||||
|
//typedef uint32_t read_pins_t;
|
||||||
|
|
||||||
|
/* read_pins_mask_t is only used for rowEnd, which extends one bit beyond the last col pin.
|
||||||
|
uncomment typedef that covers one bit beyond the last col pin.
|
||||||
|
This could be the same typedef as read_pins_t, or the next larger typedef.
|
||||||
|
*/
|
||||||
|
typedef uint8_t read_pins_mask_t;
|
||||||
|
//typedef uint16_t read_pins_mask_t;
|
||||||
|
//typedef uint32_t read_pins_mask_t;
|
||||||
|
|
||||||
|
/* SAMPLE_COUNT = 4 is very reliable for a keyboard.
|
||||||
|
Split keyboards with a long connecting wire or in environment with
|
||||||
|
strong electromagnetic interference (EMI) may need a larger SAMPLE_COUNT for reliability.
|
||||||
|
SAMPLE_COUNT is used in Debouncer_Samples.h
|
||||||
|
*/
|
||||||
|
#define SAMPLE_COUNT 4 //number of consecutive equal bits needed to change a debounced bit
|
||||||
|
|
||||||
|
#endif
|
@ -7,8 +7,8 @@ All the tutorial example sketches run on breadboard keyboards that have 2 to 8 k
|
|||||||
Breadboard keyboards have row-column matrices and diodes just like the big keyboards.
|
Breadboard keyboards have row-column matrices and diodes just like the big keyboards.
|
||||||
|
|
||||||
A breadboard is the easiest way to learn keyboard electronics.
|
A breadboard is the easiest way to learn keyboard electronics.
|
||||||
|
A novice won't get everything right the first time.
|
||||||
It's easy to get some detail wrong with electronics.
|
It's easy to get some detail wrong with electronics.
|
||||||
You won't get everything right the first time.
|
|
||||||
There is a learning curve.
|
There is a learning curve.
|
||||||
Compared to PCBs, breadboard keyboards are easier to learn on because:
|
Compared to PCBs, breadboard keyboards are easier to learn on because:
|
||||||
* Mistakes are easily corrected; no soldering and desoldering
|
* Mistakes are easily corrected; no soldering and desoldering
|
||||||
|
Reference in New Issue
Block a user