@@ -1,7 +1,3 @@ | |||
/* debounce() sets debounced and returns debouncedChanged. All variables are bitwise. | |||
For parameter, 1 means pressed, 0 means released. | |||
For return, 1 means debounced changed. | |||
*/ | |||
#include "Row.h" | |||
/* |
@@ -2,15 +2,12 @@ | |||
#define ROW_H | |||
#include <RowBase.h> | |||
//#include <RowScanner_BitManipulation.h> | |||
#include <RowScanner_Arduino.h> | |||
#include <RowScanner_PinsArray.h> | |||
#include <Debouncer_4Samples.h> | |||
/* | |||
Configuration | |||
------------- | |||
define and initilize DELAY_MICROSECONDS in sketch. | |||
const unsigned int RowBase::DELAY_MICROSECONDS = 0; | |||
Instantiation | |||
------------- | |||
@@ -19,12 +16,12 @@ Instantiation | |||
class Row : public RowBase | |||
{ | |||
private: | |||
//RowScanner_BitManipulation scanner; | |||
RowScanner_Arduino scanner; | |||
RowScanner_PinsArray scanner; | |||
Debouncer_4Samples debouncer; | |||
public: | |||
//Row constructor was like Row_DH constructor | |||
Row(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT, Key *const ptrsKeys[]) | |||
Row(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT, | |||
Key *const ptrsKeys[]) | |||
: RowBase(ptrsKeys), scanner(strobePin, readPins, READ_PIN_COUNT) { } | |||
virtual void process(); | |||
}; |
@@ -23,14 +23,14 @@ Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures | |||
Avoid sampling the switch input at a rate synchronous to events in the environment | |||
that might create periodic EMI. For instance, 50 and 60 Hz. | |||
The largest allowabl DELAY_MICROSECONDS is 65535 (.065535 second). | |||
The largest allowable DELAY_MICROSECONDS is 65535 (.065535 seconds). | |||
Polling I2C may slow the scan rate enough so that no additional delay is needed: | |||
const unsigned int Row::DELAY_MICROSECONDS = 0; | |||
Slow-scan trick for debug messages that print too fast and not aligned, add this to sketch loop(): | |||
delay(500); | |||
Keyboard.println(""); | |||
Keyboard.println(F("")); | |||
That way debug messages are printed at a managable rate, and each scan starts a new line. | |||
*/ | |||
void RowBase::wait() |
@@ -5,6 +5,9 @@ | |||
#include <Key.h> | |||
/* RowBase is an abstract base class. | |||
Define and initilize DELAY_MICROSECONDS in sketch. | |||
const unsigned int RowBase::DELAY_MICROSECONDS = 0; | |||
*/ | |||
class RowBase | |||
{ |
@@ -0,0 +1,17 @@ | |||
#include "RowIOE.h" | |||
/* | |||
process() scans the row and calls any newly pressed or released keys. | |||
*/ | |||
void RowIOE::process() | |||
{ | |||
//these variables are all bitwise, one bit per key | |||
uint8_t rowState; //1 means pressed, 0 means released | |||
uint16_t rowEnd; //1 bit marks positioned after last key of row | |||
uint8_t debouncedChanged; //1 means debounced changed | |||
wait(); | |||
rowState = scanner.scan(rowEnd); | |||
debouncedChanged = debouncer.debounce(rowState, debounced); | |||
pressRelease(rowEnd, debouncedChanged); | |||
} |
@@ -0,0 +1,28 @@ | |||
#ifndef ROWIOE_H | |||
#define ROWIOE_H | |||
#include <RowBase.h> | |||
#include <RowScanner_PinsBitwise.h> | |||
#include <Debouncer_4Samples.h> | |||
/* | |||
Simlar to Row but using RowScanner_PinsBitwise. | |||
Configuration | |||
------------- | |||
Instantiation | |||
------------- | |||
*/ | |||
class RowIOE : public RowBase | |||
{ | |||
private: | |||
RowScanner_PinsBitwise scanner; | |||
Debouncer_4Samples debouncer; | |||
public: | |||
RowIOE( RowPort& refRowPort, const uint8_t strobePin, | |||
ColPort& refColPort, Key *const ptrsKeys[]) | |||
: RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { } | |||
virtual void process(); | |||
}; | |||
#endif |
@@ -1,78 +0,0 @@ | |||
#include "RowScanner_BitManipulation.h" | |||
/* | |||
Strobes the row and reads the columns. | |||
Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. | |||
*/ | |||
uint8_t RowScanner_BitManipulation::scan(uint16_t& rowEnd) | |||
{ | |||
//strobe row on | |||
if (activeHigh) | |||
{ | |||
refRowPort.setActivePinHigh(rowPin); | |||
} | |||
else //activeLow | |||
{ | |||
refRowPort.setActivePinLow(rowPin); | |||
} | |||
//read all the column ports | |||
for (uint8_t i=0; i < colPortCount; i++) | |||
{ | |||
ptrsColPorts[i]->read(); | |||
} | |||
//strobe row off | |||
if (activeHigh) | |||
{ | |||
refRowPort.setActivePinLow(rowPin); | |||
} | |||
else //activeLow | |||
{ | |||
refRowPort.setActivePinHigh(rowPin); | |||
} | |||
return getRowState(rowEnd); | |||
} | |||
/* | |||
Copies column pins to rowState. Unused column pins are not copied. | |||
Sets rowEnd and returns rowState. | |||
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. | |||
rowEnd is a larger type than portMask so that it can not overflow. | |||
*/ | |||
uint8_t RowScanner_BitManipulation::getRowState(uint16_t& rowEnd) | |||
{ | |||
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed | |||
rowEnd = 1; | |||
for (uint8_t i=0; i < colPortCount; i++) //for each col port | |||
{ | |||
//bitwise colPins, 1 means pin is connected to column | |||
uint8_t colPins = ptrsColPorts[i]->getColPins(); | |||
//bitwise colPortState, pin values where set in ColPort::read(), get them now | |||
uint8_t colPortState = ptrsColPorts[i]->getPortState(); | |||
if (activeHigh) | |||
{ | |||
colPortState = ~colPortState; | |||
} | |||
for ( uint8_t portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow | |||
{ //for each pin of col port | |||
if (portMask & colPins) //if pin is connected to column | |||
{ | |||
if (portMask & ~colPortState) //if pin detected a key press | |||
{ | |||
rowState |= rowEnd; //set rowState bit for that key | |||
} | |||
rowEnd <<= 1; //shift rowEnd to next key | |||
} | |||
} | |||
} | |||
return rowState; | |||
} |
@@ -1,29 +0,0 @@ | |||
#ifndef ROWSCANNER_BITMANIPULATION_H | |||
#define ROWSCANNER_BITMANIPULATION_H | |||
#include <Arduino.h> | |||
#include <inttypes.h> | |||
#include <RowScannerInterface.h> | |||
#include <RowPort.h> | |||
#include <ColPort.h> | |||
/* RowScanner_BitManipulation uses bit manipulation to read all pins of one port. | |||
*/ | |||
class RowScanner_BitManipulation : public RowScannerInterface | |||
{ | |||
private: | |||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | |||
RowPort &refRowPort; //this row's IC port | |||
const uint8_t rowPin; //bitwise, 1 indicates IC pin connected to this row | |||
ColPort *const *const ptrsColPorts; //array of column ports | |||
const uint8_t colPortCount; | |||
public: | |||
RowScanner_BitManipulation(RowPort &refRowPort, const uint8_t rowPin, | |||
ColPort *const ptrsColPorts[], const uint8_t colPortCount) | |||
: refRowPort(refRowPort), rowPin(rowPin), | |||
ptrsColPorts(ptrsColPorts), colPortCount(colPortCount) {} | |||
virtual uint8_t scan(uint16_t& rowEnd); | |||
uint8_t getRowState(uint16_t& rowEnd); | |||
}; | |||
#endif |
@@ -1,4 +1,4 @@ | |||
#include "RowScanner_Arduino.h" | |||
#include "RowScanner_PinsArray.h" | |||
/* | |||
Strobes the row and reads the columns. | |||
@@ -7,7 +7,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. | |||
rowEnd is a larger type than portMask so that it can not overflow. | |||
*/ | |||
uint8_t RowScanner_Arduino::scan(uint16_t& rowEnd) | |||
uint8_t RowScanner_PinsArray::scan(uint16_t& rowEnd) | |||
{ | |||
uint8_t rowState = 0; | |||
rowEnd = 1; | |||
@@ -23,7 +23,7 @@ uint8_t RowScanner_Arduino::scan(uint16_t& rowEnd) | |||
} | |||
delayMicroseconds(3); //time to stablize voltage | |||
//read all the column ports | |||
//read all the column pins | |||
for (uint8_t i=0; i < READ_PIN_COUNT; i++) | |||
{ | |||
if ( digitalRead(readPins[i]) == activeHigh ) |
@@ -1,14 +1,14 @@ | |||
#ifndef ROWSCANNER_ARDUINO_H | |||
#define ROWSCANNER_ARDUINO_H | |||
#ifndef ROWSCANNER_PINSARRAY_H | |||
#define ROWSCANNER_PINSARRAY_H | |||
#include <Arduino.h> | |||
#include <inttypes.h> | |||
#include <RowScannerInterface.h> | |||
#include <RowPort.h> | |||
#include <ColPort.h> | |||
/* RowScanner_Arduino class uses Arduino pin numbers (no port name). | |||
/* RowScanner_PinsArray class uses Arduino pin numbers (no port name). | |||
*/ | |||
class RowScanner_Arduino : public RowScannerInterface | |||
class RowScanner_PinsArray : public RowScannerInterface | |||
{ | |||
private: | |||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | |||
@@ -16,7 +16,7 @@ class RowScanner_Arduino : public RowScannerInterface | |||
const uint8_t* readPins; //array of read pin numbers | |||
const uint8_t READ_PIN_COUNT; //number of read pins | |||
public: | |||
RowScanner_Arduino(const uint8_t strobePin, | |||
RowScanner_PinsArray(const uint8_t strobePin, | |||
const uint8_t readPins[], const uint8_t READ_PIN_COUNT) | |||
: strobePin(strobePin), readPins(readPins), READ_PIN_COUNT(READ_PIN_COUNT) | |||
{ |
@@ -0,0 +1,79 @@ | |||
#include "RowScanner_PinsBitwise.h" | |||
/* | |||
Strobes the row and reads the columns. | |||
Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. | |||
*/ | |||
uint8_t RowScanner_PinsBitwise::scan(uint16_t& rowEnd) | |||
{ | |||
//strobe row on | |||
if (activeHigh) | |||
{ | |||
refRowPort.setActivePinHigh(strobePin); | |||
} | |||
else //activeLow | |||
{ | |||
refRowPort.setActivePinLow(strobePin); | |||
} | |||
delayMicroseconds(3); //time to stablize voltage | |||
//read all the port pins | |||
refColPort.read(); | |||
/* shows strobing pin 1 and 2, but realy stobing 0 and 1 todo | |||
Keyboard.print(F(" strobePin=")); | |||
Keyboard.print(strobePin); | |||
Keyboard.print(F(", ")); | |||
*/ | |||
//strobe row off | |||
if (activeHigh) | |||
{ | |||
refRowPort.setActivePinLow(strobePin); | |||
} | |||
else //activeLow | |||
{ | |||
refRowPort.setActivePinHigh(strobePin); | |||
} | |||
return getRowState(rowEnd); | |||
} | |||
/* | |||
Copies column pins to rowState. Unused column pins are not copied. | |||
Sets rowEnd and returns rowState. | |||
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. | |||
rowEnd is a larger type than portMask so that it can not overflow. | |||
*/ | |||
uint8_t RowScanner_PinsBitwise::getRowState(uint16_t& rowEnd) | |||
{ | |||
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed | |||
uint8_t portMask; //bitwise, 1 bit is a colPortState position | |||
rowEnd = 1; | |||
//bitwise colPins, 1 means pin is connected to column | |||
uint8_t colPins = refColPort.getColPins(); | |||
//bitwise colPortState, pin values where set in ColPort::read(), get them now | |||
uint8_t colPortState = refColPort.getPortState(); | |||
if (activeHigh) | |||
{ | |||
colPortState = ~colPortState; | |||
} | |||
for ( portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow | |||
{ //for each pin of col port | |||
if (portMask & colPins) //if pin is connected to column | |||
{ | |||
if (portMask & ~colPortState) //if pin detected a key press | |||
{ | |||
rowState |= rowEnd; //set rowState bit for that key | |||
} | |||
rowEnd <<= 1; //shift rowEnd to next key | |||
} | |||
} | |||
//todo Keyboard.print(rowState); | |||
return rowState; | |||
} |
@@ -0,0 +1,26 @@ | |||
#ifndef ROWSCANNER_PINSBITWISE_H | |||
#define ROWSCANNER_PINSBITWISE_H | |||
#include <Arduino.h> | |||
#include <inttypes.h> | |||
#include <RowScannerInterface.h> | |||
#include <RowPort.h> | |||
#include <ColPort.h> | |||
/* RowScanner_PinsBitwise uses bit manipulation to read all pins of one port. | |||
*/ | |||
class RowScanner_PinsBitwise : public RowScannerInterface | |||
{ | |||
private: | |||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | |||
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) {} | |||
virtual uint8_t scan(uint16_t& rowEnd); | |||
uint8_t getRowState(uint16_t& rowEnd); | |||
}; | |||
#endif |