Bläddra i källkod

document row files

tags/v0.5.0
wolfv6 7 år sedan
förälder
incheckning
147154f040

+ 10
- 11
doc/keybrd_library_developer_guide.md Visa fil

## Style guide ## Style guide
Following the style guide makes it easier for the next programmer to understand your code. Following the style guide makes it easier for the next programmer to understand your code.
* For class names, see above section "Class naming conventions"
* For member names, use camelCase starting with lowercase letter.
* For class names, see above section "Class naming conventions".
* Member names use camelCase starting with lowercase letter.
* Use constants rather than macros, except for header guards. * Use constants rather than macros, except for header guards.
* For constant names that could be macros, use ALL_CAPS_AND_UNDERSCORE.
* **ITEM_COUNT** is a constant number of items.
* **itemCount** is a variable number of items.
* Use header guards CLASS_NAME_H.
* Prefix pointer name with "ptr" e.g. ptrRow = &row;
* Name arrays using the plural of element name e.g. Row* const = ptrsRows { &row0, &row1 };
* Pass arrays using array notation rather than pointer notation. Use
* Global const names and static const names use ALL_CAPS_AND_UNDERSCORE.
* Macros use ALL_CAPS_AND_UNDERSCORE and have _MACRO suffix e.g. SAMPLE_COUNT_MACRO
* Header guards have _H suffix e.g. #ifndef FILE_NAME_H
* Pointer names are prefixed with "ptr" e.g. ptrRow = &row;
* Arrays names use the plural of element name e.g. Row* const = ptrsRows { &row0, &row1 };
* Pass arrays using array notation rather than pointer notation:
``` ```
void printArray(char[] array); void printArray(char[] array);
not not
* In constructor's initialization list, use same names for fields and constructor parameters. * In constructor's initialization list, use same names for fields and constructor parameters.
* Do not use new or malloc (making memory leaks impossible). * Do not use new or malloc (making memory leaks impossible).
* Document class interface in .h file, above the class declaration. * Document class interface in .h file, above the class declaration.
* Code should be self-documenting. The only comments should be things that may need clarification. A simple function with a good name needs no comment.
* Code is automatically formated before being pushed to the keybrd repository.
* Code should be self-documenting. A simple function with a good name needs no comment.
* Code is automatically formatted before being pushed to the keybrd repository.
The [astyle_cpp](astyle_cpp) file specifies the format: The [astyle_cpp](astyle_cpp) file specifies the format:
* Allman style indentation * Allman style indentation
* indent 4 spaces * indent 4 spaces

+ 11
- 12
examples/keybrd_shift_register/keybrd_shift_register.ino Visa fil

// ================= INCLUDES ================== // ================= INCLUDES ==================
#include <Debug.h> #include <Debug.h>
#include <ScanDelay.h> #include <ScanDelay.h>
#include <LED_PinNumber.h>
#include <LED_uC.h>
#include <SPI.h>


//Codes //Codes
#include <Code_Sc.h> #include <Code_Sc.h>


//Matrix //Matrix
#include <Row_uC.h> #include <Row_uC.h>
#include <SPI.h>
#include <Row_ShiftRegisters.h> #include <Row_ShiftRegisters.h>


// =============== CONFIGURATION =============== // =============== CONFIGURATION ===============
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins); uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);


// ==================== LEDs =================== // ==================== LEDs ===================
LED_PinNumber LED1(16);
LED_uC LED1(16);


//sometimes OS takes 6 seconds to recongnize keyboard, LED blinks from the begining //sometimes OS takes 6 seconds to recongnize keyboard, LED blinks from the begining
void wait() void wait()
/* /*
//prints 0 1 //prints 0 1
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z }; Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z };
const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0); Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0);


//prints a b //prints a b
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z }; Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &s_z, &s_z, &s_z };
const uint8_t READ_PIN_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
uint8_t READ_PIN_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
Row_ShiftRegisters row_R1(9, READ_PIN_COUNT_R1, ptrsKeys_R1); Row_ShiftRegisters row_R1(9, READ_PIN_COUNT_R1, ptrsKeys_R1);
*/ */
/* /*
//prints 0 1 2 //prints 0 1 2
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z, Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
&s_2, &s_z, &s_z, &s_z }; &s_2, &s_z, &s_z, &s_z };
const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0); Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0);
*/ */
/* /*
//prints 0 1 2 3 //prints 0 1 2 3
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z, Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z }; &s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z };
const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0); Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0);
*/ */
/* /*
Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z, Key* ptrsKeys_R0[] = { &s_0, &s_z, &s_z, &s_z, &s_1, &s_z, &s_z, &s_z,
&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z, &s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z,
&s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z }; &s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z };
const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0); Row_ShiftRegisters row_R0(8, READ_PIN_COUNT_R0, ptrsKeys_R0);
*/ */


