replace rowEnd with KEY_COUNT, remove read_pins_mask_t, print_free_RAM()
This commit is contained in:
parent
0923f72d39
commit
a725a74831
@ -5,21 +5,23 @@ The keyboard hardware for this sketch has 4 shift registers,
|
||||
with every 4th input pin connected to a pull-down resistor and matrix column, also the 31st key.
|
||||
Unused input pins are not grounded, so add this line to RowScanner_SPIShiftRegisters::scan():
|
||||
//clear unpowered pins (for testing on breadboard)
|
||||
rowState &= 0b01010001000100010001000100010001;
|
||||
rowState &= 0b11110001000100010001000100010001; //todo
|
||||
|
||||
Layout
|
||||
| Left |**0**|**1**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**|**8**|
|
||||
|:-----:|-----|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
| **0** | a | b | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
| **1** | c | d | | **1** | a | b | c | d | e | f | g | h | i |
|
||||
| Left | **0**|**1**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**|**8**|
|
||||
|:-----:|------|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
| **0** |capLck| a | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
| **1** | b | c | | **1** | a | b | c | d | e | f | g | h | i |
|
||||
*/
|
||||
// ################## GLOBAL ###################
|
||||
// ================= INCLUDES ==================
|
||||
#include <Debug.h>
|
||||
#include <ScanDelay.h>
|
||||
#include <LED_PinNumber.h>
|
||||
|
||||
//Codes
|
||||
#include <Code_Sc.h>
|
||||
#include <Code_LEDLock.h>
|
||||
|
||||
//Matrix
|
||||
#include <Row_uC.h>
|
||||
@ -35,8 +37,27 @@ Debug debug;
|
||||
|
||||
// ================= LEFT PINS =================
|
||||
uint8_t readPins[] = {14, 15};
|
||||
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
uint8_t KEY_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||
|
||||
// ==================== LEDs ===================
|
||||
LED_PinNumber LED1(16);
|
||||
|
||||
//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
|
||||
LED1.on();
|
||||
delay(500);
|
||||
LED1.off();
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
// =================== CODES ===================
|
||||
Code_Sc s_a(KEY_A);
|
||||
Code_Sc s_b(KEY_B);
|
||||
@ -48,6 +69,13 @@ Code_Sc s_g(KEY_G);
|
||||
Code_Sc s_h(KEY_H);
|
||||
Code_Sc s_i(KEY_I);
|
||||
|
||||
Code_Sc s_u(KEY_U);
|
||||
Code_Sc s_v(KEY_V);
|
||||
Code_Sc s_w(KEY_W);
|
||||
Code_Sc s_x(KEY_X);
|
||||
|
||||
Code_Sc s_z(KEY_Z);
|
||||
|
||||
Code_Sc s_0(KEY_0);
|
||||
Code_Sc s_1(KEY_1);
|
||||
Code_Sc s_2(KEY_2);
|
||||
@ -57,14 +85,15 @@ 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);
|
||||
|
||||
Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED1);
|
||||
|
||||
// ================= LEFT ROWS =================
|
||||
Key* ptrsKeys_L0[] = { &s_a, &s_b };
|
||||
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
||||
Key* ptrsKeys_L0[] = { &o_capsLock, &s_a };
|
||||
Row_uC row_L0(0, readPins, ptrsKeys_L0, KEY_COUNT);
|
||||
|
||||
Key* ptrsKeys_L1[] = { &s_c, &s_d };
|
||||
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
||||
Key* ptrsKeys_L1[] = { &s_b, &s_c };
|
||||
Row_uC row_L1(1, readPins, ptrsKeys_L1, KEY_COUNT);
|
||||
|
||||
// ================= RIGHT ROWS ================
|
||||
//typedef should be large in /home/wolfv/Documents/Arduino/keybrd_proj/keybrd/src/config_keybrd.h
|
||||
@ -105,44 +134,25 @@ const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
*/
|
||||
|
||||
//prints 0 1 2 3 4 5 6 7 8, microseconds_per_scan=87 with SAMPLE_COUNT 4
|
||||
//prints 0 1 2 3 3 4 5 6, microseconds_per_scan=87 with SAMPLE_COUNT 4
|
||||
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
|
||||
&s_6, &s_z, &s_z, &s_z, &s_3, &s_4, &s_5, &s_6 };
|
||||
const uint8_t KEY_R0_COUNT = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||
Row_ShiftRegisters row_R0(8, ptrsKeys_R0, KEY_R0_COUNT);
|
||||
|
||||
//prints a b c d e f g h i
|
||||
//prints a b c d u v w x
|
||||
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
|
||||
&s_g, &s_z, &s_z, &s_z, &s_u, &s_v, &s_w, &s_x };
|
||||
const uint8_t KEY_R1_COUNT = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
|
||||
Row_ShiftRegisters row_R1(9, 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();
|
||||
|
||||
wait();
|
||||
@ -150,8 +160,7 @@ void setup()
|
||||
row_R0.begin();
|
||||
row_R1.begin();
|
||||
|
||||
Keyboard.print(F("keybrd_shift_reg.ino "));
|
||||
debug.print_free_RAM();
|
||||
Keyboard.println(F("keybrd_shift_reg.ino"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
@ -59,7 +59,7 @@ This debug code prints "keyboard_leds=0" when scrollLock is pressed:
|
||||
*/
|
||||
if (keyboard_leds & USB_LED_bit) //if USB_LED_bit is set
|
||||
{
|
||||
refLED.off(); //LED on-off seem inverted, but it works for active high
|
||||
refLED.off(); //LED on-off seem inverted, but it works for active low and active high
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3,8 +3,7 @@
|
||||
/*
|
||||
configures column port's configuration, input, and pins.
|
||||
*/
|
||||
ColPort_PCA9655E::ColPort_PCA9655E
|
||||
(IOExpanderPort& port, const uint8_t colPins)
|
||||
ColPort_PCA9655E::ColPort_PCA9655E (IOExpanderPort& port, const uint8_t colPins)
|
||||
: ColPort(colPins), port(port), configurationByteCommand(port.num + 6), inputByteCommand(port.num)
|
||||
{}
|
||||
|
||||
|
@ -1,12 +1,4 @@
|
||||
#include "Debug.h"
|
||||
#include "getFreeSRAM.h"
|
||||
|
||||
void Debug::print_free_RAM()
|
||||
{
|
||||
delay(1000); //give OS time to find USB
|
||||
Keyboard.print(F("Free SRAM = "));
|
||||
Keyboard.println( getFreeSRAM() );
|
||||
}
|
||||
|
||||
void Debug::print_microseconds_per_scan()
|
||||
{
|
||||
|
@ -9,7 +9,6 @@ class Debug
|
||||
unsigned int scanCount = 0;
|
||||
|
||||
public:
|
||||
void print_free_RAM(); //print free SRAM, call this from setup()
|
||||
void print_microseconds_per_scan(); //print microseconds per scan every second
|
||||
void print_scans_per_second(); //print scans per second every second
|
||||
};
|
||||
|
@ -2,13 +2,12 @@
|
||||
/*
|
||||
pressRelease() calls key's press() or release() function if it was pressed or released.
|
||||
Both parameters are bitwise.
|
||||
rowEnd bit marks positioned immediatly after last key of row.
|
||||
*/
|
||||
void RowBase::pressRelease(const uint8_t KEY_COUNT, const read_pins_t debouncedChanged)
|
||||
{
|
||||
read_pins_t isFallingEdge; //bitwise, 1 means falling edge
|
||||
read_pins_t isRisingEdge; //bitwise, 1 means rising edge
|
||||
read_pins_mask_t rowMask; //bitwise, active col bit is 1
|
||||
read_pins_t rowMask; //bitwise, active col bit is 1
|
||||
uint8_t col; //index for ptrsKeys[col] array
|
||||
|
||||
//bit=1 if last debounced changed from 1 to 0, else bit=0
|
||||
|
@ -14,7 +14,7 @@ class RowBase
|
||||
virtual void keyWasPressed();
|
||||
protected:
|
||||
read_pins_t debounced; //bitwise, 1 means pressed, 0 means released
|
||||
void pressRelease(const read_pins_mask_t rowEnd, const read_pins_t debouncedChanged);
|
||||
void pressRelease(const uint8_t KEY_COUNT, const read_pins_t debouncedChanged);
|
||||
public:
|
||||
RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
||||
virtual void process()=0;
|
||||
|
@ -28,10 +28,7 @@ RowScanner_PinsArray::RowScanner_PinsArray(const uint8_t STROBE_PIN,
|
||||
}
|
||||
|
||||
/* scan() Strobes the row and reads the columns.
|
||||
Sets rowEnd and returns rowState.
|
||||
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.
|
||||
rowEnd is a larger type than portMask so that it can not overflow.
|
||||
Sets KEY_COUNT and returns rowState.
|
||||
|
||||
https://www.arduino.cc/en/Tutorial/DigitalPins
|
||||
https://www.arduino.cc/en/Reference/PinMode
|
||||
@ -39,10 +36,10 @@ 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
|
||||
*/
|
||||
read_pins_t RowScanner_PinsArray::scan(read_pins_mask_t& rowEnd)
|
||||
read_pins_t RowScanner_PinsArray::scan(uint8_t& keyCount)
|
||||
{
|
||||
read_pins_t rowState = 0; //bitwise
|
||||
rowEnd = 1;
|
||||
read_pins_t rowState = 0; //bitwise, one col per bit, 1 means key is pressed
|
||||
read_pins_t rowMask = 1; //bitwise, one col per bit, active col bit is 1
|
||||
|
||||
//strobe row on
|
||||
if (ACTIVE_HIGH)
|
||||
@ -60,9 +57,9 @@ read_pins_t RowScanner_PinsArray::scan(read_pins_mask_t& rowEnd)
|
||||
{
|
||||
if ( digitalRead(READ_PINS[i]) == ACTIVE_HIGH )
|
||||
{
|
||||
rowState |= rowEnd;
|
||||
rowState |= rowMask;
|
||||
}
|
||||
rowEnd <<= 1;
|
||||
rowMask <<= 1;
|
||||
}
|
||||
|
||||
//strobe row off
|
||||
@ -75,5 +72,6 @@ read_pins_t RowScanner_PinsArray::scan(read_pins_mask_t& rowEnd)
|
||||
digitalWrite(STROBE_PIN, HIGH);
|
||||
}
|
||||
|
||||
keyCount = READ_PIN_COUNT;
|
||||
return rowState;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <ColPort.h>
|
||||
|
||||
/* RowScanner_PinsArray class uses Arduino pin numbers (not port pin numbers).
|
||||
The maximum keys per row is 31, because Arduino's largest type is 32 bits and rowEnd consumes the last bit.
|
||||
Constructor is in RowScanner_PinsArray.cpp
|
||||
*/
|
||||
class RowScanner_PinsArray
|
||||
@ -19,9 +18,8 @@ class RowScanner_PinsArray
|
||||
const uint8_t READ_PIN_COUNT; //number of read pins
|
||||
public:
|
||||
RowScanner_PinsArray(const uint8_t STROBE_PIN,
|
||||
const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT);
|
||||
virtual read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||
//read_pins_t getRowState(read_pins_mask_t& rowEnd);
|
||||
const uint8_t READ_PINS[], const uint8_t READ_PIN_COUNT); //todo rename READ_PIN_COUNT to KEY_COUNT ??
|
||||
virtual read_pins_t scan(uint8_t& KEY_COUNT);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "RowScanner_PinsBitwise.h"
|
||||
/*
|
||||
Strobes the row and reads the columns.
|
||||
Sets rowEnd and returns rowState.
|
||||
*/
|
||||
ColPort* const RowScanner_PinsBitwise::scan()
|
||||
{
|
||||
@ -29,6 +28,5 @@ ColPort* const RowScanner_PinsBitwise::scan()
|
||||
refRowPort.setActivePinHigh(strobePin);
|
||||
}
|
||||
|
||||
// return getRowState(refColPort, rowEnd);
|
||||
return &refColPort;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
//constructor
|
||||
RowScanner_SPIShiftRegisters::RowScanner_SPIShiftRegisters(const uint8_t STROBE_PIN, uint8_t KEY_COUNT)
|
||||
: STROBE_PIN(STROBE_PIN), ROW_END(1 << KEY_COUNT), BYTE_COUNT(ceil (float(KEY_COUNT)/8))
|
||||
: STROBE_PIN(STROBE_PIN), BYTE_COUNT(ceil (float(KEY_COUNT)/8)), KEY_COUNT(KEY_COUNT)
|
||||
{
|
||||
//configure controller to communicate with shift register matrix
|
||||
pinMode(STROBE_PIN, OUTPUT);
|
||||
@ -16,9 +16,9 @@ void RowScanner_SPIShiftRegisters::begin()
|
||||
}
|
||||
|
||||
/*
|
||||
Sets rowEnd and returns rowState.
|
||||
Sets keyCount and returns rowState.
|
||||
*/
|
||||
read_pins_t RowScanner_SPIShiftRegisters::scan(read_pins_mask_t& rowEnd)
|
||||
read_pins_t RowScanner_SPIShiftRegisters::scan(uint8_t& keyCount)
|
||||
{
|
||||
read_pins_t rowState = 0;
|
||||
|
||||
@ -34,10 +34,10 @@ read_pins_t RowScanner_SPIShiftRegisters::scan(read_pins_mask_t& rowEnd)
|
||||
//strobe row off
|
||||
digitalWrite(STROBE_PIN, LOW);
|
||||
|
||||
rowEnd = ROW_END;
|
||||
keyCount = KEY_COUNT;
|
||||
|
||||
//for testing breadboard, clear unpowered pins
|
||||
rowState &= 0b01010001000100010001000100010001; //todo
|
||||
//for testing on breadboard, clear unpowered pins
|
||||
rowState &= 0b11110001000100010001000100010001; //todo
|
||||
|
||||
return rowState;
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ in sketch:
|
||||
call begin() from setup()
|
||||
|
||||
Upto 4 shift registers can be in a daisy chained.
|
||||
The maximum keys per row is 31, because Arduino's largest type is 32 bits and rowEnd consumes the last bit.
|
||||
|
||||
The shift registers are active high:
|
||||
10k pull-down resistors are grounded
|
||||
@ -33,11 +32,11 @@ class RowScanner_SPIShiftRegisters
|
||||
private:
|
||||
static const uint8_t SHIFT_LOAD; //controller's pin number that is connected to shift register's SHIFT_LOAD pin
|
||||
const uint8_t STROBE_PIN; //Arduino pin number connected to this row
|
||||
const read_pins_mask_t ROW_END; //bitwise, 1 bit marks positioned after last key of row
|
||||
const uint8_t BYTE_COUNT; //number of bytes to read from shift registers
|
||||
uint8_t KEY_COUNT;
|
||||
public:
|
||||
RowScanner_SPIShiftRegisters(const uint8_t STROBE_PIN, uint8_t KEY_COUNT);
|
||||
virtual read_pins_t scan(read_pins_mask_t& rowEnd);
|
||||
virtual read_pins_t scan(uint8_t& KEY_COUNT);
|
||||
void begin();
|
||||
};
|
||||
#endif
|
||||
|
@ -4,12 +4,12 @@ void Row_ShiftRegisters::process()
|
||||
{
|
||||
//these variables are all bitwise, one bit per key
|
||||
read_pins_t rowState; //1 means pressed, 0 means released
|
||||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row
|
||||
uint8_t keyCount;
|
||||
read_pins_t debouncedChanged; //1 means debounced changed
|
||||
|
||||
rowState = scanner.scan(rowEnd);
|
||||
rowState = scanner.scan(keyCount);
|
||||
debouncedChanged = debouncer.debounce(rowState, debounced);
|
||||
pressRelease(rowEnd, debouncedChanged);
|
||||
pressRelease(keyCount, debouncedChanged);
|
||||
}
|
||||
|
||||
void Row_ShiftRegisters::begin()
|
||||
|
@ -7,10 +7,20 @@ void Row_uC::process()
|
||||
{
|
||||
//these variables are all bitwise, one bit per key
|
||||
read_pins_t rowState; //1 means pressed, 0 means released
|
||||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row
|
||||
uint8_t keyCount;
|
||||
read_pins_t debouncedChanged; //1 means debounced changed
|
||||
|
||||
rowState = scanner.scan(rowEnd);
|
||||
rowState = scanner.scan(keyCount);
|
||||
/*
|
||||
Keyboard.print(" keyCount=");
|
||||
Keyboard.print(keyCount);
|
||||
Keyboard.print(" rowState=");
|
||||
Keyboard.print(rowState);
|
||||
*/
|
||||
debouncedChanged = debouncer.debounce(rowState, debounced);
|
||||
pressRelease(rowEnd, debouncedChanged);
|
||||
/*
|
||||
Keyboard.print(" debounced=");
|
||||
Keyboard.print(debounced);
|
||||
*/
|
||||
pressRelease(keyCount, debouncedChanged);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
#define CONFIG_KEYBRD_H
|
||||
#include <inttypes.h>
|
||||
|
||||
/* size of read_pins_t and read_pins_mask_t depends on the maximum number of pins scanned by RowScanner.
|
||||
By default, read_pins_t and read_pins_mask_t are set to the largest type.
|
||||
/* 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.
|
||||
If your 8-bit AVR is running low on memory, using a smaller type saves SRAM.
|
||||
Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing.
|
||||
*/
|
||||
@ -13,17 +13,9 @@ Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing.
|
||||
For RowScanner_SPIShiftRegisters, RowScanner_SPIShiftRegisters::KEY_COUNT
|
||||
For RowScanner_PinsBitwise, cover the last 1 bit in RowScanner_PinsBitwise::strobePin
|
||||
*/
|
||||
typedef uint8_t read_pins_t;
|
||||
//typedef uint8_t read_pins_t;
|
||||
//typedef uint16_t read_pins_t;
|
||||
//typedef uint32_t read_pins_t;
|
||||
|
||||
/* read_pins_mask_t is only used for rowMask and rowEnd, which extends one bit beyond the last col pin.
|
||||
uncomment typedef that covers one bit beyond the last col pin.
|
||||
This could be the same typedef as read_pins_t, or the next larger typedef.
|
||||
*/
|
||||
typedef uint8_t read_pins_mask_t;
|
||||
//typedef uint16_t read_pins_mask_t;
|
||||
//typedef uint32_t read_pins_mask_t;
|
||||
typedef uint32_t read_pins_t;
|
||||
|
||||
/* SAMPLE_COUNT = 4 is very reliable for a keyboard.
|
||||
Split keyboards with a long connecting wire or in environment with
|
||||
|
BIN
tutorials/images/bend_diodes_en_masse2.JPG
Normal file
BIN
tutorials/images/bend_diodes_en_masse2.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 319 KiB |
BIN
tutorials/images/bend_diodes_en_masse3.JPG
Normal file
BIN
tutorials/images/bend_diodes_en_masse3.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 340 KiB |
BIN
tutorials/images/breadboard_keyboard_2x2_crossColumns.jpg
Normal file
BIN
tutorials/images/breadboard_keyboard_2x2_crossColumns.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
Reference in New Issue
Block a user