Browse Source

replace rowEnd with KEY_COUNT, remove read_pins_mask_t, print_free_RAM()

tags/v0.5.0
wolfv6 7 years ago
parent
commit
a725a74831

+ 45
- 36
examples/keybrd_shift_register/keybrd_shift_register.ino View File

@@ -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()

+ 1
- 1
src/Code_LEDLock.cpp View File

@@ -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
{

+ 1
- 2
src/ColPort_PCA9655E.cpp View File

@@ -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)
{}

+ 0
- 8
src/Debug.cpp View File

@@ -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()
{

+ 0
- 1
src/Debug.h View File

@@ -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
};

+ 1
- 2
src/RowBase.cpp View File

@@ -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

+ 1
- 1
src/RowBase.h View File

@@ -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;

+ 7
- 9
src/RowScanner_PinsArray.cpp View File

@@ -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;
}

+ 2
- 4
src/RowScanner_PinsArray.h View File

@@ -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


+ 0
- 2
src/RowScanner_PinsBitwise.cpp View File

@@ -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;
}

+ 6
- 6
src/RowScanner_SPIShiftRegisters.cpp View File

@@ -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;
}

+ 2
- 3
src/RowScanner_SPIShiftRegisters.h View File

@@ -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

+ 3
- 3
src/Row_ShiftRegisters.cpp View File

@@ -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()

+ 13
- 3
src/Row_uC.cpp View File

@@ -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);
}

+ 4
- 12
src/config_keybrd.h View File

@@ -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 View File


BIN
tutorials/images/bend_diodes_en_masse3.JPG View File


BIN
tutorials/images/breadboard_keyboard_2x2_crossColumns.jpg View File