add strobe off to RowScanner_SPIShiftRegisters::scan(), add keybrd/examples/keybrd_shift_register
This commit is contained in:
parent
1eb09df387
commit
f792c710bb
161
examples/keybrd_shift_register/keybrd_shift_reg.ino
Normal file
161
examples/keybrd_shift_register/keybrd_shift_reg.ino
Normal file
@ -0,0 +1,161 @@
|
||||
/* keybrd_shift_reg.ino
|
||||
this works on Teensy LC 1*bb, active low and active high
|
||||
|
||||
| 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 <SPI.h>
|
||||
#include <Row_ShiftRegisters.h>
|
||||
|
||||
// =============== CONFIGURATION ===============
|
||||
const unsigned int RowBase::DELAY_MICROSECONDS = 500; //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::ACTIVE_HIGH = 0;
|
||||
|
||||
Debug debug;
|
||||
|
||||
// ================= LEFT PINS =================
|
||||
uint8_t readPins[] = {14, 15};
|
||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
// =================== 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_e(KEY_E);
|
||||
Code_Sc s_f(KEY_F);
|
||||
Code_Sc s_g(KEY_G);
|
||||
Code_Sc s_h(KEY_H);
|
||||
Code_Sc s_i(KEY_I);
|
||||
|
||||
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_8(KEY_8);
|
||||
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 ================
|
||||
//typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h
|
||||
//Row_ShiftRegisters(STROBE_PIN, SHIFT_LOAD, ptrsKeys[], KEY_COUNT)
|
||||
//the s_z are place holders and should not print
|
||||
/*
|
||||
//BYTE_COUNT 1, prints 0 1
|
||||
Key* ptrsKeys_R0[] = { &s_0, &s_a, &s_b, &s_c, &s_1, &s_d, &s_e, &s_f };
|
||||
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, 10, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
*/
|
||||
/*
|
||||
//prints 0 1 2
|
||||
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 };
|
||||
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, 10, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
*/
|
||||
/*
|
||||
//prints 0 1 2 3
|
||||
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 };
|
||||
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, 10, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
*/
|
||||
/*
|
||||
//prints 0 1 2 3 4 5
|
||||
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_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z };
|
||||
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, 10, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
*/
|
||||
|
||||
//prints 0 1 2 3 4 5 6 7 8
|
||||
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_4, &s_z, &s_z, &s_z, &s_5, &s_z, &s_z, &s_z,
|
||||
&s_6, &s_z, &s_z, &s_z, &s_7, &s_z, &s_8 }; //31-key limit because endRow
|
||||
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, 10, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
|
||||
//unresponsive
|
||||
Key* ptrsKeys_R1[] = { &s_a, &s_z, &s_z, &s_z, &s_b, &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_g, &s_z, &s_z, &s_z, &s_h, &s_z, &s_i }; //31-key limit because endRow
|
||||
const uint8_t KEY_R1_COUNT = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
|
||||
Row_ShiftRegisters row_R1(9, 10, ptrsKeys_R1, KEY_R1_COUNT);
|
||||
|
||||
const uint8_t LED_PIN = 16; //indicates wait
|
||||
|
||||
//sometimes OS takes 6 seconds to recongnize keyboard, LED blinks from the begining
|
||||
void wait()
|
||||
{
|
||||
for (uint8_t count = 0; count < 6; count++)
|
||||
{
|
||||
//print count
|
||||
Keyboard.print(count);
|
||||
Keyboard.print(F(" "));
|
||||
|
||||
//blink LED
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(900);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
||||
{
|
||||
pinMode (LED_PIN, OUTPUT);
|
||||
Keyboard.begin();
|
||||
SPI.begin();
|
||||
|
||||
wait();
|
||||
row_R0.begin();
|
||||
row_R1.begin();
|
||||
Keyboard.print(F("keybrd_shift_reg.ino "));
|
||||
debug.print_free_RAM();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
row_L0.process();
|
||||
row_L1.process();
|
||||
|
||||
row_R0.process();
|
||||
row_R1.process();
|
||||
|
||||
//delay(100);
|
||||
//Keyboard.println("");
|
||||
//debug.print_microseconds_per_scan();
|
||||
}
|
136
examples/keybrd_shift_register/keybrd_shift_reg_works1.no
Normal file
136
examples/keybrd_shift_register/keybrd_shift_reg_works1.no
Normal file
@ -0,0 +1,136 @@
|
||||
/* this works on Teensy LC 1*bb, active low and active high
|
||||
|
||||
| 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 <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;
|
||||
|
||||
Debug debug;
|
||||
|
||||
// ================ LEFT PORTS =================
|
||||
uint8_t readPins[] = {14, 15};
|
||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
// =================== 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);
|
||||
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_8(KEY_8);
|
||||
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 ================
|
||||
// typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h
|
||||
|
||||
/*
|
||||
//prints 0 4
|
||||
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, 1, ptrsKeys_R, KEY_COUNT); // (SS, BYTE_COUNT,,)
|
||||
*/
|
||||
/*
|
||||
//prints 0 4 8
|
||||
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
|
||||
const uint8_t KEY_COUNT = sizeof(ptrsKeys_R)/sizeof(*ptrsKeys_R);
|
||||
Row_ShiftRegisters row_R(9, 2, ptrsKeys_R, KEY_COUNT);
|
||||
*/
|
||||
|
||||
//prints 0 4 8 c
|
||||
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,
|
||||
&s_c, &s_z, &s_z, &s_z }; //the s_z are place holders and should not print
|
||||
const uint8_t KEY_COUNT = sizeof(ptrsKeys_R)/sizeof(*ptrsKeys_R);
|
||||
Row_ShiftRegisters row_R(9, 2, ptrsKeys_R, KEY_COUNT);
|
||||
|
||||
const uint8_t LED_PIN = 16;
|
||||
|
||||
void wait()
|
||||
{
|
||||
static uint8_t count = 0;
|
||||
|
||||
//print count
|
||||
Keyboard.print(count);
|
||||
Keyboard.print(F(" "));
|
||||
count++;
|
||||
|
||||
//blink LED
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(900);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
delay(100);
|
||||
}
|
||||
// ################### MAIN ####################
|
||||
void setup()
|
||||
{
|
||||
pinMode (LED_PIN, OUTPUT);
|
||||
Keyboard.begin();
|
||||
wait(); //0
|
||||
SPI.begin();
|
||||
wait(); //1
|
||||
row_R.begin();
|
||||
wait(); //2
|
||||
wait(); //3
|
||||
wait(); //4
|
||||
wait(); //5 sometimes OS takes 6 seconds to recongnize keyboard, LED blinks from the begining
|
||||
Keyboard.print(F("keybrd_shift_reg.ino "));
|
||||
debug.print_free_RAM();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
row_L0.process();
|
||||
row_L1.process();
|
||||
|
||||
row_R.process();
|
||||
|
||||
//row_R0.process();
|
||||
//row_R1.process();
|
||||
|
||||
//delay(100);
|
||||
//Keyboard.println("");
|
||||
}
|
@ -5,9 +5,9 @@ void RowScanner_SPIShiftRegisters::begin()
|
||||
//configure row
|
||||
pinMode(STROBE_PIN, OUTPUT);
|
||||
|
||||
//todo there is only one slave, is select needed?
|
||||
pinMode (SHIFT_LOAD, OUTPUT);
|
||||
digitalWrite (SHIFT_LOAD, HIGH);
|
||||
//initialize shift register's shift/load pin
|
||||
pinMode(SHIFT_LOAD, OUTPUT);
|
||||
digitalWrite(SHIFT_LOAD, HIGH);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -18,18 +18,27 @@ read_pins_t RowScanner_SPIShiftRegisters::scan(read_pins_mask_t& rowEnd)
|
||||
read_pins_t rowState = 0;
|
||||
|
||||
//strobe row on
|
||||
digitalWrite(STROBE_PIN, LOW);
|
||||
digitalWrite(STROBE_PIN, HIGH);
|
||||
delayMicroseconds(3); //time to stablize voltage
|
||||
|
||||
//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
|
||||
digitalWrite(SHIFT_LOAD, LOW); //load parallel inputs to the register
|
||||
digitalWrite(SHIFT_LOAD, HIGH); //shift the data toward a serial output
|
||||
SPI.transfer(&rowState, BYTE_COUNT);
|
||||
|
||||
//strobe row off
|
||||
digitalWrite(STROBE_PIN, HIGH);
|
||||
digitalWrite(STROBE_PIN, LOW);
|
||||
|
||||
rowEnd = 1 << KEY_COUNT;
|
||||
|
||||
//clear unpowered pins (for testing bb) todo
|
||||
if (BYTE_COUNT == 1) rowState &= 0b00010001;
|
||||
if (BYTE_COUNT == 2) rowState &= 0b0001000100010001;
|
||||
if (BYTE_COUNT == 3) rowState &= 0b000100010001000100010001;
|
||||
if (BYTE_COUNT == 4) rowState &= 0b01010001000100010001000100010001; //also 31st key
|
||||
|
||||
//Keyboard.print(" ");//todo
|
||||
//Keyboard.print(rowState); //why does rowState change to 1 for both rows? (row pin 8 is unplugged)
|
||||
return rowState;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,22 @@
|
||||
/* RowScanner_SPIShiftRegisters reads all shift registers in a daisy chain.
|
||||
The maximum keys per row is 31, because Arduino's largest type is 32 bits and rowEnd consumes the last bit.
|
||||
//todo delete: Assumes only one row of shift registers is connected (no Slave Select).
|
||||
|
||||
For active low:
|
||||
10k pull-up resistor are connected to power
|
||||
connect controller's MISO pin to shift register's /QH pin
|
||||
in sketch, const bool RowScanner_PinsArray::ACTIVE_HIGH = 0;
|
||||
|
||||
For active high:
|
||||
10k pull-down resistors are grounded
|
||||
connect controller's MISO pin to shift register's QH pin
|
||||
in sketch, const bool RowScanner_PinsArray::ACTIVE_HIGH = 1;
|
||||
|
||||
shift registers 74HC165 Parallel-In-Serial-Out (PISO) are Daisy chained
|
||||
|
||||
The maximum keys per row is 31, because Arduino's largest type is 32 bits and rowEnd consumes the last bit.
|
||||
call begin() from setup()
|
||||
|
||||
*/
|
||||
class RowScanner_SPIShiftRegisters : public RowScannerInterface
|
||||
{
|
||||
@ -17,13 +33,13 @@ class RowScanner_SPIShiftRegisters : public RowScannerInterface
|
||||
//todo static const bool ACTIVE_HIGH; //logic level of strobe pin: 0=activeLow, 1=activeHigh
|
||||
const uint8_t STROBE_PIN; //Arduino pin number connected to this row
|
||||
const uint8_t SHIFT_LOAD; //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 KEY_COUNT; //number of keys in row
|
||||
const uint8_t BYTE_COUNT; //number of bytes to read from shift registers
|
||||
public:
|
||||
RowScanner_SPIShiftRegisters(const uint8_t STROBE_PIN, const uint8_t SHIFT_LOAD,
|
||||
uint8_t BYTE_COUNT, uint8_t KEY_COUNT)
|
||||
uint8_t KEY_COUNT)
|
||||
: STROBE_PIN(STROBE_PIN), SHIFT_LOAD(SHIFT_LOAD),
|
||||
BYTE_COUNT(BYTE_COUNT), KEY_COUNT(KEY_COUNT) {}
|
||||
KEY_COUNT(KEY_COUNT), BYTE_COUNT(ceil (float(KEY_COUNT)/8)) {}
|
||||
virtual read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||
void begin();
|
||||
};
|
||||
|
@ -31,9 +31,9 @@ class Row_ShiftRegisters : public RowBase
|
||||
Debouncer_4Samples debouncer;
|
||||
//Debouncer_Not debouncer; //todo test
|
||||
public:
|
||||
Row_ShiftRegisters(const uint8_t STROBE_PIN, const uint8_t SHIFT_LOAD, uint8_t BYTE_COUNT,
|
||||
Row_ShiftRegisters(const uint8_t STROBE_PIN, const uint8_t SHIFT_LOAD,
|
||||
Key *const ptrsKeys[], uint8_t KEY_COUNT)
|
||||
: RowBase(ptrsKeys), scanner(STROBE_PIN, SHIFT_LOAD, BYTE_COUNT, KEY_COUNT) { }
|
||||
: RowBase(ptrsKeys), scanner(STROBE_PIN, SHIFT_LOAD, KEY_COUNT) { }
|
||||
void begin();
|
||||
read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||
read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced);
|
||||
|
Reference in New Issue
Block a user