Browse Source

rename keybrd_MCP23018.ino to keybrd_MCP23017.ino, works on both MCP23017 and MCP23018

tags/v0.6.4
wolfv6 7 years ago
parent
commit
cf3e582e25

BIN
examples/keybrd_MCP23017/MCP23017_back.JPG View File


BIN
examples/keybrd_MCP23017/MCP23017_front.JPG View File


BIN
examples/keybrd_MCP23017/MCP23018_LEDs_back.JPG View File


BIN
examples/keybrd_MCP23017/MCP23018_LEDs_front.JPG View File


examples/keybrd_MCP23018/back.JPG → examples/keybrd_MCP23017/MCP23018_back.JPG View File


examples/keybrd_MCP23018/front.JPG → examples/keybrd_MCP23017/MCP23018_front.JPG View File


+ 136
- 0
examples/keybrd_MCP23017/keybrd_MCP23017.ino View File

/* keybrd_MCP23017.ino /* keybrd_MCP23017.ino


This sketch:
is a simple 1-layer keyboard
runs on two matrices of a breadboard keyboard
runs on both MCP23017 and MCP23018 IOEs (LED on/off will be reversed on MCP23017)

Controller I/O expander
| Left | **0** | **1** | | Right | **0** | **1** |
|-------|-------|-------| |-------|-------|-------|
| **1** | 1 | 2 | | **1** | 3 | 4 |
| **0** | a | b | | **0** | fn | z 9 |

MCP23017 pin assignments MCP23017 pin assignments
DESTINATION PIN PIN_NUMBER PIN DESTINATION DESTINATION PIN PIN_NUMBER PIN DESTINATION
row0 GPB0 1 28 GPA7 row0 GPB0 1 28 GPA7
LC 18 SDA 13 16 A1 GND LC 18 SDA 13 16 A1 GND
NC 14 15 A0 GND NC 14 15 A0 GND


MCP23018 pin assignments
DESTINATION PIN PIN_NUMBER PIN DESTINATION
GND VSS 1 28 NC
NC 2 27 GPA7
row0 GPB0 3 26 GPA6
row1 GPB1 4 25 GPA5
GPB2 5 24 GPA4
GPB4 7 22 GPA2
GPB5 8 21 GPA1 col1
GPB6 9 20 GPA0 col0
GPB7 10 19 INTA
LC 3.3V VCC 11 18 INTB
LC 19 SCL 12 17 NC
LC 18 SDA 13 16 /RESET VCC
NC 14 15 ADDR GND

*/ */
// ################## GLOBAL ###################
// ================= INCLUDES ==================
#include <ScanDelay.h>
#include <Code_Sc.h>
#include <Row.h>

#include <Code_LayerHold.h>
#include <Key_LayeredKeys.h>
#include <LayerState_LED.h>
#include <LED_PortOpenDrain.h>

//left matrix
#include <Scanner_uC.h>

//right matrix
#include <Port_MCP23018.h>
#include <Scanner_IOE.h>

// ============ SPEED CONFIGURATION ============
ScanDelay scanDelay(9000);

/* ================ LEFT SCANNER ===============
Left matrix rows work the same as the ones in keybrd_2_single-layer.ino
*/
uint8_t readPins[] = {14, 15};
const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);

Scanner_uC scanner_L(LOW, readPins, readPinCount);

// =============== RIGHT SCANNER ===============
const uint8_t IOE_ADDR = 0x20; //MCP23018 ADDR pin grounded

Port_MCP23018 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //read pins 0, 1
Port_MCP23018 portB(IOE_ADDR, 1, 0);
Scanner_IOE scanner_R(LOW, portB, portA);

// ================= RIGHT LED =================
LED_PortOpenDrain LED_normal(portA, 1<<2); //LED on/off will be reversed on MCP23017
LED_PortOpenDrain LED_fn(portB, 1<<2); // because it's not open drain

// =================== CODES ===================
// ---------------- LAYER CODES ----------------
enum layerIds { NORMAL, FN };

LEDInterface* prtsLayerLEDs[] = { &LED_normal, &LED_fn }; //array index matches enum layerIds
LayerState_LED layerState(prtsLayerLEDs);

Code_LayerHold l_fn(FN, layerState);

