Archived
1
0

add strobe off to RowScanner_SPIShiftRegisters::scan(), add keybrd/examples/keybrd_shift_register

This commit is contained in:
wolfv6 2016-07-02 01:54:57 -06:00
parent 1eb09df387
commit f792c710bb
5 changed files with 334 additions and 12 deletions

View 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();
}

View 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("");
}

View File

@ -5,9 +5,9 @@ void RowScanner_SPIShiftRegisters::begin()
//configure row //configure row
pinMode(STROBE_PIN, OUTPUT); pinMode(STROBE_PIN, OUTPUT);
//todo there is only one slave, is select needed? //initialize shift register's shift/load pin
pinMode (SHIFT_LOAD, OUTPUT); pinMode(SHIFT_LOAD, OUTPUT);
digitalWrite (SHIFT_LOAD, HIGH); digitalWrite(SHIFT_LOAD, HIGH);
} }
/* /*
@ -18,18 +18,27 @@ read_pins_t RowScanner_SPIShiftRegisters::scan(read_pins_mask_t& rowEnd)
read_pins_t rowState = 0; read_pins_t rowState = 0;
//strobe row on //strobe row on
digitalWrite(STROBE_PIN, LOW); digitalWrite(STROBE_PIN, HIGH);
delayMicroseconds(3); //time to stablize voltage delayMicroseconds(3); //time to stablize voltage
//read all the column pins //read all the column pins
digitalWrite(SHIFT_LOAD, LOW); //load parallel inputs to the register digitalWrite(SHIFT_LOAD, LOW); //load parallel inputs to the register
digitalWrite(SHIFT_LOAD, HIGH); //shift the data toward a serial output digitalWrite(SHIFT_LOAD, HIGH); //shift the data toward a serial output
SPI.transfer(&rowState, BYTE_COUNT); SPI.transfer(&rowState, BYTE_COUNT);
//strobe row off //strobe row off
digitalWrite(STROBE_PIN, HIGH); digitalWrite(STROBE_PIN, LOW);
rowEnd = 1 << KEY_COUNT; 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; return rowState;
} }

View File

@ -10,6 +10,22 @@
/* RowScanner_SPIShiftRegisters reads all shift registers in a daisy chain. /* 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. 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). //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 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 //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 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 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 KEY_COUNT; //number of keys in row
const uint8_t BYTE_COUNT; //number of bytes to read from shift registers
public: public:
RowScanner_SPIShiftRegisters(const uint8_t STROBE_PIN, const uint8_t SHIFT_LOAD, 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), : 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); virtual read_pins_t scan(read_pins_mask_t& rowEnd);
void begin(); void begin();
}; };

View File

@ -31,9 +31,9 @@ class Row_ShiftRegisters : public RowBase
Debouncer_4Samples debouncer; Debouncer_4Samples debouncer;
//Debouncer_Not debouncer; //todo test //Debouncer_Not debouncer; //todo test
public: 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) 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(); void begin();
read_pins_t scan(read_pins_mask_t& rowEnd); read_pins_t scan(read_pins_mask_t& rowEnd);
read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced); read_pins_t debounce(const read_pins_t rowState, read_pins_t& debounced);