&s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z, &s_2, &s_z, &s_z, &s_z, &s_3, &s_z, &s_z, &s_z,
&s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z, &s_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z,
&s_6, &s_z, &s_z, &s_z, &s_3, &s_4, &s_5, &s_6 }; &s_6, &s_z, &s_z, &s_z, &s_3, &s_4, &s_5, &s_6 };
const uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
uint8_t READ_PIN_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row_ShiftRegisters row_R0(0, READ_PIN_COUNT_R0, ptrsKeys_R0); Row_ShiftRegisters row_R0(0, READ_PIN_COUNT_R0, ptrsKeys_R0);


//prints a b c d u v w x //prints a b c d u v w x
&s_c, &s_z, &s_z, &s_z, &s_d, &s_z, &s_z, &s_z, &s_c, &s_z, &s_z, &s_z, &s_d, &s_z, &s_z, &s_z,
&s_e, &s_z, &s_z, &s_z, &s_f, &s_z, &s_z, &s_z, &s_e, &s_z, &s_z, &s_z, &s_f, &s_z, &s_z, &s_z,
&s_g, &s_z, &s_z, &s_z, &s_u, &s_v, &s_w, &s_x }; &s_g, &s_z, &s_z, &s_z, &s_u, &s_v, &s_w, &s_x };
const uint8_t READ_PIN_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
uint8_t READ_PIN_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
Row_ShiftRegisters row_R1(1, READ_PIN_COUNT_R1, ptrsKeys_R1); Row_ShiftRegisters row_R1(1, READ_PIN_COUNT_R1, ptrsKeys_R1);


// ################### MAIN #################### // ################### MAIN ####################
void setup() void setup()
{ {
Keyboard.begin(); Keyboard.begin();

wait();
SPI.begin(); SPI.begin();
row_R0.begin(); row_R0.begin();
row_R1.begin(); row_R1.begin();


wait();
Keyboard.println(F("keybrd_shift_reg.ino")); Keyboard.println(F("keybrd_shift_reg.ino"));
} }



+ 3
- 2
src/Debouncer_Samples.h Visa fil

#ifndef DEBOUNCER_4SAMPLES_H
#define DEBOUNCER_4SAMPLES_H
#ifndef DEBOUNCER_SAMPLES_H
#define DEBOUNCER_SAMPLES_H

#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>

+ 3
- 3
src/Row.cpp Visa fil