// ---------------- SCAN CODES -----------------
Code_Sc s_a(KEY_A);
Code_Sc s_b(KEY_B);
Code_Sc s_z(KEY_Z);

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_9(KEY_9);

// =================== KEYS ====================
Key* const ptrsKeys_z9[] = { &s_z, &s_9 };
Key_LayeredKeys k_z9(ptrsKeys_z9);

LayerStateInterface& Key_LayeredKeys::refLayerState = layerState;

// =================== ROWS ====================
// ---------------- LEFT ROWS ------------------
Key* ptrsKeys_L0[] = { &s_1, &s_2 };
const uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0);
Row row_L0(scanner_L, 0, ptrsKeys_L0, KEY_COUNT_L0);

Key* ptrsKeys_L1[] = { &s_a, &s_b };
const uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1);
Row row_L1(scanner_L, 1, ptrsKeys_L1, KEY_COUNT_L1);

// ---------------- RIGHT ROWS -----------------
Key* ptrsKeys_R0[] = { &s_3, &s_4 };
const uint8_t KEY_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row row_R0(scanner_R, 1<<0, ptrsKeys_R0, KEY_COUNT_R0);

Key* ptrsKeys_R1[] = { &l_fn, &k_z9 };
const uint8_t KEY_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1);

// ################### MAIN ####################
void setup()
{
delay(6000);
Keyboard.print("keybrd_MCP23017.ino ");

scanner_R.begin();
layerState.begin();
}

void loop()
{
//left matrix
row_L0.process();
row_L1.process();

//right matrix
row_R0.process();
row_R1.process();

scanDelay.delay();
//debug.printScansPerSecond();
//debug.printMicrosecondsPerScan();
}

+ 0
- 117
examples/keybrd_MCP23018/keybrd_MCP23018.ino View File

/* keybrd_MCP23018.ino

This sketch:
is a simple 1-layer keyboard
runs on two matrices of a breadboard keyboard

Controller I/O expander
| Left | **0** | **1** | | Right | **0** | **1** |
|-------|-------|-------| |-------|-------|-------|
| **1** | 1 | 2 | | **1** | 3 | 4 |
| **0** | a | b | | **0** | c | d |

MCP23018 pin assignments
DESTINATION PIN PIN_NUMBER PIN DESTINATION
GND VSS 1 28 NC
NC 2 27 GPA7
row0 GPB0 3 26 GPA6
row1 GPB1 4 25 GPA5
GPB2 5 24 GPA4
GPB4 7 22 GPA2
GPB5 8 21 GPA1 col1
GPB6 9 20 GPA0 col0
GPB7 10 19 INTA
LC 3.3V VCC 11 18 INTB
LC 19 SCL 12 17 NC
LC 18 SDA 13 16 /RESET VCC
NC 14 15 ADDR GND

*/
// ################## GLOBAL ###################
// ================= INCLUDES ==================
#include <ScanDelay.h>
#include <Code_Sc.h>
#include <Row.h>

//left matrix
#include <Scanner_uC.h>

//right matrix
#include <Port_MCP23018.h>
#include <Scanner_IOE.h>
#include <LED_PortOpenDrain.h>

// ============ SPEED CONFIGURATION ============
ScanDelay scanDelay(9000);

/* ================ LEFT SCANNER ===============
Left matrix rows work the same as the ones in keybrd_2_single-layer.ino
*/
uint8_t readPins[] = {14, 15};
const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);

Scanner_uC scanner_L(LOW, readPins, readPinCount);

// =============== RIGHT SCANNER ===============
const uint8_t IOE_ADDR = 0x20; //MCP23018 ADDR pin grounded

Port_MCP23018 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //read pins 0, 1
Port_MCP23018 portB(IOE_ADDR, 1, 0);
Scanner_IOE scanner_R(LOW, portB, portA);

// ================= RIGHT LED =================
LED_PortOpenDrain LED_capsLck(portA, 1<<7);

// =================== 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_1(KEY_1);
Code_Sc s_2(KEY_2);
Code_Sc s_3(KEY_3);
Code_Sc s_4(KEY_4);

// =================== ROWS ====================
// ---------------- LEFT ROWS ------------------
Key* ptrsKeys_L0[] = { &s_1, &s_2 };
const uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0);
Row row_L0(scanner_L, 0, ptrsKeys_L0, KEY_COUNT_L0);

