move IOE_scan_development and unit_tests to examples, add examples/IOE_PCA9655E_development/
Before Width: | Height: | Size: 327 KiB |
Before Width: | Height: | Size: 334 KiB |
@ -1,69 +0,0 @@
|
|||||||
/* simulate one scan of a key martix, on open-drain active-low I/O expander
|
|
||||||
|
|
||||||
BREADBOARD SETUP *******************************
|
|
||||||
Teensy LC connected to MCP23018 I/O expander via I2C
|
|
||||||
4.7k Ohm pullup resistors on SDA and SCL
|
|
||||||
use volt meter to measure pin voltages
|
|
||||||
MCP23018 has open-drain outputs (open-drain can only sink current)
|
|
||||||
|
|
||||||
MCP23018 PIN DIAGRAM ***************************
|
|
||||||
write port B read port A
|
|
||||||
GND VSS 1 28 NC
|
|
||||||
NC 2 27 GPA7
|
|
||||||
jumper0 GPB0 3 26 GPA6
|
|
||||||
GPB1 4 25 GPA5
|
|
||||||
GPB2 5 24 GPA4 jumper4
|
|
||||||
GPB3 6 23 GPA3
|
|
||||||
jumper4 GPB4 7 22 GPA2
|
|
||||||
GPB5 8 21 GPA1
|
|
||||||
GPB6 9 20 GPA0 jumper0
|
|
||||||
GPB7 10 19 INTA
|
|
||||||
power VDD 11 18 INTB
|
|
||||||
SCL SCL 12 17 NC
|
|
||||||
SDA SDA 13 16 RESET power
|
|
||||||
NC 14 15 ADDR GND
|
|
||||||
*/
|
|
||||||
#include "Wire.h"
|
|
||||||
|
|
||||||
const uint8_t ADDR = 0x20; //MCP23018 I2C address with ADDR pin grounded
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
delay(1000); //time for Serial print to work
|
|
||||||
|
|
||||||
// ================= configure ================
|
|
||||||
Serial.print("config ");
|
|
||||||
Wire.begin();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x01); //IODIRB Configure
|
|
||||||
Wire.write(0); //as output
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x00); //IODIRA Configuration
|
|
||||||
Wire.write(~0); //as input
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x0C); //GPPUA pull-up
|
|
||||||
Wire.write(~0); //pull-up enabled
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
// =================== scan ===================
|
|
||||||
Serial.println("scan");
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x13); //GPIOB output
|
|
||||||
Wire.write(B00001111); //pins 0-3 off, pins 4-7 sink on (strobe, LED on)
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x12); //GPIOA (immediately before requestFrom)
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.requestFrom(ADDR, static_cast<uint8_t>(1)); //request one byte from GPIOA read
|
|
||||||
Serial.print("portA=");
|
|
||||||
Serial.println(Wire.read(), BIN); //prints portA=11101111
|
|
||||||
}
|
|
||||||
void loop() { }
|
|
Before Width: | Height: | Size: 324 KiB |
Before Width: | Height: | Size: 330 KiB |
@ -1,69 +0,0 @@
|
|||||||
/* simulate one scan of a key martix, on source active-high I/O expander
|
|
||||||
|
|
||||||
BREADBOARD SETUP *******************************
|
|
||||||
Teensy LC connected to MCP23017 I/O expander via I2C
|
|
||||||
10k Ohm external pulldown resistors on port A
|
|
||||||
4.7k Ohm pullup resistors on SDA and SCL
|
|
||||||
use volt meter to measure pin voltages
|
|
||||||
|
|
||||||
MCP23017 PIN DIAGRAM ***************************
|
|
||||||
write port B read port A
|
|
||||||
jumper0 GPB0 1 26 GPA7 pulldown
|
|
||||||
GPB1 2 25 GPA6 pulldown
|
|
||||||
GPB2 3 24 GPA5 pulldown
|
|
||||||
GPB3 4 23 GPA4 pulldown jumper4
|
|
||||||
jumper4 GPB4 5 22 GPA3 pulldown
|
|
||||||
GPB5 6 21 GPA2 pulldown
|
|
||||||
GPB6 7 20 GPA1 pulldown
|
|
||||||
GPB7 8 19 GPA0 pulldown jumper0
|
|
||||||
power VDD 9 18 INTA
|
|
||||||
GND VSS 10 28 INTB
|
|
||||||
NC 11 27 RESET power
|
|
||||||
SCL SCL 12 17 A2 gnd
|
|
||||||
SDA SDA 13 16 A1 gnd
|
|
||||||
NC 14 15 A0 gnd
|
|
||||||
*/
|
|
||||||
#include "Wire.h"
|
|
||||||
|
|
||||||
const uint8_t ADDR = 0x20; //MCP23017 I2C address with all ADDR pins grounded
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
delay(1000); //time for Serial print to work
|
|
||||||
|
|
||||||
// ================= configure ================
|
|
||||||
Serial.print("config ");
|
|
||||||
Wire.begin();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x01); //IODIRB Configure
|
|
||||||
Wire.write(0); //as output
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x00); //IODIRA Configuration
|
|
||||||
Wire.write(~0); //as input
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x0C); //GPPUA pull-up
|
|
||||||
Wire.write(0); //pull-up disabled
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
// =================== scan ===================
|
|
||||||
Serial.println("scan");
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x13); //GPIOB output
|
|
||||||
Wire.write(B11110000); //pins 0-3 ground, pins 4-7 power (strobe, LED on)
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x12); //GPIOA (immediately before requestFrom)
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.requestFrom(ADDR, static_cast<uint8_t>(1)); //request one byte from GPIOA read
|
|
||||||
Serial.print("portA=");
|
|
||||||
Serial.println(Wire.read(), BIN); //prints portA=00010000
|
|
||||||
}
|
|
||||||
void loop() { }
|
|
Before Width: | Height: | Size: 326 KiB |
Before Width: | Height: | Size: 329 KiB |
@ -1,68 +0,0 @@
|
|||||||
/* simulate one scan of a key martix, on source active-low I/O expander
|
|
||||||
|
|
||||||
BREADBOARD SETUP *******************************
|
|
||||||
Teensy LC connected to MCP23017 I/O expander via I2C
|
|
||||||
4.7k Ohm pullup resistors on SDA and SCL
|
|
||||||
use volt meter to measure pin voltages
|
|
||||||
|
|
||||||
MCP23017 PIN DIAGRAM ***************************
|
|
||||||
write port B read port A
|
|
||||||
jumper0 GPB0 1 26 GPA7
|
|
||||||
GPB1 2 25 GPA6
|
|
||||||
GPB2 3 24 GPA5
|
|
||||||
GPB3 4 23 GPA4 jumper4
|
|
||||||
jumper4 GPB4 5 22 GPA3
|
|
||||||
GPB5 6 21 GPA2
|
|
||||||
GPB6 7 20 GPA1
|
|
||||||
GPB7 8 19 GPA0 jumper0
|
|
||||||
power VDD 9 18 INTA
|
|
||||||
GND VSS 10 28 INTB
|
|
||||||
NC 11 27 RESET power
|
|
||||||
SCL SCL 12 17 A2 gnd
|
|
||||||
SDA SDA 13 16 A1 gnd
|
|
||||||
NC 14 15 A0 gnd
|
|
||||||
*/
|
|
||||||
#include "Wire.h"
|
|
||||||
|
|
||||||
const uint8_t ADDR = 0x20; //MCP23017 I2C address with all ADDR pins grounded
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
delay(1000); //time for Serial print to work
|
|
||||||
|
|
||||||
// ================= configure ================
|
|
||||||
Serial.print("config ");
|
|
||||||
Wire.begin();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x01); //IODIRB Configure
|
|
||||||
Wire.write(0); //as output
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x00); //IODIRA Configuration
|
|
||||||
Wire.write(~0); //as input
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x0C); //GPPUA pull-up
|
|
||||||
Wire.write(~0); //pull-up enabled
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
// =================== scan ===================
|
|
||||||
Serial.println("scan");
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x13); //GPIOB output
|
|
||||||
Wire.write(B00001111); //pins 0-3 power (strobe, LED on), pins 4-7 ground
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.beginTransmission(ADDR);
|
|
||||||
Wire.write(0x12); //GPIOA (immediately before requestFrom)
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Wire.requestFrom(ADDR, static_cast<uint8_t>(1)); //request one byte from GPIOA read
|
|
||||||
Serial.print("portA=");
|
|
||||||
Serial.println(Wire.read(), BIN); //prints portA=11101111
|
|
||||||
}
|
|
||||||
void loop() { }
|
|
@ -0,0 +1,58 @@
|
|||||||
|
/* PCA9655E_1_write_read.ino
|
||||||
|
|
||||||
|
set port 1 pins
|
||||||
|
read and print value of port 0
|
||||||
|
measure port 1 pin voltages with a multimeter
|
||||||
|
|
||||||
|
DESTINATION PIN PIN_NUMBER PIN DESTINATION
|
||||||
|
x INT 1 24 VDD Teensy LC 3.3V
|
||||||
|
SCL AD1 2 23 SDA Teensy LC 18
|
||||||
|
GND AD2 3 22 SCL Teensy LC 19
|
||||||
|
GND IO0_0 4 21 AD0 SCL
|
||||||
|
GND IO0_1 5 20 IO1_6 x
|
||||||
|
VDD IO0_2 6 19 IO1_5 x
|
||||||
|
VDD IO0_3 7 18 IO1_4 x
|
||||||
|
GND IO0_4 8 17 IO1_4 x
|
||||||
|
GND IO0_5 9 16 IO1_3 x
|
||||||
|
x IO0_6 10 15 IO1_2 x
|
||||||
|
x IO0_7 11 14 IO1_1 x
|
||||||
|
GND VSS 12 13 IO1_0 x
|
||||||
|
*/
|
||||||
|
#include "Wire.h"
|
||||||
|
|
||||||
|
const uint8_t ADDR = 0x18; //I2C address with AD2=GND AD1=SCL AD0=SCL
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
delay(1000);
|
||||||
|
Serial.print("PCA9655E_read.ino");
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
//Configure port 1 to output
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(7); //configure direction
|
||||||
|
Wire.write(0); //0=output
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(3); //command byte 3 = Output Port 1
|
||||||
|
Wire.write( 1<<2 | 1<<3); //1=high
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
//Configure port 0 to input
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(6); //command byte 6 = Configuration dir Port 0
|
||||||
|
Wire.write(~0); //1=input
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(0); //command byte 0 = Input Port 0
|
||||||
|
Wire.endTransmission(false); //PCA9655E needs false to send a restart
|
||||||
|
|
||||||
|
Wire.requestFrom(ADDR, 1u); //request one byte from input port
|
||||||
|
|
||||||
|
Serial.print(" port0_val= ");
|
||||||
|
uint8_t port0_val = Wire.read();
|
||||||
|
Serial.print(port0_val, BIN); //expect xx001100
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { }
|
BIN
examples/IOE_PCA9655E_development/PCA9655E_1_write_read/back.JPG
Normal file
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 129 KiB |
BIN
examples/IOE_PCA9655E_development/PCA9655E_2_scan/DSCF0001.JPG
Normal file
After Width: | Height: | Size: 146 KiB |
BIN
examples/IOE_PCA9655E_development/PCA9655E_2_scan/DSCF0002.JPG
Normal file
After Width: | Height: | Size: 122 KiB |
@ -0,0 +1,56 @@
|
|||||||
|
/* PCA9655E_2_scan.ino
|
||||||
|
|
||||||
|
power IO0_2 and read IO1_1 (similar to strobe and read on key matrix)
|
||||||
|
|
||||||
|
DESTINATION PIN PIN_NUMBER PIN DESTINATION
|
||||||
|
x INT 1 24 VDD Teensy LC 3.3V
|
||||||
|
SCL AD1 2 23 SDA Teensy LC 18
|
||||||
|
GND AD2 3 22 SCL Teensy LC 19
|
||||||
|
GND IO0_0 4 21 AD0 SCL
|
||||||
|
GND IO0_1 5 20 IO1_6 x
|
||||||
|
IO1_1 IO0_2 6 19 IO1_5 x
|
||||||
|
GND IO0_3 7 18 IO1_4 x
|
||||||
|
GND IO0_4 8 17 IO1_4 x
|
||||||
|
GND IO0_5 9 16 IO1_3 x
|
||||||
|
x IO0_6 10 15 IO1_2 x
|
||||||
|
x IO0_7 11 14 IO1_1 IO0_2
|
||||||
|
GND VSS 12 13 IO1_0 x
|
||||||
|
*/
|
||||||
|
#include "Wire.h"
|
||||||
|
|
||||||
|
const uint8_t ADDR = 0x18; //I2C address with AD2=GND AD1=SCL AD0=SCL
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
delay(1000);
|
||||||
|
Serial.print("PCA9655E_read.ino");
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
//Configure port 1 to output
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(7); //command byte 7 = Configuration dir Port 1
|
||||||
|
Wire.write(0); //0=output
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(3); //command byte 3 = Output Port 1
|
||||||
|
Wire.write( 1<<1 ); //1=high
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
//Configure port 0 to input
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(6); //command byte 6 = Configuration dir Port 0
|
||||||
|
Wire.write(~0); //1=input
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.beginTransmission(ADDR);
|
||||||
|
Wire.write(0); //command byte 0 = Input Port 0
|
||||||
|
Wire.endTransmission(false); //PCA9655E needs false to send a restart
|
||||||
|
|
||||||
|
Wire.requestFrom(ADDR, 1u); //request one byte from input port
|
||||||
|
|
||||||
|
Serial.print(" port0_val= ");
|
||||||
|
uint8_t port0_val = Wire.read();
|
||||||
|
Serial.print(port0_val, BIN); //expect xx000100
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { }
|
@ -0,0 +1,45 @@
|
|||||||
|
/* PCA9655E_3_scan_lib.ino
|
||||||
|
does same as PCA9655E_2_scan.ino, but using keybrd library classes
|
||||||
|
pictures in PCA9655E_2_scan/
|
||||||
|
|
||||||
|
set port 1 pins
|
||||||
|
read and print value of port 0
|
||||||
|
measure port 1 pin voltages with a multimeter
|
||||||
|
|
||||||
|
DESTINATION PIN PIN_NUMBER PIN DESTINATION
|
||||||
|
x INT 1 24 VDD Teensy LC 3.3V
|
||||||
|
SCL AD1 2 23 SDA Teensy LC 18
|
||||||
|
GND AD2 3 22 SCL Teensy LC 19
|
||||||
|
GND IO0_0 4 21 AD0 SCL
|
||||||
|
GND IO0_1 5 20 IO1_6 x
|
||||||
|
IO1_1 IO0_2 6 19 IO1_5 x
|
||||||
|
GND IO0_3 7 18 IO1_4 x
|
||||||
|
GND IO0_4 8 17 IO1_4 x
|
||||||
|
GND IO0_5 9 16 IO1_3 x
|
||||||
|
x IO0_6 10 15 IO1_2 x
|
||||||
|
x IO0_7 11 14 IO1_1 IO0_2 strobe pin
|
||||||
|
GND VSS 12 13 IO1_0 x
|
||||||
|
*/
|
||||||
|
#include <Port_PCA9655E.h>
|
||||||
|
#include <Scanner_IOE.h>
|
||||||
|
|
||||||
|
const uint8_t ADDR = 0x18; //I2C address with AD2=GND AD1=SCL AD0=SCL
|
||||||
|
|
||||||
|
Port_PCA9655E port0(ADDR, 0, ~0); //read all pins
|
||||||
|
Port_PCA9655E port1(ADDR, 1, 0); //for strobe
|
||||||
|
|
||||||
|
Scanner_IOE scanner_R(HIGH, port1, port0);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
delay(6000);
|
||||||
|
Keyboard.print("PCA9655E_scan.ino");
|
||||||
|
|
||||||
|
scanner_R.begin();
|
||||||
|
|
||||||
|
Keyboard.print(" port0_val= ");
|
||||||
|
uint8_t port0_val = scanner_R.scan(1<<1); //strobe pin 1
|
||||||
|
Keyboard.print(port0_val, BIN); //expect xx000100
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { }
|
@ -0,0 +1,86 @@
|
|||||||
|
/* PCA9655E_4_scan_loop.ino
|
||||||
|
does same as PCA9655E_2_scan.ino, but using keybrd library classes
|
||||||
|
pictures in PCA9655E_2_scan/
|
||||||
|
|
||||||
|
set port 1 pins
|
||||||
|
read and print value of port 0
|
||||||
|
measure port 1 pin voltages with a multimeter
|
||||||
|
|
||||||
|
DESTINATION PIN PIN_NUMBER PIN DESTINATION
|
||||||
|
x INT 1 24 VDD Teensy LC 3.3V
|
||||||
|
SCL AD1 2 23 SDA Teensy LC 18
|
||||||
|
GND AD2 3 22 SCL Teensy LC 19
|
||||||
|
GND IO0_0 4 21 AD0 SCL
|
||||||
|
GND IO0_1 5 20 IO1_6 x
|
||||||
|
IO1_1 IO0_2 6 19 IO1_5 x
|
||||||
|
GND IO0_3 7 18 IO1_4 x
|
||||||
|
GND IO0_4 8 17 IO1_4 x
|
||||||
|
GND IO0_5 9 16 IO1_3 x
|
||||||
|
x IO0_6 10 15 IO1_2 x
|
||||||
|
x IO0_7 11 14 IO1_1 IO0_2 strobe pin
|
||||||
|
GND VSS 12 13 IO1_0 x
|
||||||
|
*/
|
||||||
|
#include <Port_PCA9655E.h>
|
||||||
|
#include <Scanner_IOE.h>
|
||||||
|
|
||||||
|
const uint8_t ADDR = 0x18; //I2C address with AD2=GND AD1=SCL AD0=SCL
|
||||||
|
|
||||||
|
Port_PCA9655E port0(ADDR, 0, ~0); //read all pins
|
||||||
|
Port_PCA9655E port1(ADDR, 1, 0); //for strobe
|
||||||
|
|
||||||
|
Scanner_IOE scanner_R(HIGH, port1, port0);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
delay(6000);
|
||||||
|
Keyboard.println("PCA9655E_scan_loop.ino");
|
||||||
|
|
||||||
|
scanner_R.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t port0_val; //bit pattern
|
||||||
|
uint8_t errorCount = 0;
|
||||||
|
int loopCount = 0;
|
||||||
|
int wait = 0; //delayMicroseconds
|
||||||
|
|
||||||
|
void status()
|
||||||
|
{
|
||||||
|
Keyboard.print(" loopCount=");
|
||||||
|
Keyboard.print(loopCount);
|
||||||
|
Keyboard.print(" wait=");
|
||||||
|
Keyboard.println(wait);
|
||||||
|
};
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
port0_val = scanner_R.scan(1<<1); //strobe pin 1
|
||||||
|
if ( (B00111111 & port0_val) != B00000100 ) //expect xx000100, where xx float
|
||||||
|
{
|
||||||
|
Keyboard.print("port0_val=");
|
||||||
|
Keyboard.print(port0_val, BIN);
|
||||||
|
errorCount++;
|
||||||
|
status();
|
||||||
|
}
|
||||||
|
|
||||||
|
loopCount++;
|
||||||
|
if (loopCount > 32000 || errorCount > 10)
|
||||||
|
{
|
||||||
|
Keyboard.print("stop errorCount=");
|
||||||
|
Keyboard.print(errorCount);
|
||||||
|
status();
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loopCount % 1000 == 0)
|
||||||
|
{
|
||||||
|
Keyboard.print(" progress");
|
||||||
|
status();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loopCount > 22000)
|
||||||
|
{
|
||||||
|
wait++; //test other delays
|
||||||
|
}
|
||||||
|
|
||||||
|
delayMicroseconds(wait);
|
||||||
|
}
|
BIN
examples/IOE_PCA9655E_development/PCA9655E_5_keybrd/back.JPG
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
examples/IOE_PCA9655E_development/PCA9655E_5_keybrd/front.JPG
Normal file
After Width: | Height: | Size: 150 KiB |
@ -1,10 +1,26 @@
|
|||||||
/* keybrd_PCA9655E.ino
|
/* keybrd_PCA9655E.ino
|
||||||
|
keyboard layout is same as top-left keys of DH matrices:
|
||||||
|
|
||||||
Controller I/O expander
|
Controller I/O expander
|
||||||
| Left | **0** | **1** | | Right | **0** | **1** |
|
| Left | **0** | **1** | | Right | **2** | **3** |
|
||||||
|:-----:|-------|-------| |:-----:|-------|-------|
|
|:-----:|-------|-------| |:-----:|-------|-------|
|
||||||
| **1** | 1 | 2 | | **1** | 3 | 4 |
|
| **1** | q | w | | **1** | u | i |
|
||||||
| **0** | a | b | | **0** | c | d |
|
| **0** | [ | b | | **0** | h | y |
|
||||||
|
|
||||||
|
PCA9655E pin assignments are compatible with this sketch and keybrd_DH.ino
|
||||||
|
DESTINATION PIN PIN_NUMBER PIN DESTINATION
|
||||||
|
x INT 1 24 VDD Teensy LC 3.3V
|
||||||
|
SCL AD1 2 23 SDA Teensy LC 18
|
||||||
|
GND AD2 3 22 SCL Teensy LC 19
|
||||||
|
GND IO0_0 4 21 AD0 SCL
|
||||||
|
GND IO0_1 5 20 IO1_6 x
|
||||||
|
col2 IO0_2 6 19 IO1_5 x
|
||||||
|
col3 IO0_3 7 18 IO1_4 x
|
||||||
|
GND IO0_4 8 17 IO1_4 x
|
||||||
|
GND IO0_5 9 16 IO1_3 x
|
||||||
|
x IO0_6 10 15 IO1_2 x
|
||||||
|
x IO0_7 11 14 IO1_1 row1
|
||||||
|
GND VSS 12 13 IO1_0 row2
|
||||||
*/
|
*/
|
||||||
// ################## GLOBAL ###################
|
// ################## GLOBAL ###################
|
||||||
// ================= INCLUDES ==================
|
// ================= INCLUDES ==================
|
||||||
@ -29,55 +45,62 @@ uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
|||||||
Scanner_uC scanner_L(HIGH, readPins, readPinCount);
|
Scanner_uC scanner_L(HIGH, readPins, readPinCount);
|
||||||
|
|
||||||
// =============== RIGHT SCANNER ===============
|
// =============== RIGHT SCANNER ===============
|
||||||
const uint8_t IOE_ADDR = 0x18;
|
const uint8_t IOE_ADDR = 0x18; //AD2=GND AD1=SCL AD0=SCL
|
||||||
|
|
||||||
Port_PCA9655E port1(IOE_ADDR, 1, 0); //for strobe
|
Port_PCA9655E port0(IOE_ADDR, 0, 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 ); //for read
|
||||||
Port_PCA9655E port0(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read
|
Port_PCA9655E port1(IOE_ADDR, 1, 0); //for strobe
|
||||||
|
|
||||||
Scanner_IOE scanner_R(HIGH, port1, port0);
|
Scanner_IOE scanner_R(HIGH, port1, port0);
|
||||||
|
|
||||||
// =================== CODES ===================
|
// =================== CODES ===================
|
||||||
Code_Sc s_a(KEY_A);
|
Code_Sc s_B(KEY_B);
|
||||||
Code_Sc s_b(KEY_B);
|
Code_Sc s_I(KEY_I);
|
||||||
Code_Sc s_c(KEY_C);
|
Code_Sc s_H(KEY_H);
|
||||||
Code_Sc s_d(KEY_D);
|
Code_Sc s_Q(KEY_Q);
|
||||||
|
Code_Sc s_W(KEY_W);
|
||||||
|
Code_Sc s_U(KEY_U);
|
||||||
|
Code_Sc s_Y(KEY_Y);
|
||||||
|
|
||||||
|
Code_Sc s_0(KEY_0);
|
||||||
Code_Sc s_1(KEY_1);
|
Code_Sc s_1(KEY_1);
|
||||||
Code_Sc s_2(KEY_2);
|
Code_Sc s_leftBracket(KEY_LEFT_BRACE);
|
||||||
Code_Sc s_3(KEY_3);
|
|
||||||
Code_Sc s_4(KEY_4);
|
|
||||||
|
|
||||||
// =================== ROWS ====================
|
// =================== ROWS ====================
|
||||||
// ---------------- LEFT ROWS ------------------
|
// ---------------- LEFT ROWS ------------------
|
||||||
Key* ptrsKeys_L0[] = { &s_1, &s_2 };
|
Key* ptrsKeys_L0[] = { &s_Q, &s_W };
|
||||||
uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0);
|
uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0);
|
||||||
Row row_L0(scanner_L, 21, ptrsKeys_L0, KEY_COUNT_L0);
|
Row row_L0(scanner_L, 21, ptrsKeys_L0, KEY_COUNT_L0);
|
||||||
|
|
||||||
Key* ptrsKeys_L1[] = { &s_a, &s_b };
|
Key* ptrsKeys_L1[] = { &s_leftBracket, &s_B };
|
||||||
uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1);
|
uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1);
|
||||||
Row row_L1(scanner_L, 20, ptrsKeys_L1, KEY_COUNT_L1);
|
Row row_L1(scanner_L, 20, ptrsKeys_L1, KEY_COUNT_L1);
|
||||||
|
|
||||||
// ---------------- RIGHT ROWS -----------------
|
// ---------------- RIGHT ROWS -----------------
|
||||||
Key* ptrsKeys_R0[] = { &s_3, &s_4 };
|
Key* ptrsKeys_R0[] = { &s_0, &s_1, &s_U, &s_I };
|
||||||
uint8_t KEY_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
uint8_t KEY_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||||
Row row_R0(scanner_R, 1<<0, ptrsKeys_R0, KEY_COUNT_R0);
|
Row row_R0(scanner_R, 1<<0, ptrsKeys_R0, KEY_COUNT_R0);
|
||||||
|
|
||||||
Key* ptrsKeys_R1[] = { &s_c, &s_d };
|
Key* ptrsKeys_R1[] = { &s_0, &s_1, &s_H, &s_Y };
|
||||||
uint8_t KEY_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
|
uint8_t KEY_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
|
||||||
Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1);
|
Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
// ################### MAIN ####################
|
// ################### MAIN ####################
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Keyboard.begin();
|
delay(6000);
|
||||||
|
Keyboard.print("keybrd_PCA9655E.ino ");
|
||||||
|
|
||||||
|
//Keyboard.begin(); not needed ?? it's in DH mainSketch.cpp and keybrd_4c_split_keyboard_with_IOE.ino
|
||||||
scanner_R.begin();
|
scanner_R.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
//left matrix
|
//left matrix (commented because keys are not connected)
|
||||||
row_L0.process();
|
//row_L0.process();
|
||||||
row_L1.process();
|
//row_L1.process();
|
||||||
|
|
||||||
//right matrix
|
//right matrix
|
||||||
row_R0.process();
|
row_R0.process();
|
8
examples/IOE_PCA9655E_development/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
The series of sketches in this folder where used to develope the Port_PCA9655E class.
|
||||||
|
The folder numbers are ordered from fundamental to practical.
|
||||||
|
|
||||||
|
Each sketch was tested on a breadboard. Breadboards hold:
|
||||||
|
* Teensy LC controller
|
||||||
|
* PCA9655E I/O expander
|
||||||
|
|
||||||
|
Pictures of the breadboard are in the folders.
|
@ -71,7 +71,7 @@ Code_Sc s_2(KEY_2);
|
|||||||
Code_Sc s_3(KEY_3);
|
Code_Sc s_3(KEY_3);
|
||||||
Code_Sc s_4(KEY_4);
|
Code_Sc s_4(KEY_4);
|
||||||
|
|
||||||
Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED_capsLck);//todo was testing LED, restore s_4 when done
|
Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED_capsLck);//was testing LED, restore s_4 when done
|
||||||
|
|
||||||
/* =================== ROWS ====================
|
/* =================== ROWS ====================
|
||||||
Left row names contain the letter 'L', while right row names conatain the letter 'R'.
|
Left row names contain the letter 'L', while right row names conatain the letter 'R'.
|
||||||
@ -118,14 +118,9 @@ void loop()
|
|||||||
|
|
||||||
//right matrix
|
//right matrix
|
||||||
row_R0.process();
|
row_R0.process();
|
||||||
//Keyboard.println(" 0");
|
|
||||||
//delay(2000);
|
|
||||||
row_R1.process();
|
row_R1.process();
|
||||||
//Keyboard.println(" 1");
|
|
||||||
//delay(2000);
|
|
||||||
|
|
||||||
scanDelay.delay();
|
scanDelay.delay();
|
||||||
//Keyboard.println(" end loop");//todo
|
|
||||||
//debug.print_scans_per_second();
|
//debug.print_scans_per_second();
|
||||||
//debug.print_microseconds_per_scan();
|
//debug.print_microseconds_per_scan();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
#include "LED_uC.h"
|
#include "LED_uC.h"
|
||||||
|
|
||||||
|
LED_uC::LED_uC(const uint8_t pin) : pin(pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
void LED_uC::on()
|
void LED_uC::on()
|
||||||
{
|
{
|
||||||
digitalWrite(pin, HIGH);
|
digitalWrite(pin, HIGH);
|
||||||
|
@ -9,13 +9,9 @@
|
|||||||
class LED_uC: public LEDInterface
|
class LED_uC: public LEDInterface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const uint8_t pin; //Aduino pin that is connected to an LED
|
const uint8_t pin; //Aduino pin number connected to an LED
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LED_uC(const uint8_t pin): pin(pin)
|
LED_uC(const uint8_t pin);
|
||||||
{
|
|
||||||
pinMode(pin, OUTPUT);//todo move to .cpp file
|
|
||||||
}
|
|
||||||
virtual void on();
|
virtual void on();
|
||||||
virtual void off();
|
virtual void off();
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "Port_MCP23018.h"
|
#include "Port_MCP23018.h"
|
||||||
//todo add Port_MCP23018::write() like Port_MCP23S17::transer() ??
|
|
||||||
|
|
||||||
/* beginProtocol() is called from Scanner_IOE::begin(). Initiates I2C bus.
|
/* beginProtocol() is called from Scanner_IOE::begin(). Initiates I2C bus.
|
||||||
|
|
||||||
@ -11,7 +10,6 @@ Longer wires require lower clock speeds.
|
|||||||
void Port_MCP23018::beginProtocol()
|
void Port_MCP23018::beginProtocol()
|
||||||
{
|
{
|
||||||
Wire.begin(); //initiate I2C bus to 100 kHz
|
Wire.begin(); //initiate I2C bus to 100 kHz
|
||||||
//Wire.setClock(400000L); //set I2C bus to 400 kHz (have not tested 400 kHz)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin().
|
/* begin() is called from Scanner_IOE::begin().
|
||||||
@ -51,21 +49,16 @@ void Port_MCP23018::write(const uint8_t pin, const bool logicLevel)
|
|||||||
if (logicLevel == LOW)
|
if (logicLevel == LOW)
|
||||||
{
|
{
|
||||||
outputVal &= ~pin; //set pin output to low
|
outputVal &= ~pin; //set pin output to low
|
||||||
//Keyboard.print(" low");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
outputVal |= pin; //set pin output to high
|
outputVal |= pin; //set pin output to high
|
||||||
//Keyboard.print(" high");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Keyboard.print(" outputVal=");//todo
|
|
||||||
//Keyboard.println(outputVal);
|
|
||||||
Wire.beginTransmission(deviceAddr);
|
Wire.beginTransmission(deviceAddr);
|
||||||
Wire.write(portNum + 0x12); //GPIO
|
Wire.write(portNum + 0x12); //GPIO
|
||||||
Wire.write(outputVal);
|
Wire.write(outputVal);
|
||||||
Wire.endTransmission();
|
Wire.endTransmission();
|
||||||
//delay(4000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read() returns portState.
|
/* read() returns portState.
|
||||||
|
@ -15,12 +15,12 @@ void Port_PCA9655E::beginProtocol()
|
|||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin().
|
/* begin() is called from Scanner_IOE::begin().
|
||||||
Configures read pins to input.
|
Configures read pins to input.
|
||||||
strobeOn is not used because PCA9655E has no pull-up resistors.
|
strobeOn is not used because PCA9655E has no internal pull-up resistors.
|
||||||
*/
|
*/
|
||||||
void Port_PCA9655E::begin(const uint8_t strobeOn)
|
void Port_PCA9655E::begin(const uint8_t strobeOn)
|
||||||
{
|
{
|
||||||
Wire.beginTransmission(deviceAddr);
|
Wire.beginTransmission(deviceAddr);
|
||||||
Wire.write(portNum + 6); //configuration byte command
|
Wire.write(portNum + 6); //configure direction
|
||||||
Wire.write(readPins); //0=output (for strobe and LED), 1=input (for read)
|
Wire.write(readPins); //0=output (for strobe and LED), 1=input (for read)
|
||||||
Wire.endTransmission();
|
Wire.endTransmission();
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,10 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
strobePin has one of two formats:
|
strobePin has one of two formats:
|
||||||
1. if strobe pin is on uC (Scanner_uC or Scanner_ShiftRegsRead),
|
* if strobe pin is on uC (strobe for Scanner_uC or Scanner_ShiftRegsRead),
|
||||||
then strobePin is an Arduino pin number connected to this row.
|
then strobePin is an Arduino pin number connected to this row.
|
||||||
2. if strobe pin is on I/O expander (Scanner_IOE), then strobePin is bit pattern,
|
* if strobe pin is on I/O expander (strobe for Scanner_IOE), then strobePin is bit pattern,
|
||||||
1 indicating the I/O expander pin connected to this row
|
1 indicating the I/O expander pin connected to this row
|
||||||
|
|
||||||
todo instantiation examples - here or in Scanner?
|
|
||||||
*/
|
*/
|
||||||
class Row
|
class Row
|
||||||
{
|
{
|
||||||
@ -31,7 +29,7 @@ class Row
|
|||||||
protected:
|
protected:
|
||||||
const uint8_t keyCount; //number of read pins
|
const uint8_t keyCount; //number of read pins
|
||||||
//Debouncer_Samples debouncer;
|
//Debouncer_Samples debouncer;
|
||||||
Debouncer_Not debouncer; //todo
|
Debouncer_Not debouncer; //todo restore Debouncer_Samples after testing
|
||||||
read_pins_t debounced; //bit pattern, state of keys after debouncing, 1=pressed, 0=released
|
read_pins_t debounced; //bit pattern, state of keys after debouncing, 1=pressed, 0=released
|
||||||
public:
|
public:
|
||||||
Row(ScannerInterface& refScanner, const uint8_t strobePin,
|
Row(ScannerInterface& refScanner, const uint8_t strobePin,
|
||||||
|
@ -6,25 +6,20 @@ Scanner_ShiftRegsReadStrobed::Scanner_ShiftRegsReadStrobed(const bool activeStat
|
|||||||
slaveSelect(slaveSelect), byte_count(byte_count)
|
slaveSelect(slaveSelect), byte_count(byte_count)
|
||||||
{
|
{
|
||||||
pinMode(slaveSelect, OUTPUT);
|
pinMode(slaveSelect, OUTPUT);
|
||||||
|
SPI.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init() is called once for each row from Row constructor.
|
/* init() is called once for each row from Row constructor.
|
||||||
Configures controller to communicate with shift register matrix.
|
Configures controller to communicate with shift register matrix.
|
||||||
|
|
||||||
|
slaveSelect initialize not needed, only affects first scan, which is before USB is detected by OS.
|
||||||
|
digitalWrite(slaveSelect, HIGH);
|
||||||
*/
|
*/
|
||||||
void Scanner_ShiftRegsReadStrobed::init(const uint8_t strobePin)
|
void Scanner_ShiftRegsReadStrobed::init(const uint8_t strobePin)
|
||||||
{
|
{
|
||||||
pinMode(strobePin, OUTPUT);
|
pinMode(strobePin, OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin() should be called once from sketch setup().
|
|
||||||
Initializes shift register's shift/load pin.
|
|
||||||
*/
|
|
||||||
void Scanner_ShiftRegsReadStrobed::begin()
|
|
||||||
{
|
|
||||||
digitalWrite(slaveSelect, HIGH); //initialize ??only needed for first scan
|
|
||||||
SPI.begin(); //todo move this to constructor or init()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* scan() strobes the row's strobePin and returns state of the shift register's input pins.
|
/* scan() strobes the row's strobePin and returns state of the shift register's input pins.
|
||||||
strobePin is Arduino pin number connected to this row.
|
strobePin is Arduino pin number connected to this row.
|
||||||
Bit patterns are 1 bit per key.
|
Bit patterns are 1 bit per key.
|
||||||
@ -44,6 +39,7 @@ read_pins_t Scanner_ShiftRegsReadStrobed::scan(const uint8_t strobePin)
|
|||||||
{
|
{
|
||||||
read_pins_t readState = 0; //bits, 1 means key is pressed, 0 means released
|
read_pins_t readState = 0; //bits, 1 means key is pressed, 0 means released
|
||||||
|
|
||||||
|
//strobe off here NOT release continuously
|
||||||
digitalWrite(strobePin, activeState); //strobe on
|
digitalWrite(strobePin, activeState); //strobe on
|
||||||
|
|
||||||
//SPI.beginTransaction( SPISettings(5000000, MSBFIRST, SPI_MODE0) ); //control SPI bus, 5 MHz
|
//SPI.beginTransaction( SPISettings(5000000, MSBFIRST, SPI_MODE0) ); //control SPI bus, 5 MHz
|
||||||
@ -53,7 +49,7 @@ read_pins_t Scanner_ShiftRegsReadStrobed::scan(const uint8_t strobePin)
|
|||||||
|
|
||||||
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output
|
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output
|
||||||
|
|
||||||
digitalWrite(strobePin, !activeState); //strobe off to preserv IR LED life
|
digitalWrite(strobePin, !activeState); //strobe off to preserve IR LED life
|
||||||
|
|
||||||
SPI.transfer(&readState, byte_count);
|
SPI.transfer(&readState, byte_count);
|
||||||
|
|
||||||
@ -61,6 +57,7 @@ read_pins_t Scanner_ShiftRegsReadStrobed::scan(const uint8_t strobePin)
|
|||||||
|
|
||||||
digitalWrite(slaveSelect, LOW); //load parallel inputs to registers
|
digitalWrite(slaveSelect, LOW); //load parallel inputs to registers
|
||||||
|
|
||||||
|
//strobe off here still releases continuously
|
||||||
return readState;
|
return readState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ class Scanner_ShiftRegsReadStrobed : public ScannerInterface
|
|||||||
Scanner_ShiftRegsReadStrobed(const bool activeState,
|
Scanner_ShiftRegsReadStrobed(const bool activeState,
|
||||||
const uint8_t slaveSelect, const uint8_t byte_count);
|
const uint8_t slaveSelect, const uint8_t byte_count);
|
||||||
virtual void init(const uint8_t strobePin);
|
virtual void init(const uint8_t strobePin);
|
||||||
virtual void begin();
|
|
||||||
virtual read_pins_t scan(const uint8_t strobePin);
|
virtual read_pins_t scan(const uint8_t strobePin);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,8 +49,8 @@ In portA, the first two pins are set to input for reading.
|
|||||||
"<<" (bit shift left) and "|" (OR) are bitwise operators.
|
"<<" (bit shift left) and "|" (OR) are bitwise operators.
|
||||||
Pin numbers to be read are to the right of "1<<" and delimited by "|".
|
Pin numbers to be read are to the right of "1<<" and delimited by "|".
|
||||||
*/
|
*/
|
||||||
Port_MCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 );
|
Port_MCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read
|
||||||
Port_MCP23S17 portB(IOE_ADDR, 1, 0);
|
Port_MCP23S17 portB(IOE_ADDR, 1, 0); //for strobe
|
||||||
Scanner_IOE scanner_R(LOW, portB, portA);
|
Scanner_IOE scanner_R(LOW, portB, portA);
|
||||||
|
|
||||||
// =================== CODES ===================
|
// =================== CODES ===================
|
||||||
@ -69,8 +69,10 @@ Left row names contain the letter 'L', while right row names conatain the letter
|
|||||||
|
|
||||||
Row constructor parameters are: scanner, strobePin, ptrsKeys[], keyCount.
|
Row constructor parameters are: scanner, strobePin, ptrsKeys[], keyCount.
|
||||||
strobePin has one of two formats:
|
strobePin has one of two formats:
|
||||||
* if refScanner a Scanner_uC, then strobePin is an Arduino pin number connected to this row
|
* if strobe pin is on uC (strobe for Scanner_uC or Scanner_ShiftRegsRead),
|
||||||
* otherwise strobePin is a bit pattern, 1 indicating an IC pin connected to the row
|
then strobePin is an Arduino pin number connected to this row.
|
||||||
|
* if strobe pin is on I/O expander (strobe for Scanner_IOE), then strobePin is bit pattern,
|
||||||
|
1 indicating the I/O expander pin connected to this row
|
||||||
*/
|
*/
|
||||||
/* ---------------- LEFT ROWS ------------------
|
/* ---------------- LEFT ROWS ------------------
|
||||||
The left rows have a Scanner_uC and Arduino pin numbers to strobe.
|
The left rows have a Scanner_uC and Arduino pin numbers to strobe.
|
||||||
|
@ -19,8 +19,8 @@ Steps to writing a new port class:
|
|||||||
5. Study other keybrd port classes.
|
5. Study other keybrd port classes.
|
||||||
* SPI I/O expander port classes: Port_MCP23S17
|
* SPI I/O expander port classes: Port_MCP23S17
|
||||||
* I2C I/O expander port classes: Port_PCA9655E
|
* I2C I/O expander port classes: Port_PCA9655E
|
||||||
6. Write the port classes for your I/O expander.
|
6. Write the port classes for your I/O expander. Debugging I/O expander code is hard because
|
||||||
Debugging I/O expander code is hard because SPI or I2C protocol adds a level of indirection.
|
SPI or I2C protocol, expander configuration, and expander commands.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<a rel="license" href="https://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">keybrd tutorial</span> by <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd" property="cc:attributionName" rel="cc:attributionURL">Wolfram Volpi</a> is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />Permissions beyond the scope of this license may be available at <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="https://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">keybrd tutorial</span> by <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd" property="cc:attributionName" rel="cc:attributionURL">Wolfram Volpi</a> is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />Permissions beyond the scope of this license may be available at <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/* unit test for Port_MCP23018
|
|
||||||
Picture of hardware is in unit_tests/PortMCP23018_read/PortMCP23018_bb.JPG todo
|
|
||||||
The setup is an MCP23018 I/O expander on a Teensy LC controller.
|
|
||||||
MCP23018 port-A GPIO pins are not connected to anything.
|
|
||||||
Port-A GPIO-pin ouputs alternate between 0 and 3.3 volts.
|
|
||||||
volt meter between pin A1 and power because
|
|
||||||
MCP23018 has open-drain outputs (open-drain can only sink current)
|
|
||||||
|
|
||||||
Use a volt meter to measure port-A GPIO-pin outputs or red LED.
|
|
||||||
*/
|
|
||||||
#include "Port_MCP23018.h"
|
|
||||||
|
|
||||||
const uint8_t IOE_ADDR = 0x20; //MCP23018 address ADDR pin grounded
|
|
||||||
Port_MCP23018 portA(IOE_ADDR, 0, 0);
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
delay(6000);
|
|
||||||
Keyboard.println("PortMCP23018_write.ino");
|
|
||||||
portA.beginProtocol();
|
|
||||||
portA.begin(LOW); //HIGH or LOW, not matter if readPins=0
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
portA.write(~0, HIGH); //set all GPIOA pins HIGH
|
|
||||||
Keyboard.print("+");
|
|
||||||
delay(2000);
|
|
||||||
|
|
||||||
portA.write(~0, LOW); //set all GPIOA pins LOW
|
|
||||||
Keyboard.print("0");
|
|
||||||
delay(2000);
|
|
||||||
}
|
|
Before Width: | Height: | Size: 165 KiB |
@ -1,25 +0,0 @@
|
|||||||
/* unit test for PortMCP23S17
|
|
||||||
Picture of hardware is in unit_tests/PortMCP23S17_read/PortMCP23S17_bb.JPG
|
|
||||||
The setup is an MCP23S17 I/O expander on a Teensy LC controller.
|
|
||||||
MCP23S17 port-B pins are alternately grounded and energized.
|
|
||||||
output is: 10101010
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Port_MCP23S17.h"
|
|
||||||
|
|
||||||
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins grounded
|
|
||||||
Port_MCP23S17 portB(IOE_ADDR, 1, ~0); //read all pins
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
uint8_t BitPattern; //reading of port B
|
|
||||||
|
|
||||||
delay(6000);
|
|
||||||
portB.begin(HIGH); //HIGH or LOW, does not matter
|
|
||||||
|
|
||||||
BitPattern = portB.read();
|
|
||||||
Keyboard.print("BitPattern = ");
|
|
||||||
Keyboard.println(BitPattern, BIN); //prints 10101010
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() { }
|
|
@ -1,29 +0,0 @@
|
|||||||
/* unit test for Port_MCP23S17
|
|
||||||
Picture of hardware is in unit_tests/PortMCP23S17_read/PortMCP23S17_bb.JPG
|
|
||||||
The setup is an MCP23S17 I/O expander on a Teensy LC controller.
|
|
||||||
MCP23S17 port-A GPIO pins are not connected to anything.
|
|
||||||
Port-A GPIO-pin ouputs alternate between 0 and 3.3 volts.
|
|
||||||
|
|
||||||
Use a volt meter to measure port-A GPIO-pin outputs or red LED.
|
|
||||||
*/
|
|
||||||
#include "Port_MCP23S17.h"
|
|
||||||
|
|
||||||
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins grounded
|
|
||||||
Port_MCP23S17 portA(IOE_ADDR , 0, 0); //PortAWrite needed for begin()
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
delay(6000);
|
|
||||||
Keyboard.println("start setup");
|
|
||||||
portA.begin(LOW); //HIGH or LOW, not matter if readPins=0
|
|
||||||
Keyboard.println("start loop");
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
portA.write(~0, HIGH); //set all GPIOA pins HIGH
|
|
||||||
delay(2000);
|
|
||||||
|
|
||||||
portA.write(~0, LOW); //set all GPIOA pins LOW
|
|
||||||
delay(2000);
|
|
||||||
}
|
|