change activeHigh to static, add LED_PinNumber, RowScanner_SPI-ShiftRegisters, keybrd regression tests, remove MCP23018::begin()
This commit is contained in:
parent
fcaa6d06e9
commit
04ab6ebe72
13
examples/tests_regression/classes/Code_Sc_LED.cpp
Normal file
13
examples/tests_regression/classes/Code_Sc_LED.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "Code_Sc_LED.h"
|
||||||
|
|
||||||
|
void Code_Sc_LED::press()
|
||||||
|
{
|
||||||
|
Keyboard.press(scancode);
|
||||||
|
refLED.on();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Code_Sc_LED::release()
|
||||||
|
{
|
||||||
|
Keyboard.release(scancode);
|
||||||
|
refLED.off();
|
||||||
|
}
|
21
examples/tests_regression/classes/Code_Sc_LED.h
Normal file
21
examples/tests_regression/classes/Code_Sc_LED.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef CODE_SC_LED_H
|
||||||
|
#define CODE_SC_LED_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <Code.h>
|
||||||
|
#include <LED.h>
|
||||||
|
|
||||||
|
/* Class Code_Sc_LED sends a scancode when press() or release() is called.
|
||||||
|
"S" stands for Scancode.
|
||||||
|
*/
|
||||||
|
class Code_Sc_LED : public Code
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const uint16_t scancode;
|
||||||
|
LED& refLED;
|
||||||
|
public:
|
||||||
|
Code_Sc_LED(const uint16_t scancode, LED& refLED): scancode(scancode), refLED(refLED) { }
|
||||||
|
virtual void press();
|
||||||
|
virtual void release();
|
||||||
|
};
|
||||||
|
#endif
|
1
examples/tests_regression/keybrd/classes
Symbolic link
1
examples/tests_regression/keybrd/classes
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../classes
|
150
examples/tests_regression/keybrd/keybrd.ino
Normal file
150
examples/tests_regression/keybrd/keybrd.ino
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/* this works on Teensy LC 1*bb, active low and active high
|
||||||
|
MCP23018 is not working, MCP23018::begin() hangs, details in setup()
|
||||||
|
|
||||||
|
| Layout | **0** | **1** |
|
||||||
|
|:------:|-------|-------|
|
||||||
|
| **0** | a | b |
|
||||||
|
| **1** | c | d |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
//LEDs
|
||||||
|
#include <LED_PinNumber.h>
|
||||||
|
#include "classes/Code_Sc_LED.h" //symlink: ln -s ../classes classes
|
||||||
|
|
||||||
|
//IOE Ports
|
||||||
|
#include "IOExpanderPort.h"
|
||||||
|
#include <RowPort_MCP23018.h>
|
||||||
|
#include <ColPort_MCP23018.h>
|
||||||
|
|
||||||
|
//Codes
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
|
||||||
|
//Matrix
|
||||||
|
#include <Row_uC.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Row_ShiftRegisters.h>
|
||||||
|
|
||||||
|
// =============== CONFIGURATION ===============
|
||||||
|
const unsigned int RowBase::DELAY_MICROSECONDS = 500;
|
||||||
|
|
||||||
|
//activeLow has diode cathode (band) on row
|
||||||
|
//activeHigh has diode cathode (band) on col, and pull down resistors on cols
|
||||||
|
//0=active low, 1= active high
|
||||||
|
const bool RowScanner_PinsArray::activeHigh = 0;
|
||||||
|
//const bool RowScanner_PinsBitwise::activeHigh = 0;
|
||||||
|
|
||||||
|
Debug debug;
|
||||||
|
|
||||||
|
// ================ LEFT PORTS =================
|
||||||
|
uint8_t readPins[] = {14, 15};
|
||||||
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
|
LED_PinNumber LED1(16); //Teensy LC pins 16, 17 are 20 ma
|
||||||
|
|
||||||
|
// ================ RIGHT PORTS ================
|
||||||
|
/*
|
||||||
|
const uint8_t IOExpanderPort::ADDR = 0x20;
|
||||||
|
|
||||||
|
IOExpanderPort portA(0, 0);
|
||||||
|
RowPort_MCP23018 rowPort(portA);
|
||||||
|
|
||||||
|
IOExpanderPort portB(1, 0);
|
||||||
|
ColPort_MCP23018 colPort(portB, 1<<0 | 1<<1 );
|
||||||
|
*/
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
Code_Sc_LED s_d(KEY_D, LED1);
|
||||||
|
|
||||||
|
Code_Sc s_0(KEY_0);
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_2(KEY_2);
|
||||||
|
Code_Sc s_3(KEY_3);
|
||||||
|
Code_Sc s_4(KEY_4);
|
||||||
|
Code_Sc s_5(KEY_5);
|
||||||
|
Code_Sc s_6(KEY_6);
|
||||||
|
Code_Sc s_7(KEY_7);
|
||||||
|
Code_Sc s_z(KEY_Z);
|
||||||
|
|
||||||
|
// ================= LEFT ROWS =================
|
||||||
|
Key* ptrsKeys_L0[] = { &s_a, &s_b };
|
||||||
|
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_L1[] = { &s_c, &s_d };
|
||||||
|
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
||||||
|
|
||||||
|
// ================= RIGHT ROWS ================
|
||||||
|
/*
|
||||||
|
Key* ptrsKeys_R[] = { &s_0, &s_z, &s_z, &s_z,
|
||||||
|
&s_4, &s_z, &s_z, &s_z,
|
||||||
|
&s_8, &s_z, &s_z, &s_z }; //the s_z are place holders and should not print
|
||||||
|
*/
|
||||||
|
Key* ptrsKeys_R[] = { &s_0, &s_1, &s_2, &s_3,
|
||||||
|
&s_4, &s_5, &s_6, &s_7 }; //the most that 8-bit send() can handle
|
||||||
|
const uint8_t KEY_COUNT = sizeof(ptrsKeys_R)/sizeof(*ptrsKeys_R);
|
||||||
|
//Row_ShiftRegisters row_R(9, 2, ptrsKeys_R, KEY_COUNT);
|
||||||
|
Row_ShiftRegisters row_R(9, 1, ptrsKeys_R, KEY_COUNT); //1 byte
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
SPI.begin();
|
||||||
|
row_R.begin();
|
||||||
|
|
||||||
|
//delay(1000); //time for OS to detect USB before printing
|
||||||
|
Keyboard.print(F("activeState.ino "));
|
||||||
|
debug.print_free_RAM();
|
||||||
|
|
||||||
|
//Wire.begin();
|
||||||
|
/* Teensy LC on 1*bb 6/13/16 copied to: activeState_MCP23018_begin_hangs.no
|
||||||
|
RowPort_MCP23018::begin() hangs
|
||||||
|
ColPort_MCP23018::begin() sometimes hangs, sometimes prints after 6 seconds
|
||||||
|
PCA9655E::begin()s works on 4*bb
|
||||||
|
maybe hangs if IOE is not attached because endTransmission() waiting for confirmation??
|
||||||
|
|
||||||
|
trouble shooting MCP23018::begin()s
|
||||||
|
checked wiring against datasheets
|
||||||
|
measured power and ground, 3.3 volts checks out
|
||||||
|
!! next things to check could take days:
|
||||||
|
test MCP23018 with Teensy 2.0, because it worked last year
|
||||||
|
set Teensy 2.0 to 3.3 volts and test again
|
||||||
|
try with PCA9655E instead of MCP23018 (works on 4*bb)
|
||||||
|
might be solder joints on LC (I soldered it), try using other Teensy LC
|
||||||
|
test MCP23018 on simple demo sketch /home/wolfv/Documents/Arduino/demo_keep/mcp23018_../
|
||||||
|
test MCP23018 with signal analyzer
|
||||||
|
|
||||||
|
//rowPort.begin(); //this breaks sketch, does not print "activeState.ino ", kb unresponsive
|
||||||
|
//colPort.begin(RowScanner_PinsBitwise::activeHigh); //hanges for 6 seconds
|
||||||
|
Keyboard.println(F(" after Port.begin()"));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//uint16_t next = 0;
|
||||||
|
//elapsedMillis elapsed;
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
row_L0.process();
|
||||||
|
row_L1.process();
|
||||||
|
|
||||||
|
row_R.process();
|
||||||
|
|
||||||
|
//row_R0.process();
|
||||||
|
//row_R1.process();
|
||||||
|
|
||||||
|
/* used this when debugging MCP23018::begin() hangs
|
||||||
|
if ( (next < 10) && (elapsed > 1000 * next) )
|
||||||
|
{
|
||||||
|
Keyboard.print(next);
|
||||||
|
Keyboard.print(F(" "));
|
||||||
|
next++;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//delay(100);
|
||||||
|
//Keyboard.println("");
|
||||||
|
}
|
129
examples/tests_regression/keybrd/keybrd_MCP23018_begin_hangs.no
Normal file
129
examples/tests_regression/keybrd/keybrd_MCP23018_begin_hangs.no
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* this works on Teensy LC 1*bb, active low and active high
|
||||||
|
MCP23018::begin() hangs, details in setup()
|
||||||
|
|
||||||
|
| Layout | **0** | **1** |
|
||||||
|
|:------:|-------|-------|
|
||||||
|
| **0** | a | b |
|
||||||
|
| **1** | c | d |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
//IOE Ports
|
||||||
|
#include "IOExpanderPort.h"
|
||||||
|
#include <RowPort_MCP23018.h>
|
||||||
|
#include <ColPort_MCP23018.h>
|
||||||
|
|
||||||
|
//Codes
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
|
||||||
|
//Matrix
|
||||||
|
#include <Row_uC.h>
|
||||||
|
#include <Row_IOE.h>
|
||||||
|
|
||||||
|
// =============== CONFIGURATION ===============
|
||||||
|
const unsigned int RowBase::DELAY_MICROSECONDS = 500;
|
||||||
|
|
||||||
|
//activeLow has diode cathode (band) on row
|
||||||
|
//activeHigh has diode cathode (band) on col, and pull down resistors on cols
|
||||||
|
//0=active low, 1= active high
|
||||||
|
const bool RowScanner_PinsArray::activeHigh = 0;
|
||||||
|
const bool RowScanner_PinsBitwise::activeHigh = 0;
|
||||||
|
|
||||||
|
Debug debug;
|
||||||
|
|
||||||
|
// ================= uC PINS =================
|
||||||
|
uint8_t readPins[] = {14, 15};
|
||||||
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
|
// ================ IOE PORTS ================
|
||||||
|
const uint8_t IOExpanderPort::ADDR = 0x20;
|
||||||
|
|
||||||
|
IOExpanderPort portA(0, 0);
|
||||||
|
RowPort_MCP23018 rowPort(portA);
|
||||||
|
|
||||||
|
IOExpanderPort portB(1, 0);
|
||||||
|
ColPort_MCP23018 colPort(portB, 1<<0 | 1<<1 );
|
||||||
|
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
Code_Sc s_d(KEY_D);
|
||||||
|
|
||||||
|
Code_Sc s_0(KEY_0);
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_2(KEY_2);
|
||||||
|
Code_Sc s_3(KEY_3);
|
||||||
|
|
||||||
|
// ================= LEFT ROWS =================
|
||||||
|
Key* ptrsKeys_L0[] = { &s_a, &s_b };
|
||||||
|
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_L1[] = { &s_c, &s_d };
|
||||||
|
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
||||||
|
|
||||||
|
// ================= RIGHT ROWS ================
|
||||||
|
Key* ptrsKeys_R0[] = { &s_0, &s_1 };
|
||||||
|
Row_IOE row_R0(rowPort, 1<<0, colPort, ptrsKeys_R0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_R1[] = { &s_2, &s_3 };
|
||||||
|
Row_IOE row_R1(rowPort, 1<<1, colPort, ptrsKeys_R1);
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
Wire.begin(); //Wire.begin() must be called before rowPort.begin() colPort.begin()
|
||||||
|
|
||||||
|
//delay(1000); //time for OS to detect USB before printing
|
||||||
|
Keyboard.print(F("activeState.ino "));
|
||||||
|
debug.print_free_RAM();
|
||||||
|
|
||||||
|
/* Teensy LC on 1*bb
|
||||||
|
RowPort_MCP23018::begin() hangs
|
||||||
|
ColPort_MCP23018::begin() sometimes hangs, sometimes prints after 6 seconds
|
||||||
|
PCA9655E::begin()s works on 4*bb
|
||||||
|
maybe hangs if IOE is not attached because endTransmission() waiting for confirmation??
|
||||||
|
|
||||||
|
trouble shooting MCP23018::begin()s
|
||||||
|
checked wiring against datasheets
|
||||||
|
measured power and ground, 3.3 volts checks out
|
||||||
|
!! next things to check could take days:
|
||||||
|
test MCP23018 with Teensy 2.0, because it worked last year
|
||||||
|
set Teensy 2.0 to 3.3 volts and test again
|
||||||
|
try with PCA9655E instead of MCP23018 (works on 4*bb)
|
||||||
|
might be solder joints on LC (I soldered it), try using other Teensy LC
|
||||||
|
test MCP23018 on simple demo sketch /home/wolfv/Documents/Arduino/demo_keep/mcp23018_../
|
||||||
|
test MCP23018 with signal analyzer
|
||||||
|
|
||||||
|
//rowPort.begin(); //this breaks sketch, does not print "activeState.ino ", kb unresponsive
|
||||||
|
//colPort.begin(RowScanner_PinsBitwise::activeHigh); //hanges for 6 seconds
|
||||||
|
Keyboard.println(F(" after Port.begin()"));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t next = 0;
|
||||||
|
elapsedMillis elapsed;
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
row_L0.process();
|
||||||
|
row_L1.process();
|
||||||
|
|
||||||
|
//row_R0.process();
|
||||||
|
//row_R1.process();
|
||||||
|
|
||||||
|
/* used this when debugging MCP23018::begin() hangs
|
||||||
|
if ( (next < 10) && (elapsed > 1000 * next) )
|
||||||
|
{
|
||||||
|
Keyboard.print(next);
|
||||||
|
Keyboard.print(F(" "));
|
||||||
|
next++;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//delay(500);
|
||||||
|
//Keyboard.println("");
|
||||||
|
}
|
1
examples/tests_regression/keybrd_AVR/classes
Symbolic link
1
examples/tests_regression/keybrd_AVR/classes
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../classes
|
113
examples/tests_regression/keybrd_AVR/keybrd_AVR.ino
Normal file
113
examples/tests_regression/keybrd_AVR/keybrd_AVR.ino
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/* this works on DH 4*bb, top-left buttons
|
||||||
|
demo RowScanner_PinsBitwise
|
||||||
|
|
||||||
|
| Left | **0** | **1** | | Right | **0** | **1** |
|
||||||
|
|:-----:|-------|-------| |:-----:|-------|-------|
|
||||||
|
| **0** | a | b | | **0** | 0 | 1 |
|
||||||
|
| **1** | c | d | | **1** | 2 | 3 |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
//Ports
|
||||||
|
#include <RowPort_AVR_Optic.h>
|
||||||
|
#include <ColPort_AVR.h>
|
||||||
|
|
||||||
|
//LEDs
|
||||||
|
#include <LED_AVR.h>
|
||||||
|
#include <LED_PCA9655E.h>
|
||||||
|
#include "classes/Code_Sc_LED.h" //symlink: ln -s ../classes classes
|
||||||
|
|
||||||
|
//Codes
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
|
||||||
|
//Matrix
|
||||||
|
#include <Row_IOE.h>
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
// =============== CONFIGURATION ===============
|
||||||
|
const unsigned int RowBase::DELAY_MICROSECONDS = 500;
|
||||||
|
|
||||||
|
const bool RowScanner_PinsBitwise::activeHigh = 1;
|
||||||
|
|
||||||
|
Debug debug;
|
||||||
|
|
||||||
|
// ================ LEFT PORTS =================
|
||||||
|
RowPort_AVR_Optic rowPort_L(DDRF, PORTF);
|
||||||
|
ColPort_AVR colPort_L(DDRB, PORTB, PINB, 1<<0 | 1<<1 );
|
||||||
|
|
||||||
|
//LED
|
||||||
|
LED_AVR LED_L1(PORTB, 1<<6); //green
|
||||||
|
|
||||||
|
// ================ RIGHT PORTS ================
|
||||||
|
#include <IOExpanderPort.h>
|
||||||
|
#include <RowPort_PCA9655E.h>
|
||||||
|
#include <ColPort_PCA9655E.h>
|
||||||
|
|
||||||
|
const uint8_t IOExpanderPort::ADDR = 0x18;
|
||||||
|
|
||||||
|
//row port
|
||||||
|
IOExpanderPort port1(1, 0);
|
||||||
|
RowPort_PCA9655E rowPort_R(port1);
|
||||||
|
|
||||||
|
//column and pin numbers on schematic_switch_matrix.png and schematic_pca9655_pin_assignments.png
|
||||||
|
//col port
|
||||||
|
IOExpanderPort port0(0, 0);
|
||||||
|
ColPort_PCA9655E colPort_R(port0, 1<<0 | 1<<1 );
|
||||||
|
|
||||||
|
//LED
|
||||||
|
LED_PCA9655E LED_R1(port1, 1<<5); //blue
|
||||||
|
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
//Code_Sc s_d(KEY_D);
|
||||||
|
Code_Sc_LED s_d(KEY_D, LED_L1);
|
||||||
|
|
||||||
|
Code_Sc s_0(KEY_0);
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_2(KEY_2);
|
||||||
|
//Code_Sc s_3(KEY_3);
|
||||||
|
Code_Sc_LED s_3(KEY_3, LED_R1);
|
||||||
|
|
||||||
|
// ================= LEFT ROWS =================
|
||||||
|
Key* const ptrsKeys_L0[] = { &s_a, &s_b };
|
||||||
|
Row_IOE row_L0(rowPort_L, 1<<0, colPort_L, ptrsKeys_L0); //strobe F0
|
||||||
|
|
||||||
|
Key* const ptrsKeys_L1[] = { &s_c, &s_d };
|
||||||
|
Row_IOE row_L1(rowPort_L, 1<<1, colPort_L, ptrsKeys_L1); //strobe F1
|
||||||
|
|
||||||
|
// ================= RIGHT ROWS ================
|
||||||
|
Key* ptrsKeys_R0[] = { &s_0, &s_1 };
|
||||||
|
Row_IOE row_R0(rowPort_R, 1<<0, colPort_R, ptrsKeys_R0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_R1[] = { &s_2, &s_3 };
|
||||||
|
Row_IOE row_R1(rowPort_R, 1<<1, colPort_R, ptrsKeys_R1);
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
delay(1000); //time for OS to detect USB before printing
|
||||||
|
Keyboard.print(F("activeState_AVR.ino "));
|
||||||
|
debug.print_free_RAM();
|
||||||
|
|
||||||
|
rowPort_R.begin();
|
||||||
|
colPort_R.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
row_L0.process();
|
||||||
|
row_L1.process();
|
||||||
|
|
||||||
|
row_R0.process();
|
||||||
|
row_R1.process();
|
||||||
|
|
||||||
|
//delay(500);
|
||||||
|
//Keyboard.println(F(""));
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <Code.h>
|
#include <Code.h>
|
||||||
|
|
||||||
/* Class Code_Sc is composed of one scancode, which it sends when press() or release() is called.
|
/* Class Code_Sc_LED sends a scancode when press() or release() is called.
|
||||||
"S" stands for Scancode.
|
"S" stands for Scancode.
|
||||||
*/
|
*/
|
||||||
class Code_Sc : public Code
|
class Code_Sc : public Code
|
||||||
|
@ -7,14 +7,8 @@ ColPort_MCP23018::ColPort_MCP23018(IOExpanderPort& port, const uint8_t colPins)
|
|||||||
: ColPort(colPins), port(port), IODIR(port.num), GPIO(port.num + 0x12), GPPU(port.num + 0x0C)
|
: ColPort(colPins), port(port), IODIR(port.num), GPIO(port.num + 0x12), GPPU(port.num + 0x0C)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void ColPort_MCP23018::begin()
|
void ColPort_MCP23018::begin(uint8_t activeHigh)
|
||||||
{
|
{
|
||||||
//Wire.begin() should only be called once https://www.arduino.cc/en/Reference/WireBegin
|
|
||||||
#ifndef WIRE_BEGIN
|
|
||||||
#define WIRE_BEGIN
|
|
||||||
Wire.begin();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Wire.beginTransmission(port.ADDR);
|
Wire.beginTransmission(port.ADDR);
|
||||||
Wire.write(IODIR);
|
Wire.write(IODIR);
|
||||||
Wire.write(colPins); //0=configure as output (for LED), 1=configure as input (for read)
|
Wire.write(colPins); //0=configure as output (for LED), 1=configure as input (for read)
|
||||||
@ -22,7 +16,14 @@ void ColPort_MCP23018::begin()
|
|||||||
|
|
||||||
Wire.beginTransmission(port.ADDR);
|
Wire.beginTransmission(port.ADDR);
|
||||||
Wire.write(GPPU);
|
Wire.write(GPPU);
|
||||||
|
if (activeHigh)
|
||||||
|
{
|
||||||
|
Wire.write(0); //0=pull-up disabled for activeHigh //todo not tested yet
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Wire.write(colPins); //0=pull-up disabled (for LED), 1=pull-up enabled (for read)
|
Wire.write(colPins); //0=pull-up disabled (for LED), 1=pull-up enabled (for read)
|
||||||
|
}
|
||||||
Wire.endTransmission();
|
Wire.endTransmission();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class ColPort_MCP23018 : public ColPort
|
|||||||
public:
|
public:
|
||||||
//The constructor initialization list is in .cpp
|
//The constructor initialization list is in .cpp
|
||||||
ColPort_MCP23018(IOExpanderPort& port, const uint8_t colPins);
|
ColPort_MCP23018(IOExpanderPort& port, const uint8_t colPins);
|
||||||
void begin();
|
void begin(uint8_t activeHigh);
|
||||||
|
|
||||||
//read port and store result in portState
|
//read port and store result in portState
|
||||||
virtual void read();
|
virtual void read();
|
||||||
|
@ -10,12 +10,6 @@ ColPort_PCA9655E::ColPort_PCA9655E
|
|||||||
|
|
||||||
void ColPort_PCA9655E::begin()
|
void ColPort_PCA9655E::begin()
|
||||||
{
|
{
|
||||||
//Wire.begin() should only be called once https://www.arduino.cc/en/Reference/WireBegin
|
|
||||||
#ifndef WIRE_BEGIN
|
|
||||||
#define WIRE_BEGIN
|
|
||||||
Wire.begin();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Wire.beginTransmission(port.ADDR);
|
Wire.beginTransmission(port.ADDR);
|
||||||
Wire.write(configurationByteCommand);
|
Wire.write(configurationByteCommand);
|
||||||
Wire.write(colPins); //0=configure as output (for LED), 1=configure as input (for read)
|
Wire.write(colPins); //0=configure as output (for LED), 1=configure as input (for read)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "IOExpanderPort.h"
|
#include "IOExpanderPort.h"
|
||||||
|
|
||||||
/* One PCA9655E I/O expander port connected to matrix columns.
|
/* One PCA9655E I/O expander port connected to matrix columns.
|
||||||
|
PCA9655E does not have internal pull-up resistors (PCA9535E does).
|
||||||
|
|
||||||
Instantiation
|
Instantiation
|
||||||
------------
|
------------
|
||||||
|
@ -15,9 +15,7 @@ class LED_AVR: public LED
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
LED_AVR(volatile unsigned char& PORTx, const uint8_t pin): PORT(PORTx), pin(pin) {}
|
LED_AVR(volatile unsigned char& PORTx, const uint8_t pin): PORT(PORTx), pin(pin) {}
|
||||||
|
|
||||||
virtual void on();
|
virtual void on();
|
||||||
|
|
||||||
virtual void off();
|
virtual void off();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
11
src/LED_PinNumber.cpp
Normal file
11
src/LED_PinNumber.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "LED_PinNumber.h"
|
||||||
|
|
||||||
|
void LED_PinNumber::on()
|
||||||
|
{
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LED_PinNumber::off()
|
||||||
|
{
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
}
|
22
src/LED_PinNumber.h
Normal file
22
src/LED_PinNumber.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef LED_PINNUMBER_H
|
||||||
|
#define LED_PINNUMBER_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <LED.h>
|
||||||
|
|
||||||
|
/* A LED_PinNumber object is an Aduino pin that is used to power an LED on and off.
|
||||||
|
*/
|
||||||
|
class LED_PinNumber: public LED
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const uint8_t pin;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LED_PinNumber(const uint8_t pin): pin(pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
}
|
||||||
|
virtual void on();
|
||||||
|
virtual void off();
|
||||||
|
};
|
||||||
|
#endif
|
@ -21,6 +21,8 @@ This version of wait() is very simple. More sophisticated versions can override
|
|||||||
For fastest response time, wait() should be placed before scan() or after pressRelease()
|
For fastest response time, wait() should be placed before scan() or after pressRelease()
|
||||||
(waiting between strobe and send would unnecessarily delay send).
|
(waiting between strobe and send would unnecessarily delay send).
|
||||||
|
|
||||||
|
DELAY_MICROSECONDS explained
|
||||||
|
----------------------------
|
||||||
A keyboard with a faster scan rate responds faster.
|
A keyboard with a faster scan rate responds faster.
|
||||||
Follow these step to tune DELAY_MICROSECONDS for maximum scan rate for a given SAMPLE_COUNT:
|
Follow these step to tune DELAY_MICROSECONDS for maximum scan rate for a given SAMPLE_COUNT:
|
||||||
Initialize DELAY_MICROSECONDS in your sketch:
|
Initialize DELAY_MICROSECONDS in your sketch:
|
||||||
@ -58,7 +60,7 @@ void RowBase::pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged
|
|||||||
{
|
{
|
||||||
uint8_t isFallingEdge; //1 means falling edge
|
uint8_t isFallingEdge; //1 means falling edge
|
||||||
uint8_t isRisingEdge; //1 means rising edge
|
uint8_t isRisingEdge; //1 means rising edge
|
||||||
uint8_t rowMask; //bitwise, active col bit is 1
|
uint16_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
|
||||||
|
@ -9,12 +9,6 @@ RowPort_MCP23018::RowPort_MCP23018(IOExpanderPort& port)
|
|||||||
|
|
||||||
void RowPort_MCP23018::begin()
|
void RowPort_MCP23018::begin()
|
||||||
{
|
{
|
||||||
//Wire.begin() should only be called once https://www.arduino.cc/en/Reference/WireBegin
|
|
||||||
#ifndef WIRE_BEGIN
|
|
||||||
#define WIRE_BEGIN
|
|
||||||
Wire.begin();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Wire.beginTransmission(port.ADDR);
|
Wire.beginTransmission(port.ADDR);
|
||||||
Wire.write(IODIR);
|
Wire.write(IODIR);
|
||||||
Wire.write(0); //0=configure as output (for strobe pins and LED pins)
|
Wire.write(0); //0=configure as output (for strobe pins and LED pins)
|
||||||
|
@ -9,12 +9,6 @@ RowPort_PCA9655E::RowPort_PCA9655E(IOExpanderPort& port)
|
|||||||
|
|
||||||
void RowPort_PCA9655E::begin()
|
void RowPort_PCA9655E::begin()
|
||||||
{
|
{
|
||||||
//Wire.begin() should only be called once https://www.arduino.cc/en/Reference/WireBegin
|
|
||||||
#ifndef WIRE_BEGIN
|
|
||||||
#define WIRE_BEGIN
|
|
||||||
Wire.begin();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Wire.beginTransmission(port.ADDR);
|
Wire.beginTransmission(port.ADDR);
|
||||||
Wire.write(configurationByteCommand);
|
Wire.write(configurationByteCommand);
|
||||||
Wire.write(0); //0=configure as output (for strobe pins and LED)
|
Wire.write(0); //0=configure as output (for strobe pins and LED)
|
||||||
|
@ -23,6 +23,8 @@ Example instantiation for row port 1:
|
|||||||
|
|
||||||
Diode orientation
|
Diode orientation
|
||||||
----------------
|
----------------
|
||||||
|
PCA9655E does not have internal pull-up resistors, external pull-down resistors are required.
|
||||||
|
|
||||||
Rows, columns, and diode orientation are explained in Matrix.h
|
Rows, columns, and diode orientation are explained in Matrix.h
|
||||||
|
|
||||||
PCA9655E data sheet
|
PCA9655E data sheet
|
||||||
|
@ -1,11 +1,43 @@
|
|||||||
#include "RowScanner_PinsArray.h"
|
#include "RowScanner_PinsArray.h"
|
||||||
|
|
||||||
/*
|
/* constructor
|
||||||
Strobes the row and reads the columns.
|
*/
|
||||||
|
RowScanner_PinsArray::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)
|
||||||
|
{
|
||||||
|
uint8_t mode;
|
||||||
|
|
||||||
|
//configure row
|
||||||
|
pinMode(strobePin, OUTPUT);
|
||||||
|
|
||||||
|
if (activeHigh)
|
||||||
|
{
|
||||||
|
mode = INPUT; //requires external pull-down resistor
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode = INPUT_PULLUP; //uses internal pull-up resistor
|
||||||
|
}
|
||||||
|
|
||||||
|
//configure cols
|
||||||
|
for (uint8_t i=0; i < READ_PIN_COUNT; i++)
|
||||||
|
{
|
||||||
|
pinMode(readPins[i], mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scan() Strobes the row and reads the columns.
|
||||||
Sets rowEnd and returns rowState.
|
Sets rowEnd and returns rowState.
|
||||||
rowEnd is a bitwise row mask, one col per bit, where active col bit is 1.
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
*/
|
*/
|
||||||
uint8_t RowScanner_PinsArray::scan(uint16_t& rowEnd)
|
uint8_t RowScanner_PinsArray::scan(uint16_t& rowEnd)
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <RowPort.h>
|
#include <RowPort.h>
|
||||||
#include <ColPort.h>
|
#include <ColPort.h>
|
||||||
|
|
||||||
/* RowScanner_PinsArray class uses Arduino pin numbers (no port name).
|
/* RowScanner_PinsArray class uses Arduino pin numbers (not port pin numbers).
|
||||||
*/
|
*/
|
||||||
class RowScanner_PinsArray : public RowScannerInterface
|
class RowScanner_PinsArray : public RowScannerInterface
|
||||||
{
|
{
|
||||||
@ -17,18 +17,7 @@ class RowScanner_PinsArray : public RowScannerInterface
|
|||||||
const uint8_t READ_PIN_COUNT; //number of read pins
|
const uint8_t READ_PIN_COUNT; //number of read pins
|
||||||
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);
|
||||||
: strobePin(strobePin), readPins(readPins), READ_PIN_COUNT(READ_PIN_COUNT)
|
|
||||||
{
|
|
||||||
//row
|
|
||||||
pinMode(strobePin, OUTPUT);
|
|
||||||
|
|
||||||
//cols
|
|
||||||
for (uint8_t i=0; i < READ_PIN_COUNT; i++)
|
|
||||||
{
|
|
||||||
pinMode(readPins[i], INPUT_PULLUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual uint8_t scan(uint16_t& rowEnd);
|
virtual uint8_t scan(uint16_t& rowEnd);
|
||||||
uint8_t getRowState(uint16_t& rowEnd);
|
uint8_t getRowState(uint16_t& rowEnd);
|
||||||
};
|
};
|
||||||
|
@ -69,7 +69,6 @@ uint8_t RowScanner_PinsBitwise::getRowState(uint16_t& rowEnd)
|
|||||||
rowEnd <<= 1; //shift rowEnd to next key
|
rowEnd <<= 1; //shift rowEnd to next key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//todo Keyboard.print(rowState);
|
|
||||||
|
|
||||||
return rowState;
|
return rowState;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
class RowScanner_PinsBitwise : public RowScannerInterface
|
class RowScanner_PinsBitwise : public RowScannerInterface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh
|
|
||||||
RowPort& refRowPort; //this row's IC port
|
RowPort& refRowPort; //this row's IC port
|
||||||
const uint8_t strobePin; //bitwise, 1 indicates IC pin connected to this row
|
const uint8_t strobePin; //bitwise, 1 indicates IC pin connected to this row
|
||||||
ColPort& refColPort;
|
ColPort& refColPort;
|
||||||
@ -20,6 +19,7 @@ class RowScanner_PinsBitwise : public RowScannerInterface
|
|||||||
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
|
||||||
virtual uint8_t scan(uint16_t& rowEnd);
|
virtual uint8_t scan(uint16_t& rowEnd);
|
||||||
uint8_t getRowState(uint16_t& rowEnd);
|
uint8_t getRowState(uint16_t& rowEnd);
|
||||||
};
|
};
|
||||||
|
23
src/RowScanner_SPIShiftRegisters.cpp
Normal file
23
src/RowScanner_SPIShiftRegisters.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "RowScanner_SPIShiftRegisters.h"
|
||||||
|
|
||||||
|
void RowScanner_SPIShiftRegisters::begin()
|
||||||
|
{
|
||||||
|
pinMode (SS, OUTPUT);
|
||||||
|
digitalWrite (SS, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets rowEnd and returns rowState.
|
||||||
|
*/
|
||||||
|
uint8_t RowScanner_SPIShiftRegisters::scan(uint16_t& rowEnd)
|
||||||
|
{
|
||||||
|
//todo rowEnd, rowState, return int size depend on BYTE_COUNT, like in send()
|
||||||
|
uint8_t rowState;
|
||||||
|
|
||||||
|
digitalWrite(SS, LOW);
|
||||||
|
digitalWrite(SS, HIGH);
|
||||||
|
SPI.transfer(&rowState, BYTE_COUNT);
|
||||||
|
rowEnd = 1 << KEY_COUNT;
|
||||||
|
return rowState;
|
||||||
|
}
|
||||||
|
|
25
src/RowScanner_SPIShiftRegisters.h
Normal file
25
src/RowScanner_SPIShiftRegisters.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef ROWSCANNER_SPI_SHIFTREGISTERS_H
|
||||||
|
#define ROWSCANNER_SPI_SHIFTREGISTERS_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <RowScannerInterface.h>
|
||||||
|
#include <RowPort.h>
|
||||||
|
#include <ColPort.h>
|
||||||
|
|
||||||
|
/* RowScanner_SPIShiftRegisters reads all shift registers in a daisy chain.
|
||||||
|
//todo delete: Assumes only one row of shift registers is connected (no Slave Select).
|
||||||
|
*/
|
||||||
|
class RowScanner_SPIShiftRegisters : public RowScannerInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const uint8_t SS; //Slave Select, pin on master
|
||||||
|
const uint8_t BYTE_COUNT; //number of shift registers
|
||||||
|
const uint8_t KEY_COUNT; //number of keys in row
|
||||||
|
public:
|
||||||
|
RowScanner_SPIShiftRegisters(const uint8_t SS, uint8_t BYTE_COUNT, uint16_t KEY_COUNT)
|
||||||
|
: SS(SS), BYTE_COUNT(BYTE_COUNT), KEY_COUNT(KEY_COUNT) {}
|
||||||
|
virtual uint8_t scan(uint16_t& rowEnd);
|
||||||
|
void begin();
|
||||||
|
};
|
||||||
|
#endif
|
@ -7,13 +7,15 @@
|
|||||||
|
|
||||||
/* Row_DH_IOE is a row connected to an Input/Output Expander.
|
/* Row_DH_IOE is a row connected to an Input/Output Expander.
|
||||||
|
|
||||||
Configuration
|
|
||||||
-------------
|
|
||||||
Define and initilize DELAY_MICROSECONDS in sketch. Detailed how to is in RowBase.cpp.
|
|
||||||
|
|
||||||
Instantiation
|
Instantiation
|
||||||
-------------
|
-------------
|
||||||
|
Definition of DELAY_MICROSECONDS is explained in RowBase.cpp.
|
||||||
|
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 bool RowScanner_PinsArray::activeHigh = 0;
|
||||||
|
|
||||||
const uint8_t IOExpanderPort::ADDR = 0x18;
|
const uint8_t IOExpanderPort::ADDR = 0x18;
|
||||||
|
|
||||||
IOExpanderPort port1(1, 0);
|
IOExpanderPort port1(1, 0);
|
||||||
|
16
src/Row_ShiftRegisters.cpp
Normal file
16
src/Row_ShiftRegisters.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "Row_ShiftRegisters.h"
|
||||||
|
|
||||||
|
void Row_ShiftRegisters::begin()
|
||||||
|
{
|
||||||
|
scanner.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Row_ShiftRegisters::scan(uint16_t& rowEnd)
|
||||||
|
{
|
||||||
|
return scanner.scan(rowEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Row_ShiftRegisters::debounce(const uint8_t rowState, uint8_t& debounced)
|
||||||
|
{
|
||||||
|
return debouncer.debounce(rowState, debounced);
|
||||||
|
}
|
38
src/Row_ShiftRegisters.h
Normal file
38
src/Row_ShiftRegisters.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef ROW_SHIFTREGISTERS_H
|
||||||
|
#define ROW_SHIFTREGISTERS_H
|
||||||
|
|
||||||
|
#include <RowBase.h>
|
||||||
|
#include <RowScanner_SPIShiftRegisters.h>
|
||||||
|
#include <Debouncer_4Samples.h>
|
||||||
|
|
||||||
|
/* Row_DH_IOE is a row connected to an Input/Output Expander.
|
||||||
|
|
||||||
|
Instantiation
|
||||||
|
-------------
|
||||||
|
Definition of DELAY_MICROSECONDS is explained in RowBase.cpp.
|
||||||
|
Example instantiation of a row:
|
||||||
|
|
||||||
|
const unsigned int RowBase::DELAY_MICROSECONDS = 1000;
|
||||||
|
|
||||||
|
todo
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
class Row_ShiftRegisters : public RowBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
RowScanner_SPIShiftRegisters scanner;
|
||||||
|
Debouncer_4Samples debouncer;
|
||||||
|
public:
|
||||||
|
Row_ShiftRegisters(const uint8_t SS, uint8_t BYTE_COUNT, Key *const ptrsKeys[], uint16_t KEY_COUNT)
|
||||||
|
: RowBase(ptrsKeys), scanner(SS, BYTE_COUNT, KEY_COUNT) { }
|
||||||
|
void begin();
|
||||||
|
uint8_t scan(uint16_t& rowEnd);
|
||||||
|
uint8_t debounce(const uint8_t rowState, uint8_t& debounced);
|
||||||
|
};
|
||||||
|
#endif
|
@ -6,14 +6,16 @@
|
|||||||
#include <Debouncer_4Samples.h>
|
#include <Debouncer_4Samples.h>
|
||||||
|
|
||||||
/* Row_uC is a row connected to a micro controller.
|
/* Row_uC is a row connected to a micro controller.
|
||||||
Configuration
|
|
||||||
-------------
|
|
||||||
Define and initilize DELAY_MICROSECONDS in sketch. Detailed how to is in RowBase.cpp.
|
|
||||||
|
|
||||||
Instantiation
|
Instantiation
|
||||||
-------------
|
-------------
|
||||||
|
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 bool RowScanner_PinsArray::activeHigh = 0;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
Binary file not shown.
@ -7,7 +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.
|
||||||
Electronics are fickle, and you won't get everything right the first time.
|
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
|
||||||
@ -22,12 +23,13 @@ Breadboard keyboards are useful for:
|
|||||||
## Breadboard keyboard starter kit
|
## Breadboard keyboard starter kit
|
||||||
The parts needed to build all the tutorial Breadboard Keyboards are listed in [breadboard_keyboard_supplies.ods](breadboard_keyboard_supplies.ods).
|
The parts needed to build all the tutorial Breadboard Keyboards are listed in [breadboard_keyboard_supplies.ods](breadboard_keyboard_supplies.ods).
|
||||||
|
|
||||||
Wire cutters (or nail clipper) is the only required tool.
|
You will need two tools:
|
||||||
A multi-meter is useful for trouble shooting.
|
* Wire cutters (or nail clipper)
|
||||||
|
* A multi-meter for trouble shooting
|
||||||
|
|
||||||
## How a breadboard works
|
## How a breadboard works
|
||||||
To understand the breadboard keyboard you will need to know the internal parts of a breadboard:
|
To understand the breadboard keyboard you will need to know the internal parts of a breadboard:
|
||||||
* power rail
|
* bus strip
|
||||||
* terminal strip
|
* terminal strip
|
||||||
|
|
||||||
These are explained in [How to Use a Breadboard](https://learn.sparkfun.com/tutorials/how-to-use-a-breadboard)
|
These are explained in [How to Use a Breadboard](https://learn.sparkfun.com/tutorials/how-to-use-a-breadboard)
|
||||||
@ -42,7 +44,7 @@ The basic breadboard has 4 switches and a microcontroller.
|
|||||||
![breadboard keyboard with 2 rows and 2 columns](images/breadboard_keyboard_2x2_labeled.jpg "2x2 breadboard keyboard")
|
![breadboard keyboard with 2 rows and 2 columns](images/breadboard_keyboard_2x2_labeled.jpg "2x2 breadboard keyboard")
|
||||||
|
|
||||||
The key matrix has two rows and two columns.
|
The key matrix has two rows and two columns.
|
||||||
Breadboard power rails are repurposed as matrix rows.
|
Breadboard bus strips are used as matrix rows.
|
||||||
Short bare wires connect terminal strips into matrix columns.
|
Short bare wires connect terminal strips into matrix columns.
|
||||||
Switch-diode pairs connect rows to columns.
|
Switch-diode pairs connect rows to columns.
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ Breadboard keyboard assembly instructions:
|
|||||||
* Teensy LC on the terminal strip labeled 1
|
* Teensy LC on the terminal strip labeled 1
|
||||||
* switch leads oriented so that they will connect diodes to columns
|
* switch leads oriented so that they will connect diodes to columns
|
||||||
* diode cut offs connect terminal strips into columns
|
* diode cut offs connect terminal strips into columns
|
||||||
* diodes are orient with cathode (banded end) towards the row (power strip)
|
* diodes are orient with cathode (banded end) towards the row (bus strip)
|
||||||
3. Insert jumper wires connecting Teensy2 to the matrix rows and columns.
|
3. Insert jumper wires connecting Teensy2 to the matrix rows and columns.
|
||||||
* follow pin connections table (below) and consult pinout diagram in
|
* follow pin connections table (below) and consult pinout diagram in
|
||||||
[close-up pic shows switch way half out, to show lead orientation]
|
[close-up pic shows switch way half out, to show lead orientation]
|
||||||
|
@ -6,10 +6,8 @@ When you finish this tutorial you will be able to be able to modify a 2-matrix k
|
|||||||
The breadboard in this picture models a split keyboard.
|
The breadboard in this picture models a split keyboard.
|
||||||
![breadboard keyboard with 2 rows and 4 columns of keys](images/breadboard_keyboard_2x5_labeled.jpg "2x5 breadboard keyboard")
|
![breadboard keyboard with 2 rows and 4 columns of keys](images/breadboard_keyboard_2x5_labeled.jpg "2x5 breadboard keyboard")
|
||||||
|
|
||||||
There is a total of 4 matrix rows, each on a breadboard power rail.
|
The breadboard has four bus strips used as rows.
|
||||||
|
Two rows connected to a microcontroller, and two rows connected to a I/O expander.
|
||||||
The right matrix is connected to a microcontroller.
|
|
||||||
The left matrix is connected to a I/O expander.
|
|
||||||
|
|
||||||
The I/O expander has a small notch on one end, which identifies the end with pin 1.
|
The I/O expander has a small notch on one end, which identifies the end with pin 1.
|
||||||
In the picture, pin 1 is on the right end.
|
In the picture, pin 1 is on the right end.
|
||||||
|
Reference in New Issue
Block a user