Key* ptrsKeys_L1[] = { &s_a, &s_b };
const uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1);
Row row_L1(scanner_L, 1, ptrsKeys_L1, KEY_COUNT_L1);

// ---------------- RIGHT ROWS -----------------
Key* ptrsKeys_R0[] = { &s_3, &s_4 };
const uint8_t KEY_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
Row row_R0(scanner_R, 1<<0, ptrsKeys_R0, KEY_COUNT_R0);

Key* ptrsKeys_R1[] = { &s_c, &s_d };
const uint8_t KEY_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1);

// ################### MAIN ####################
void setup()
{
delay(6000);
Keyboard.print("keybrd_MCP23018.ino ");

scanner_R.begin();
}

void loop()
{
//left matrix
row_L0.process();
row_L1.process();

//right matrix
row_R0.process();
row_R1.process();

scanDelay.delay();
//debug.printScansPerSecond();
//debug.printMicrosecondsPerScan();
}

+ 2
- 1
src/LED_Port.h View File

/* An LED_Port object is an I/O expander output pin that is connected to an LED indicator light. /* An LED_Port object is an I/O expander output pin that is connected to an LED indicator light.
LED_Port functions turn LED on and off. LED_Port functions turn LED on and off.
LED anode connected to ouput pin. LED cathode grounded.
This is for push-pull ouput pins.
This class is for push-pull ouput pins.
For LEDs connected to open drain output types, use LED_Port class. For LEDs connected to open drain output types, use LED_Port class.
Example initialization: Example initialization:

+ 1
- 1
src/LED_PortOpenDrain.cpp View File

*/ */
void LED_PortOpenDrain::on() void LED_PortOpenDrain::on()
{ {
refPort.writeLow(pin);
refPort.writeLow(pin); //sink output pin
} }


void LED_PortOpenDrain::off() void LED_PortOpenDrain::off()

+ 2
- 1
src/LED_PortOpenDrain.h View File

/* An LED_PortOpenDrain object is an I/O expander ouput pin that is connected to an LED. /* An LED_PortOpenDrain object is an I/O expander ouput pin that is connected to an LED.
LED_PortOpenDrain functions turn LED on and off. LED_PortOpenDrain functions turn LED on and off.
LED anode connected to power. LED cathode connected to open-drain ouput pin.
This is for open drain ouput pins.
This class is for open drain ouput pins.
For LEDs connected to push-pull output types, use LED_Port class. For LEDs connected to push-pull output types, use LED_Port class.
Example initialization: Example initialization:

+ 5
- 3
src/Port_MCP23018.h View File

write pins are connected to matrix Row (strobe pin) or LED. write pins are connected to matrix Row (strobe pin) or LED.
readPins are connected to matrix column to read which keys are pressed. readPins are connected to matrix column to read which keys are pressed.
MCP23018 has open-drain outputs (open-drain can only sink current). If LEDs are used, connect:
LED anodes (the longer lead) to power
LED cathodes (the shorter lead) to GPIO pin
Port_MCP23018 can only be active low (Scanner_IOE::activeState = LOW).
Open-drain active high would not work because pull down resistors have no effect on sink.
https://en.wikipedia.org/wiki/Open_collector
Use LED_PortOpenDrain class for indicator LEDs.
Instantiation Instantiation
------------ ------------

+ 2
- 3
tutorials/keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino View File

LED_Port LED_fn(portB, 1<<4); LED_Port LED_fn(portB, 1<<4);


// =================== CODES =================== // =================== CODES ===================
// ---------------- LAYER CODE -----------------
// ---------------- LAYER CODES ----------------
enum layerIds { NORMAL, FN }; enum layerIds { NORMAL, FN };


LEDInterface* prtsLayerLEDs[] = { &LED_normal, &LED_fn }; //array index matches enum layerIds LEDInterface* prtsLayerLEDs[] = { &LED_normal, &LED_fn }; //array index matches enum layerIds
*/ */
void setup() void setup()
{ {
Keyboard.begin();
scanner_R.begin(); scanner_R.begin();
layerState.begin(); //call LayerState_LED::begin() after Scanner_IOE::begin()
layerState.begin(); //todo call LayerState_LED::begin() after Scanner_IOE::begin()
} }


void loop() void loop()