#include "Row.h" #include "Row.h"
/* /*
send() calls key's press() or release() function if it was pressed or released.
send() calls key's press() or release() function if key was pressed or released.
Both parameters are bitwise. Both parameters are bitwise.
*/ */
void Row::send(const uint8_t readPinCount, const read_pins_t debouncedChanged) void Row::send(const uint8_t readPinCount, const read_pins_t debouncedChanged)
{ {
read_pins_t isFallingEdge; //bitwise, 1 means falling edge read_pins_t isFallingEdge; //bitwise, 1 means falling edge
read_pins_t isRisingEdge; //bitwise, 1 means rising edge read_pins_t isRisingEdge; //bitwise, 1 means rising edge
read_pins_t readMask; //bitwise, active read bit is 1
read_pins_t readMask; //bitwise, active bit is 1
uint8_t i; //index for ptrsKeys[i] array uint8_t i; //index for ptrsKeys[i] 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
void Row::keyWasPressed() void Row::keyWasPressed()
{ {
//empty in Row class. To unstick sticky keys, override keyWasPressed() in derived class.
//empty in Row class. To unstick sticky keys, override keyWasPressed() in derived Row class.
} }

+ 3
- 1
src/Row.h Visa fil

#ifndef ROW_H #ifndef ROW_H
#define ROW_H #define ROW_H
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>
Key *const *const ptrsKeys; //array of Key pointers Key *const *const ptrsKeys; //array of Key pointers
virtual void keyWasPressed(); virtual void keyWasPressed();
protected: protected:
read_pins_t debounced; //bitwise, 1 means pressed, 0 means released
read_pins_t debounced; //bitwise state of keys after debouncing
// 1 means pressed, 0 means released
void send(const uint8_t readPinCount, const read_pins_t debouncedChanged); void send(const uint8_t readPinCount, const read_pins_t debouncedChanged);
public: public:
Row(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { } Row(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }

+ 12
- 8
src/Row_ShiftRegisters.cpp Visa fil

#include "Row_ShiftRegisters.h" #include "Row_ShiftRegisters.h"


/* Call begin() once in sketch setup()
*/
void Row_ShiftRegisters::begin()
{
scanner.begin();
}

/* process() scans the row and calls any newly pressed or released keys.
Bitwise variables are 1 bit per key.
*/
void Row_ShiftRegisters::process() void Row_ShiftRegisters::process()
{ {
//these variables are all bitwise, one bit per key
read_pins_t readState; //1 means pressed, 0 means released
read_pins_t debouncedChanged; //1 means debounced changed
read_pins_t readState; //bitwise, 1 means key is pressed, 0 means released
read_pins_t debouncedChanged; //bitwise, 1 means debounced changed


readState = scanner.scan(); readState = scanner.scan();
debouncedChanged = debouncer.debounce(readState, debounced); debouncedChanged = debouncer.debounce(readState, debounced);
send(READ_PIN_COUNT, debouncedChanged); send(READ_PIN_COUNT, debouncedChanged);
} }

void Row_ShiftRegisters::begin()
{
scanner.begin();
}

+ 19
- 12
src/Row_ShiftRegisters.h Visa fil

#include <Row.h> #include <Row.h>
#include <Scanner_ShiftRegs74HC165.h> #include <Scanner_ShiftRegs74HC165.h>
#include <Debouncer_Samples.h> #include <Debouncer_Samples.h>
//#include <Debouncer_Not.h>


/* Row_DH_IOE is a row connected to an Input/Output Expander.
/* Row_ShiftRegisters is a row connected to shift registers.


Instantiation Instantiation
------------- -------------
Definition of DELAY_MICROSECONDS is explained in Row.cpp. Definition of DELAY_MICROSECONDS is explained in Row.cpp.
Example instantiation of a row:
Example instantiation of a Row_ShiftRegisters:


const unsigned int Row::DELAY_MICROSECONDS = 1000;
todo
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW; //logic level of strobe on, active low
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = HIGH; //logic level of strobe off


Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 }; Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 };
Row_ShiftRegisters row_0(uint8_t BYTE_COUNT, ptrsKeys_0);
uint8_t READ_PIN_COUNT_0 = sizeof(ptrsKeys_0)/sizeof(*ptrsKeys_0);
Row_ShiftRegisters row_0(1, READ_PIN_COUNT_0, ptrsKeys_0);

call begin() from sketch setup():
void setup()
{
Keyboard.begin();
SPI.begin();
row_0.begin();
}


Number of pins in colPort0 should equal number of keys in ptrsKeys_0[] array.
if a pin is missing, a key will be unresposive
if a Key pointer is missing, the keyboard will fail in an unprdictable way
READ_PIN_COUNT should equal number of keys in ptrsKeys_0[] array.
if READ_PIN_COUNT is too small, a key will be unresposive
if READ_PIN_COUNT is too large, the keyboard will fail in an unpredictable way
*/ */
class Row_ShiftRegisters : public Row class Row_ShiftRegisters : public Row
{ {
private: private:
Scanner_ShiftRegs74HC165 scanner; Scanner_ShiftRegs74HC165 scanner;
Debouncer_Samples debouncer; Debouncer_Samples debouncer;
//Debouncer_Not debouncer; //passed test
const uint8_t READ_PIN_COUNT; //number of read pins const uint8_t READ_PIN_COUNT; //number of read pins
public: public:
Row_ShiftRegisters(const uint8_t STROBE_PIN, uint8_t READ_PIN_COUNT, Key *const ptrsKeys[])
Row_ShiftRegisters(const uint8_t STROBE_PIN, const uint8_t READ_PIN_COUNT, Key *const ptrsKeys[])
: Row(ptrsKeys), scanner(STROBE_PIN, READ_PIN_COUNT), READ_PIN_COUNT(READ_PIN_COUNT) { } : Row(ptrsKeys), scanner(STROBE_PIN, READ_PIN_COUNT), READ_PIN_COUNT(READ_PIN_COUNT) { }
void begin(); void begin();
void process(); void process();

+ 4
- 5
src/Row_uC.cpp Visa fil

#include "Row_uC.h" #include "Row_uC.h"


/*
process() scans the row and calls any newly pressed or released keys.
/* process() scans the row and calls any newly pressed or released keys.
Bitwise variables are 1 bit per key.
*/ */
void Row_uC::process() void Row_uC::process()
{ {
//these variables are all bitwise, one bit per key
read_pins_t readState; //1 means pressed, 0 means released
read_pins_t debouncedChanged; //1 means debounced changed
read_pins_t readState; //bitwise, 1 means key is pressed, 0 means released
read_pins_t debouncedChanged; //bitwise, 1 means debounced changed


readState = scanner.scan(); readState = scanner.scan();
debouncedChanged = debouncer.debounce(readState, debounced); debouncedChanged = debouncer.debounce(readState, debounced);

+ 4
- 5
src/Row_uC.h Visa fil

Instantiation Instantiation
------------- -------------
Definition of DELAY_MICROSECONDS is explained in Row.cpp. Definition of DELAY_MICROSECONDS is explained in Row.cpp.
Example instantiation of a row:
Example instantiation of a Row_uC:


const unsigned int Row::DELAY_MICROSECONDS = 1000;
const bool Scanner_uC::STROBE_ON = LOW; //logic level of strobe on
const bool Scanner_uC::STROBE_ON = LOW; //logic level of strobe on, active low
const bool Scanner_uC::STROBE_OFF = HIGH; //logic level of strobe off const bool Scanner_uC::STROBE_OFF = HIGH; //logic level of strobe off


const uint8_t readPins[] = {0,1,2,3,7,8}; const uint8_t readPins[] = {0,1,2,3,7,8};


Number of readPins should equal number of keys in ptrsKeys_0[] array. Number of readPins should equal number of keys in ptrsKeys_0[] array.
if a readPins is missing, a key will be unresposive if a readPins is missing, a key will be unresposive
if a Key pointer is missing, the keyboard will fail in an unprdictable way
if a Key pointer is missing, the keyboard will fail in an unpredictable way
*/ */
class Row_uC : public Row class Row_uC : public Row
{ {
private: private:
Scanner_uC scanner; Scanner_uC scanner;
Debouncer_Samples debouncer; Debouncer_Samples debouncer;
const uint8_t READ_PIN_COUNT; //number of read pins
const uint8_t READ_PIN_COUNT;
public: public:
Row_uC(const uint8_t strobePin, const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT, Row_uC(const uint8_t strobePin, const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT,
Key *const ptrsKeys[]) Key *const ptrsKeys[])

+ 6
- 6
src/Scanner_Port.cpp Visa fil

#include "Scanner_Port.h" #include "Scanner_Port.h"
/*
Strobes the row and reads the columns.

/* scan() strobes the row's STROBE_PIN and retuns state of port's input pins.
Bitwise variables are 1 bit per key.
*/ */
uint8_t Scanner_Port::scan() uint8_t Scanner_Port::scan()
{ {
uint8_t readState;
uint8_t readState; //bitwise, 1 means key is pressed, 0 means released


//strobe row on
//strobe on
refPortWrite.write(STROBE_PIN, STROBE_ON); refPortWrite.write(STROBE_PIN, STROBE_ON);
delayMicroseconds(3); //time to stablize voltage delayMicroseconds(3); //time to stablize voltage


//read the port pins //read the port pins
readState = refPortRead.read(); readState = refPortRead.read();


//strobe row off
//strobe off
refPortWrite.write(STROBE_PIN, STROBE_OFF); refPortWrite.write(STROBE_PIN, STROBE_OFF);
//return refPortRead.getPortState();
return readState; return readState;
} }

+ 6
- 4
src/Scanner_Port.h Visa fil

#ifndef SCANNER_PORT_H #ifndef SCANNER_PORT_H
#define SCANNER_PORT_H #define SCANNER_PORT_H

#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <PortWrite.h> #include <PortWrite.h>
#include <PortRead.h> #include <PortRead.h>


/* Scanner_Port uses bit manipulation to read all pins of one port. /* Scanner_Port uses bit manipulation to read all pins of one port.
The ports are normally from an I/O Expander, but could also be ports from an AVR uC.
The maximum keys per row is 8, because ports have a maximum of 8 pins each. The maximum keys per row is 8, because ports have a maximum of 8 pins each.
*/ */
class Scanner_Port class Scanner_Port
{ {
private: private:
static const bool STROBE_ON; //HIGH or LOW logic level of strobe on, active state static const bool STROBE_ON; //HIGH or LOW logic level of strobe on, active state
static const bool STROBE_OFF; //logic level of strobe off, complement of STROBE_ON
PortWrite& refPortWrite; //this row's IC port
const uint8_t STROBE_PIN; //bitwise, 1 indicates IC pin connected to this row
PortRead& refPortRead;
static const bool STROBE_OFF; //logic level of strobe off, complement of STROBE_ON
PortWrite& refPortWrite; //the IC port containing the STROBE_PIN
const uint8_t STROBE_PIN; //bitwise, 1 indicates IC pin connected to this row
PortRead& refPortRead; //the IC's read port
public: public:
Scanner_Port(PortWrite &refPortWrite, const uint8_t STROBE_PIN, PortRead& refPortRead) Scanner_Port(PortWrite &refPortWrite, const uint8_t STROBE_PIN, PortRead& refPortRead)
: refPortWrite(refPortWrite), STROBE_PIN(STROBE_PIN), refPortRead(refPortRead) {} : refPortWrite(refPortWrite), STROBE_PIN(STROBE_PIN), refPortRead(refPortRead) {}

+ 4
- 4
src/Scanner_ShiftRegs74HC165.cpp Visa fil

digitalWrite(SHIFT_LOAD, HIGH); digitalWrite(SHIFT_LOAD, HIGH);
} }


/*
returns readState.
/* scan() strobes the row's STROBE_PIN and retuns state of the shift register's input pins.
Bitwise variables are 1 bit per key.
*/ */
read_pins_t Scanner_ShiftRegs74HC165::scan() read_pins_t Scanner_ShiftRegs74HC165::scan()
{ {
read_pins_t readState = 0;
read_pins_t readState = 0; //bitwise, 1 means key is pressed, 0 means released


//strobe row on //strobe row on
digitalWrite(STROBE_PIN, STROBE_ON); digitalWrite(STROBE_PIN, STROBE_ON);
digitalWrite(STROBE_PIN, STROBE_OFF); digitalWrite(STROBE_PIN, STROBE_OFF);


//for testing on breadboard, clear unpowered pins //for testing on breadboard, clear unpowered pins
readState &= 0b11110001000100010001000100010001; //todo
readState &= 0b11110001000100010001000100010001; //todo delete this line


return readState; return readState;
} }

+ 5
- 8
src/Scanner_ShiftRegs74HC165.h Visa fil

#ifndef ROWSCANNER_SHIFTREGS74HC165_H #ifndef ROWSCANNER_SHIFTREGS74HC165_H
#define ROWSCANNER_SHIFTREGS74HC165_H #define ROWSCANNER_SHIFTREGS74HC165_H

#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>
#include <PortRead.h> #include <PortRead.h>


/* Scanner_ShiftRegs74HC165 reads shift registers. /* Scanner_ShiftRegs74HC165 reads shift registers.
shift registers 74HC165 is Parallel-In-Serial-Out (PISO)
Upto 4 shift registers can be in a daisy chained.

In sketch:
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
call begin() from setup()
shift registers 74HC165 are Parallel-In-Serial-Out (PISO)
Upto 4 shift registers can be in a daisy chained for a total of 32 read pins.


For active low: For active low:
const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW; const bool Scanner_ShiftRegs74HC165::STROBE_ON = LOW;
//shift register parallel input pins have 10k pull-down resistors grounded //shift register parallel input pins have 10k pull-down resistors grounded
//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


In addition, each row needs to be connected to a strobe pin from controller.
In addition, each row needs to be connected to a strobe pin from the controller.


todo move this to tutorial todo move this to tutorial
The shift register needs 5 wires. The shift register needs 5 wires.
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 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 STROBE_PIN, uint8_t READ_PIN_COUNT);
Scanner_ShiftRegs74HC165(const uint8_t STROBE_PIN, const uint8_t READ_PIN_COUNT);
virtual read_pins_t scan(); virtual read_pins_t scan();
void begin(); void begin();
}; };

+ 14
- 13
src/Scanner_uC.cpp Visa fil

#include "Scanner_uC.h" #include "Scanner_uC.h"


/* Scanner_uC functions call Arduino's Digital Pins functions
https://www.arduino.cc/en/Tutorial/DigitalPins
https://www.arduino.cc/en/Reference/PinMode
https://www.arduino.cc/en/Reference/DigitalWrite
https://www.arduino.cc/en/Reference/DigitalRead
https://www.arduino.cc/en/Reference/Constants > Digital Pins modes: INPUT, INPUT_PULLUP, and OUTPUT
*/

/* constructor /* constructor
*/ */
Scanner_uC::Scanner_uC(const uint8_t STROBE_PIN, Scanner_uC::Scanner_uC(const uint8_t STROBE_PIN,


if (STROBE_ON == LOW) //if active low if (STROBE_ON == LOW) //if active low
{ {
mode = INPUT_PULLUP; //uses internal pull-up resistor
mode = INPUT_PULLUP; //use internal pull-up resistor
} }
else
else //if active high
{ {
mode = INPUT; //requires external pull-down resistor mode = INPUT; //requires external pull-down resistor
} }
} }
} }


/* scan() Strobes the row and reads the columns.
Sets READ_PIN_COUNT and returns readState.

https://www.arduino.cc/en/Tutorial/DigitalPins
https://www.arduino.cc/en/Reference/PinMode
https://www.arduino.cc/en/Reference/DigitalWrite
https://www.arduino.cc/en/Reference/DigitalRead
https://www.arduino.cc/en/Reference/Constants > Digital Pins modes: INPUT, INPUT_PULLUP, and OUTPUT
/* scan() strobes the row's STROBE_PIN and retuns state of READ_PINS.
Bitwise variables are 1 bit per key.
*/ */
read_pins_t Scanner_uC::scan() read_pins_t Scanner_uC::scan()
{ {
read_pins_t readState = 0; //bitwise, one col per bit, 1 means key is pressed
read_pins_t readMask = 1; //bitwise, one col per bit, active col bit is 1
read_pins_t readState = 0; //bitwise, 1 means key is pressed, 0 means released
read_pins_t readMask = 1; //bitwise, active bit is 1


//strobe row on //strobe row on
digitalWrite(STROBE_PIN, STROBE_ON); digitalWrite(STROBE_PIN, STROBE_ON);
//strobe row off //strobe row off
digitalWrite(STROBE_PIN, STROBE_OFF); digitalWrite(STROBE_PIN, STROBE_OFF);


// readPinCount = READ_PIN_COUNT;
return readState; return readState;
} }

+ 1
- 0
src/Scanner_uC.h Visa fil

#ifndef SCANNER_UC_H #ifndef SCANNER_UC_H
#define SCANNER_UC_H #define SCANNER_UC_H

#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <config_keybrd.h> #include <config_keybrd.h>

+ 6
- 6
src/config_keybrd.h Visa fil



/* size of read_pins_t depends on the maximum number of pins scanned by RowScanner. /* size of read_pins_t depends on the maximum number of pins scanned by RowScanner.
By default, read_pins_t is set to the largest type. By default, read_pins_t is set to the largest type.
If your 8-bit AVR is running low on memory, using a smaller type saves SRAM.
If your 8-bit AVR (Teensy 2) is running low on memory, using a smaller type saves SRAM.
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 size that covers all col pins of all RowScanner objects i.e.
/* Use a read_pins_t size that covers all read pins of all RowScanner objects i.e.
For Scanner_uC, Scanner_uC::READ_PIN_COUNT For Scanner_uC, Scanner_uC::READ_PIN_COUNT
For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::READ_PIN_COUNT For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::READ_PIN_COUNT
For Scanner_Port, cover the last 1 bit in Scanner_Port::strobePin For Scanner_Port, cover the last 1 bit in Scanner_Port::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 = 4 is very reliable for a keyboard.
/* SAMPLE_COUNT is used in Debouncer_Samples.h
SAMPLE_COUNT = 4 is very reliable for a keyboard.
Split keyboards with a long connecting wire or in environment with Split keyboards with a long connecting wire or in environment with
strong electromagnetic interference (EMI) may need a larger SAMPLE_COUNT for reliability. 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 #define SAMPLE_COUNT 4 //number of consecutive equal bits needed to change a debounced bit