// =============== CONFIGURATION =============== | // =============== CONFIGURATION =============== | ||||
ScanDelay scanDelay(9000); | ScanDelay scanDelay(9000); | ||||
const bool RowScanner_PinsArray::ACTIVE_HIGH = 0; //left matrix is active low | |||||
//active state of left matrix | |||||
const bool RowScanner_PinsArray::STROBE_ON = LOW; | |||||
const bool RowScanner_PinsArray::STROBE_OFF = HIGH; | |||||
const uint8_t RowScanner_SPIShiftRegisters::SHIFT_LOAD = 10; | const uint8_t RowScanner_SPIShiftRegisters::SHIFT_LOAD = 10; | ||||
Debug debug; | Debug debug; |
//configure row | //configure row | ||||
pinMode(STROBE_PIN, OUTPUT); | pinMode(STROBE_PIN, OUTPUT); | ||||
if (ACTIVE_HIGH) | |||||
if (STROBE_ON == LOW) //if active low | |||||
{ | { | ||||
mode = INPUT; //requires external pull-down resistor | |||||
mode = INPUT_PULLUP; //uses internal pull-up resistor | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
mode = INPUT_PULLUP; //uses internal pull-up resistor | |||||
mode = INPUT; //requires external pull-down resistor | |||||
} | } | ||||
//configure cols | //configure cols | ||||
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 rowMask = 1; //bitwise, one col per bit, active col bit is 1 | ||||
//strobe row on | |||||
if (ACTIVE_HIGH) | |||||
{ | |||||
digitalWrite(STROBE_PIN, HIGH); | |||||
} | |||||
else //activeLow | |||||
{ | |||||
digitalWrite(STROBE_PIN, LOW); | |||||
} | |||||
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 column 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]) == ACTIVE_HIGH ) | |||||
if ( digitalRead(READ_PINS[i]) == STROBE_ON ) | |||||
{ | { | ||||
rowState |= rowMask; | rowState |= rowMask; | ||||
} | } | ||||
rowMask <<= 1; | rowMask <<= 1; | ||||
} | } | ||||
//strobe row off | |||||
if (ACTIVE_HIGH) | |||||
{ | |||||
digitalWrite(STROBE_PIN, LOW); | |||||
} | |||||
else //activeLow | |||||
{ | |||||
digitalWrite(STROBE_PIN, HIGH); | |||||
} | |||||
digitalWrite(STROBE_PIN, STROBE_OFF); | |||||
keyCount = READ_PIN_COUNT; | keyCount = READ_PIN_COUNT; | ||||
return rowState; | return rowState; |
class RowScanner_PinsArray | class RowScanner_PinsArray | ||||
{ | { | ||||
private: | private: | ||||
static const bool ACTIVE_HIGH; //logic level of strobe pin: 0=activeLow, 1=activeHigh | |||||
static const bool STROBE_ON; //logic level of strobe on, HIGH or LOW | |||||
static const bool STROBE_OFF; //logic level of strobe off, HIGH or LOW | |||||
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* 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 |
ColPort* const RowScanner_PinsBitwise::scan() | ColPort* const RowScanner_PinsBitwise::scan() | ||||
{ | { | ||||
//strobe row on | //strobe row on | ||||
if (activeHigh) | |||||
if (STROBE_ON == LOW) | |||||
{ | { | ||||
refRowPort.setActivePinHigh(strobePin); | |||||
refRowPort.setActivePinLow(strobePin); | |||||
} | } | ||||
else //activeLow | else //activeLow | ||||
{ | { | ||||
refRowPort.setActivePinLow(strobePin); | |||||
refRowPort.setActivePinHigh(strobePin); | |||||
} | } | ||||
delayMicroseconds(3); //time to stablize voltage | delayMicroseconds(3); //time to stablize voltage | ||||
refColPort.read(); | refColPort.read(); | ||||
//strobe row off | //strobe row off | ||||
if (activeHigh) | |||||
if (STROBE_ON == LOW) | |||||
{ | { | ||||
refRowPort.setActivePinLow(strobePin); | |||||
refRowPort.setActivePinHigh(strobePin); | |||||
} | } | ||||
else //activeLow | else //activeLow | ||||
{ | { | ||||
refRowPort.setActivePinHigh(strobePin); | |||||
refRowPort.setActivePinLow(strobePin); | |||||
} | } | ||||
return &refColPort; | return &refColPort; |
ColPort& refColPort) | ColPort& refColPort) | ||||
: 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 STROBE_ON; //logic level of strobe on, active state, HIGH or LOW | |||||
virtual ColPort* const scan(); | virtual ColPort* const scan(); | ||||
}; | }; | ||||
#endif | #endif |
Instantiation | Instantiation | ||||
------------- | ------------- | ||||
Definition of DELAY_MICROSECONDS is explained in RowBase.cpp. | Definition of DELAY_MICROSECONDS is explained in RowBase.cpp. | ||||
todo Definition of activeHigh is explained in RowScanner_Interface.h | |||||
Example instantiation of a row: | Example instantiation of a row: | ||||
const unsigned int RowBase::DELAY_MICROSECONDS = 1000; | const unsigned int RowBase::DELAY_MICROSECONDS = 1000; | ||||
const bool RowScanner_PinsArray::activeHigh = 0; | |||||
const bool RowScanner_PinsArray::STROBE_ON = LOW; //logic level of strobe on | |||||
const bool RowScanner_PinsArray::STROBE_OFF = HIGH; //logic level of strobe off | |||||
const uint8_t colPins[] = {0,1,2,3,7,8}; | const uint8_t colPins[] = {0,1,2,3,7,8}; | ||||
const uint8_t COL_PIN_COUNT = sizeof(colPins)/sizeof(*colPins); | const uint8_t COL_PIN_COUNT = sizeof(colPins)/sizeof(*colPins); |
Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing. | 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. | |||||
/* 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 RowScanner_PinsArray, RowScanner_PinsArray::READ_PIN_COUNT | ||||
For RowScanner_SPIShiftRegisters, RowScanner_SPIShiftRegisters::KEY_COUNT | For RowScanner_SPIShiftRegisters, RowScanner_SPIShiftRegisters::KEY_COUNT | ||||
For RowScanner_PinsBitwise, cover the last 1 bit in RowScanner_PinsBitwise::strobePin | For RowScanner_PinsBitwise, cover the last 1 bit in RowScanner_PinsBitwise::strobePin |