/* scan() strobes the row's strobePin and retuns state of port's input pins. | /* scan() strobes the row's strobePin and retuns state of port's input pins. | ||||
Bitwise variables are 1 bit per key. | Bitwise variables are 1 bit per key. | ||||
*/ | */ | ||||
uint8_t Scanner_IOE::scan(const uint8_t strobePin) | |||||
read_pins_t Scanner_IOE::scan(const uint8_t strobePin) | |||||
{ | { | ||||
uint8_t readState; //bitwise, 1 means key is pressed, 0 means released | uint8_t readState; //bitwise, 1 means key is pressed, 0 means released | ||||
refPortWrite(refPortWrite), refPortRead(refPortRead) {} | refPortWrite(refPortWrite), refPortRead(refPortRead) {} | ||||
void init(const uint8_t strobePin); | void init(const uint8_t strobePin); | ||||
void begin(); | void begin(); | ||||
uint8_t scan(const uint8_t strobePin); | |||||
read_pins_t scan(const uint8_t strobePin); | |||||
}; | }; | ||||
#endif | #endif |
#include "Scanner_ShiftRegs74HC165.h" | #include "Scanner_ShiftRegs74HC165.h" | ||||
//constructor | |||||
Scanner_ShiftRegs74HC165::Scanner_ShiftRegs74HC165(const uint8_t strobePin, uint8_t readPinCount) | |||||
: strobePin(strobePin), byte_count(ceil (float(readPinCount)/8)) | |||||
Scanner_ShiftRegs74HC165::Scanner_ShiftRegs74HC165(const bool strobeOn, const uint8_t slaveSelect, | |||||
const uint8_t readPinCount) | |||||
: strobeOn(strobeOn), strobeOff(!strobeOn), slaveSelect(slaveSelect), | |||||
byte_count( ceil(float(readPinCount)/8) ) | |||||
{ | |||||
pinMode(slaveSelect, OUTPUT); | |||||
} | |||||
/* init() is called once for each row from Row constructor. | |||||
Configure controller to communicate with shift register matrix. | |||||
*/ | |||||
void Scanner_ShiftRegs74HC165::init(const uint8_t strobePin) | |||||
{ | { | ||||
//configure controller to communicate with shift register matrix | |||||
pinMode(strobePin, OUTPUT); | pinMode(strobePin, OUTPUT); | ||||
pinMode(SHIFT_LOAD, OUTPUT); | |||||
} | } | ||||
/* begin() should be called once from sketch setup(). | |||||
*/ | |||||
void Scanner_ShiftRegs74HC165::begin() | void Scanner_ShiftRegs74HC165::begin() | ||||
{ | { | ||||
//initialize shift register's shift/load pin | //initialize shift register's shift/load pin | ||||
digitalWrite(SHIFT_LOAD, HIGH); | |||||
digitalWrite(slaveSelect, HIGH); | |||||
} | } | ||||
/* scan() strobes the row's strobePin and retuns state of the shift register's input pins. | |||||
/* scan() strobes the row's strobePin and returns state of the shift register's input pins. | |||||
strobePin is Arduino pin number connected to this row | |||||
Bitwise variables are 1 bit per key. | Bitwise variables are 1 bit per key. | ||||
*/ | */ | ||||
read_pins_t Scanner_ShiftRegs74HC165::scan() | |||||
read_pins_t Scanner_ShiftRegs74HC165::scan(const uint8_t strobePin) | |||||
{ | { | ||||
read_pins_t readState = 0; //bitwise, 1 means key is pressed, 0 means released | read_pins_t readState = 0; //bitwise, 1 means key is pressed, 0 means released | ||||
//strobe row on | //strobe row on | ||||
digitalWrite(strobePin, STROBE_ON); | |||||
delayMicroseconds(3); //time to stablize voltage | |||||
digitalWrite(strobePin, strobeOn); | |||||
//delayMicroseconds(3); //time to stablize voltage | |||||
delayMicroseconds(333); //todo | |||||
//read all the column pins | //read all the column pins | ||||
digitalWrite(SHIFT_LOAD, LOW); //load parallel inputs to the register | |||||
digitalWrite(SHIFT_LOAD, HIGH); //shift the data toward a serial output | |||||
SPI.transfer(&readState, byte_count); | |||||
digitalWrite(slaveSelect, LOW); //load parallel inputs to the register | |||||
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output | |||||
//SPI.transfer(&readState, byte_count); | |||||
SPI.transfer(&readState, 4);//todo | |||||
//strobe row off | //strobe row off | ||||
digitalWrite(strobePin, STROBE_OFF); | |||||
digitalWrite(strobePin, strobeOff); | |||||
return readState; | return readState; | ||||
} | } |
#include <inttypes.h> | #include <inttypes.h> | ||||
#include <config_keybrd.h> | #include <config_keybrd.h> | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <ScannerInterface.h> | |||||
#include <PortWriteInterface.h> | #include <PortWriteInterface.h> | ||||
#include <PortReadInterface.h> | #include <PortReadInterface.h> | ||||
Orient diodes with cathode (banded end) towards the write pins (row) | 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 | Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin | ||||
Use these two lines in the sketch: | Use these two lines in the sketch: | ||||
const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW; | |||||
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH; | |||||
const bool Scanner_ShiftRegs74HC165::strobeOn = LOW; | |||||
const bool Scanner_ShiftRegs74HC165::strobeOff = HIGH; | |||||
For active high: | For active high: | ||||
Shift register parallel input pins have 10k pull-down resistors grounded | Shift register parallel input pins have 10k pull-down resistors grounded | ||||
Orient diodes with cathode (banded end) towards the read pins. | Orient diodes with cathode (banded end) towards the read pins. | ||||
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 | ||||
Use these two lines in the sketch: | Use these two lines in the sketch: | ||||
const bool Scanner_ShiftRegs74HC165::STROBE_ON = HIGH; | |||||
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = LOW; | |||||
const bool Scanner_ShiftRegs74HC165::strobeOn = HIGH; | |||||
const bool Scanner_ShiftRegs74HC165::strobeOff = LOW; | |||||
In addition, each row needs to be connected to a strobe pin from the controller. | In addition, each row needs to be connected to a strobe pin from the controller. | ||||
*/ | */ | ||||
class Scanner_ShiftRegs74HC165 | |||||
class Scanner_ShiftRegs74HC165 : public ScannerInterface | |||||
{ | { | ||||
private: | private: | ||||
static const uint8_t SHIFT_LOAD; //controller's pin number that is | |||||
// connected to shift register's SHIFT_LOAD pin | |||||
static const bool STROBE_ON; //logic level of strobe on, active state HIGH or LOW | |||||
static const bool STROBE_OFF; //logic level of strobe off, complement of active state | |||||
const uint8_t strobePin; //Arduino pin number connected to this row | |||||
const bool strobeOn; //logic level of strobe on, active state HIGH or LOW | |||||
const bool strobeOff; //logic level of strobe off, complement of active state | |||||
const uint8_t slaveSelect; //controller's pin number that is | |||||
// connected to shift register's SHIFT-LOAD pin | |||||
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 | ||||
public: | public: | ||||
Scanner_ShiftRegs74HC165(const uint8_t strobePin, const uint8_t readPinCount); | |||||
virtual read_pins_t scan(); | |||||
Scanner_ShiftRegs74HC165(const bool strobeOn, const uint8_t slaveSelect, | |||||
const uint8_t readPinCount); | |||||
void init(const uint8_t strobePin); | |||||
void begin(); | void begin(); | ||||
virtual read_pins_t scan(const uint8_t strobePin); | |||||
}; | }; | ||||
#endif | #endif |
For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::readPinCount | For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::readPinCount | ||||
For Scanner_IOE, cover the last 1 bit in Scanner_IOE::strobePin | For Scanner_IOE, cover the last 1 bit in Scanner_IOE::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; | ||||
//typedef uint32_t read_pins_t; | |||||
typedef uint32_t read_pins_t; | |||||
/* SAMPLE_COUNT_MACRO is used in Debouncer_Samples.h | /* SAMPLE_COUNT_MACRO is used in Debouncer_Samples.h | ||||
SAMPLE_COUNT_MACRO = 4 is very reliable for a keyboard. | SAMPLE_COUNT_MACRO = 4 is very reliable for a keyboard. |
The right matrix has 2 shift registers daisy chained. | The right matrix has 2 shift registers daisy chained. | ||||
Layout Layout | Layout Layout | ||||
| Left |**0** | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**| | |||||
|:-----:|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|-----| | |||||
| **0** | x | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | |||||
| **1** | y | | **1** | a | b | c | d | e | f | g | h | | |||||
| Left |**0**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**| | |||||
|:-----:|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----| | |||||
| **0** | x | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | | |||||
| **1** | y | | **1** | a | b | c | d | e | f | g | | |||||
*/ | */ | ||||
// ################## GLOBAL ################### | // ################## GLOBAL ################### | ||||
// ================= INCLUDES ================== | // ================= INCLUDES ================== | ||||
#include <Code_Sc.h> | #include <Code_Sc.h> | ||||
//Left matrix | //Left matrix | ||||
#include <Row_uC.h> | |||||
#include <Scanner_uC.h> | |||||
#include <Row.h> | |||||
//Right matrix | //Right matrix | ||||
#include <SPI.h> | |||||
#include <Row_ShiftRegisters.h> | |||||
#include <SPI.h>//needed?? todo | |||||
#include <Scanner_ShiftRegs74HC165.h> | |||||
// =============== CONFIGURATION =============== | // =============== CONFIGURATION =============== | ||||
ScanDelay scanDelay(9000); | ScanDelay scanDelay(9000); | ||||
Code_Sc s_6(KEY_6); | Code_Sc s_6(KEY_6); | ||||
// =============== LEFT MATRIX ================= | // =============== LEFT MATRIX ================= | ||||
//set left matrix for active low | |||||
const bool Scanner_uC::STROBE_ON = LOW; | |||||
const bool Scanner_uC::STROBE_OFF = HIGH; | |||||
uint8_t readPins_L[] = {14}; | |||||
uint8_t readPinCount_L = sizeof(readPins_L)/sizeof(*readPins_L); | |||||
//column pin | |||||
uint8_t readPins[] = {14}; | |||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins); | |||||
Scanner_uC scanner_L(LOW, readPins_L, readPinCount_L); //active LOW | |||||
//rows | //rows | ||||
Key* ptrsKeys_L0[] = { &s_x }; | Key* ptrsKeys_L0[] = { &s_x }; | ||||
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0); | |||||
uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0); | |||||
Row row_L0(scanner_L, 0, ptrsKeys_L0, KEY_COUNT_L0); | |||||
Key* ptrsKeys_L1[] = { &s_y }; | Key* ptrsKeys_L1[] = { &s_y }; | ||||
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1); | |||||
uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1); | |||||
Row row_L1(scanner_L, 1, ptrsKeys_L1, KEY_COUNT_L1); | |||||
// =============== RIGHT MATRIX ================ | // =============== RIGHT MATRIX ================ | ||||
//set matrix to active high | |||||
const bool Scanner_ShiftRegs74HC165::STROBE_ON = HIGH; | |||||
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = LOW; | |||||
//chip select pin | |||||
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10; | |||||
//use slaveSelect pin SS (Arduino pin 10) for fastest scan | |||||
Scanner_ShiftRegs74HC165 scanner_R(HIGH, SS, 14); //active HIGH | |||||
//rows | //rows | ||||
Key* ptrsKeys_R0[] = { &s_6, &s_5, &s_4, &s_3, //shift regiser on right | |||||
Key* ptrsKeys_R0[] = { &s_6, &s_5, &s_4, &s_3, //shift register on right | |||||
&s_c, &s_d, &s_e, &s_f, | &s_c, &s_d, &s_e, &s_f, | ||||
&s_2, &s_1, &s_0, &s_g, //shift regiser on left | |||||
&s_2, &s_1, &s_0, &s_g, //shift register on left | |||||
&s_a, &s_b }; //unused input pins are grounded | &s_a, &s_b }; //unused input pins are grounded | ||||
Row_ShiftRegisters row_R0(0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0); | |||||
Row row_R0(scanner_R, 0, ptrsKeys_R0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0)); | |||||
// ################### MAIN #################### | // ################### MAIN #################### | ||||
void setup() | void setup() | ||||
{ | { | ||||
Keyboard.begin(); | Keyboard.begin(); | ||||
SPI.begin(); | |||||
row_R0.begin(); | |||||
SPI.begin();//todo move to begin() | |||||
scanner_R.begin(); | |||||
} | } | ||||
void loop() | void loop() |