Browse Source

fixed MCP23S17 port classes and keybrd_4c_split_with_IOE.ino

tags/v0.6.0
wolfv6 7 years ago
parent
commit
4b1b53a76a

+ 1
- 1
examples/keybrd_PCA9655E/keybrd_PCA9655E.ino View File

PortWrite_PCA9655E portWrite_R1(port_R1); PortWrite_PCA9655E portWrite_R1(port_R1);


PortIOE port_R0(0, 0); PortIOE port_R0(0, 0);
//PortWrite_PCA9655E portWrite_R0(port_R0); for LEDs
//PortWrite_PCA9655E portWrite_R0(port_R0); //for LEDs
PortRead_PCA9655E portRead_R0(port_R0, 1<<0 | 1<<1 ); PortRead_PCA9655E portRead_R0(port_R0, 1<<0 | 1<<1 );


Scanner_IOE scanner_R(HIGH, portWrite_R1, portRead_R0); Scanner_IOE scanner_R(HIGH, portWrite_R1, portRead_R0);

+ 2
- 13
src/PortIOE.h View File

http://playground.arduino.cc/Main/WireLibraryDetailedReference http://playground.arduino.cc/Main/WireLibraryDetailedReference
The PCA9655E data sheet is on http://www.onsemi.com/pub_link/Collateral/PCA9655E-D.PDF The PCA9655E data sheet is on http://www.onsemi.com/pub_link/Collateral/PCA9655E-D.PDF
portNumber: If the I/O expander uses port letters, use 0 instead of A, use 1 instead of B.
outputVal: For pins that are connected to active low rows, set outputVal bit to 1.
Set all other outputVal bits to 0.
Example instantiation for port0 with active low rows on all pins:
PortIOE port0(0, ~0);
Example instantiation for portA with active low rows on pins 0,1,2:
PortIOE portA(0, 1<<0 | 1<<1 | 1<<2 );
Example instantiation for portB with active high rows on pins 0,1,2:
PortIOE portB(1, 0);
portNumber: If the I/O expander uses port letters, use 0 inplace of A, use 1 inplace of B.
*/ */
struct PortIOE struct PortIOE
{ {
static const uint8_t DEVICE_ADDR; static const uint8_t DEVICE_ADDR;
const uint8_t num; //port number const uint8_t num; //port number
uint8_t outputVal; //bitwise value of output register
uint8_t outputVal; //bitwise value of output register for LEDs
PortIOE(const uint8_t portNumber, uint8_t outputVal) PortIOE(const uint8_t portNumber, uint8_t outputVal)
: num(portNumber), outputVal(outputVal) {} : num(portNumber), outputVal(outputVal) {}

+ 1
- 1
src/PortReadInterface.h View File

class PortReadInterface class PortReadInterface
{ {
public: public:
virtual void begin()=0;
virtual void begin(const uint8_t strobeOn)=0;
virtual uint8_t read()=0; virtual uint8_t read()=0;
}; };
#endif #endif

+ 12
- 12
src/PortRead_MCP23S17.cpp View File

#include "PortRead_MCP23S17.h" #include "PortRead_MCP23S17.h"
/* /*
SPI bus is configured in PortWrite_MCP23S17::begin().
begin() is called from Scanner_IOE::begin().
*/ */
void PortRead_MCP23S17::begin(const uint8_t strobeOn) void PortRead_MCP23S17::begin(const uint8_t strobeOn)
{ {
uint8_t pullUp; //bitwise, 1 means internal pull-up resistor enabled
if (strobeOn == LOW) //if active low if (strobeOn == LOW) //if active low
{ {
pullUp = readPins; pullUp = readPins;
pullUp = 0; pullUp = 0;
} }
Keyboard.print("\npullUp=");//todo
Keyboard.print(pullUp);
/*
//todo these 4 lines are duplicated in PortWrite_MCP23S17::begin(), which is called first
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output
digitalWrite(SS, HIGH); //disable Slave Select digitalWrite(SS, HIGH); //disable Slave Select
SPI.begin(); SPI.begin();
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed? SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed?
//SPI.endTransaction() not called to release SPI bus because keyboard only has one SPI device.
*/
digitalWrite(SS, LOW); //enable Slave Select digitalWrite(SS, LOW); //enable Slave Select
SPI.transfer(port.DEVICE_ADDR << 1); //write command
SPI.transfer(port.DEVICE_ADDR << 1); //write command
SPI.transfer(port.num); //configure IODIR SPI.transfer(port.num); //configure IODIR
SPI.transfer(readPins); //0=output (for LED), 1=input (for read) SPI.transfer(readPins); //0=output (for LED), 1=input (for read)
digitalWrite(SS, LOW); //enable Slave Select
digitalWrite(SS, HIGH); //enable Slave Select
digitalWrite(SS, HIGH); //disable Slave Select
SPI.transfer(port.DEVICE_ADDR << 1); //write command
digitalWrite(SS, LOW); //disable Slave Select
SPI.transfer(port.DEVICE_ADDR << 1); //write command
SPI.transfer(port.num + 0x0C); //configure GPPU SPI.transfer(port.num + 0x0C); //configure GPPU
SPI.transfer(pullUp); //0=pull-up disabled (for LED), 1=pull-up enabled (for read) SPI.transfer(pullUp); //0=pull-up disabled (for LED), 1=pull-up enabled (for read)
digitalWrite(SS, HIGH); //disable Slave Select digitalWrite(SS, HIGH); //disable Slave Select
//SPI.endTransaction() is not called to release the SPI bus
// because keyboard only has one SPI device.
} }
/* /*
uint8_t portState; //bit wise uint8_t portState; //bit wise
digitalWrite(SS, LOW); //enable Slave Select digitalWrite(SS, LOW); //enable Slave Select
SPI.transfer(port.DEVICE_ADDR << 1 | 1); //read command
SPI.transfer(port.DEVICE_ADDR << 1 | 1); //read command
SPI.transfer(port.num + 0x12); //GPIO register address to read data from SPI.transfer(port.num + 0x12); //GPIO register address to read data from
portState = SPI.transfer(0); //save the data (0 is dummy data to send) portState = SPI.transfer(0); //save the data (0 is dummy data to send)
digitalWrite(SS, HIGH); //disable Slave Select digitalWrite(SS, HIGH); //disable Slave Select

+ 3
- 1
src/PortRead_MCP23S17.h View File

{ {
private: private:
PortIOE& port; PortIOE& port;
uint8_t pullUp; //bitwise, 1 means internal pull-up resistor enabled
const uint8_t readPins; //bitwise, 1 means internal pull-up resistor enabled const uint8_t readPins; //bitwise, 1 means internal pull-up resistor enabled
public: public:
PortRead_MCP23S17(PortIOE& port, const uint8_t readPins) : port(port), readPins(readPins) {}
PortRead_MCP23S17(PortIOE& port, const uint8_t readPins)
: port(port), readPins(readPins) {}
void begin(const uint8_t strobeOn); void begin(const uint8_t strobeOn);
virtual uint8_t read(); virtual uint8_t read();
}; };

+ 3
- 1
src/PortRead_PCA9655E.cpp View File

#include "PortRead_PCA9655E.h" #include "PortRead_PCA9655E.h"
void PortRead_PCA9655E::begin()
/*
*/
void PortRead_PCA9655E::begin(const uint8_t strobeOn)
{ {
Wire.beginTransmission(port.DEVICE_ADDR); Wire.beginTransmission(port.DEVICE_ADDR);
Wire.write(port.num + 6); //configuration byte command Wire.write(port.num + 6); //configuration byte command

+ 1
- 1
src/PortRead_PCA9655E.h View File

public: public:
PortRead_PCA9655E (PortIOE& port, const uint8_t readPins) PortRead_PCA9655E (PortIOE& port, const uint8_t readPins)
: port(port), readPins(readPins) {} : port(port), readPins(readPins) {}
void begin();
void begin(const uint8_t strobeOn);
virtual uint8_t read(); virtual uint8_t read();
}; };
#endif #endif

+ 1
- 1
src/PortWriteInterface.h View File

{ {
public: public:
virtual void begin()=0; virtual void begin()=0;
virtual void write(const uint8_t pin, const bool level)=0;
virtual void write(const uint8_t strobePin, const bool pinLogicLevel)=0;
}; };
#endif #endif

+ 6
- 8
src/PortWrite_MCP23S17.cpp View File

void PortWrite_MCP23S17::writePort(const uint8_t registerAddr, const uint8_t data) void PortWrite_MCP23S17::writePort(const uint8_t registerAddr, const uint8_t data)
{ {
digitalWrite(SS, LOW); //enable Slave Select digitalWrite(SS, LOW); //enable Slave Select
SPI.transfer(port.DEVICE_ADDR << 1); //write command
SPI.transfer(port.DEVICE_ADDR << 1); //write command
SPI.transfer(registerAddr); //register address to write data to SPI.transfer(registerAddr); //register address to write data to
SPI.transfer(data); //data SPI.transfer(data); //data
digitalWrite(SS, HIGH); //disable Slave Select digitalWrite(SS, HIGH); //disable Slave Select
} }
/* begin() should be called once from sketch in setup().
/* begin() is called from Scanner_IOE::begin(). Initiates SPI bus and configures write pins.
PortRead_MCP23S17 and PortWrite_MCP23S17 should be on seperate ports on the same MCP23S17. PortRead_MCP23S17 and PortWrite_MCP23S17 should be on seperate ports on the same MCP23S17.
Output pins can be used for strobe pins and LEDs. Output pins can be used for strobe pins and LEDs.
*/ */
digitalWrite(SS, HIGH); //disable Slave Select digitalWrite(SS, HIGH); //disable Slave Select
SPI.begin(); SPI.begin();
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed? SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed?
//SPI.endTransaction() not called to release SPI bus because keyboard only has one SPI device.
writePort(port.num, 0); //configure port direction (port.num) to output (0) writePort(port.num, 0); //configure port direction (port.num) to output (0)
//SPI.endTransaction() is not called to release the SPI bus
// because keyboard only has one SPI device.
} }
/* /*
strobePin is bitwise, where pin being strobed is 1. strobePin is bitwise, where pin being strobed is 1.
pinLogicLevel is HIGH or LOW. pinLogicLevel is HIGH or LOW.
port.outputVal can be shared by LEDs. port.outputVal can be shared by LEDs.
The functions does not reset the other pins so that they can be used for LEDs.
The function does not reset the other pins so that they can be used for LEDs.
*/ */
void PortWrite_MCP23S17::write(const uint8_t strobePin, const uint8_t pinLogicLevel)
void PortWrite_MCP23S17::write(const uint8_t strobePin, const bool pinLogicLevel)
{ {
if (pinLogicLevel == LOW) if (pinLogicLevel == LOW)
{ {
port.outputVal |= strobePin; //set strobePin output to high port.outputVal |= strobePin; //set strobePin output to high
} }
writePort(port.num + 0x12, port.outputVal); //set GPIO port pins for stobe and LEDs
writePort(port.num + 0x12, port.outputVal); //set GPIO port pins for strobe and LEDs
} }

+ 1
- 1
src/PortWrite_MCP23S17.h View File

public: public:
PortWrite_MCP23S17(PortIOE& port) : port(port) {} PortWrite_MCP23S17(PortIOE& port) : port(port) {}
void begin(); void begin();
virtual void write(const uint8_t pin, const uint8_t level);
virtual void write(const uint8_t pin, const bool pinLogicLevel);
}; };
#endif #endif

+ 9
- 7
src/PortWrite_PCA9655E.cpp View File

*/ */
void PortWrite_PCA9655E::begin() void PortWrite_PCA9655E::begin()
{ {
Wire.begin();
Wire.beginTransmission(port.DEVICE_ADDR); Wire.beginTransmission(port.DEVICE_ADDR);
Wire.write(port.num + 6); //configuration byte command Wire.write(port.num + 6); //configuration byte command
Wire.write(0); //0=configure as output (for strobe pins and LED) Wire.write(0); //0=configure as output (for strobe pins and LED)
} }
/* /*
pin is bitwise, where pin being strobed is 1.
value is HIGH or LOW.
strobePin is bitwise, where pin being strobed is 1.
pinLogicLevel is HIGH or LOW.
Does not reset the other pins because LEDs could be using some of the pins. Does not reset the other pins because LEDs could be using some of the pins.
Syntax is similar to Arduino DigitalWrite(). Syntax is similar to Arduino DigitalWrite().
*/ */
void PortWrite_PCA9655E::write(const uint8_t pin, const bool value)
void PortWrite_PCA9655E::write(const uint8_t strobePin, const bool pinLogicLevel)
{ {
if (value == LOW) //if active low
if (pinLogicLevel == LOW) //if strobePin low
{ {
port.outputVal &= ~pin; //set pin output to low
port.outputVal &= ~strobePin; //set pin output to low
} }
else //if active high
else //if strobestrobe high
{ {
port.outputVal |= pin; //set pin output to high
port.outputVal |= strobePin; //set pin output to high
} }
Wire.beginTransmission(port.DEVICE_ADDR); Wire.beginTransmission(port.DEVICE_ADDR);

+ 1
- 1
src/PortWrite_PCA9655E.h View File

PortWrite_PCA9655E(PortIOE& port) : port(port) {} PortWrite_PCA9655E(PortIOE& port) : port(port) {}
void begin(); void begin();
virtual void write(const uint8_t pin, const bool level);
virtual void write(const uint8_t strobePin, const bool pinLogicLevel);
}; };
#endif #endif

+ 10
- 6
src/Scanner_IOE.cpp View File

#include "Scanner_IOE.h" #include "Scanner_IOE.h"


/* Row constructor calls every Scanner's init().
/* init() is called once for each row from Row constructor.
*/ */
void Scanner_IOE::init(const uint8_t strobePin) void Scanner_IOE::init(const uint8_t strobePin)
{ {
//emty function
//empty
} }


/* begin() should be called once from sketch setup(). /* begin() should be called once from sketch setup().
*/ */
void Scanner_IOE::begin() void Scanner_IOE::begin()
{ {
Wire.begin();
refPortWrite.begin();
refPortRead.begin();
refPortWrite.begin(); //configures SPI bus
refPortRead.begin(strobeOn);
} }


/* scan() strobes the row's strobePin and retuns state of port's input pins.
/* scan() is called on every iteration of sketch loop().
scan() strobes the row's strobePin and retuns state of port's input pins.
Bitwise variables are 1 bit per key. Bitwise variables are 1 bit per key.
*/ */
read_pins_t Scanner_IOE::scan(const uint8_t strobePin) read_pins_t Scanner_IOE::scan(const uint8_t strobePin)
//strobe off //strobe off
refPortWrite.write(strobePin, strobeOff); refPortWrite.write(strobePin, strobeOff);


if (strobeOn == LOW) //if active low
{
readState = ~readState;
}
return readState; return readState;
} }

+ 0
- 1
src/Scanner_IOE.h View File



#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <Wire.h>
#include <ScannerInterface.h> #include <ScannerInterface.h>
#include <PortWriteInterface.h> #include <PortWriteInterface.h>
#include <PortReadInterface.h> #include <PortReadInterface.h>

+ 1
- 1
src/Scanner_ShiftRegsPISOSingleRow.h View File

In the above example, the "strobePin" argument is 0, but it doesn't matter what value is given. In the above example, the "strobePin" argument is 0, but it doesn't matter what value is given.


There are three Scanner_ShiftRegsPISOSingleRow parameters. There are three Scanner_ShiftRegsPISOSingleRow parameters.
"strobeOn" paramter is active state HIGH or LOW.
"strobeOn" paramter is ignored, but should be active state HIGH or LOW required by ScannerInterface.


"slaveSelect" paramter can be any controller pin connected to shift register's SHIFT-LOAD pin. "slaveSelect" paramter can be any controller pin connected to shift register's SHIFT-LOAD pin.
slaveSelect pin SS (Arduino pin 10) has the fastest scan. slaveSelect pin SS (Arduino pin 10) has the fastest scan.

+ 2
- 1
src/Scanner_uC.cpp View File

pinMode(strobePin, OUTPUT); pinMode(strobePin, OUTPUT);
} }


/* scan() strobes the row's strobePin and retuns state of readPins.
/* scan() is called on every iteration of sketch loop().
scan() strobes the row's strobePin and retuns state of readPins.
Bitwise variables are 1 bit per key. Bitwise variables are 1 bit per key.
*/ */
read_pins_t Scanner_uC::scan(const uint8_t strobePin) read_pins_t Scanner_uC::scan(const uint8_t strobePin)

+ 2
- 2
src/config_keybrd.h View File

For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::readPinCount For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::readPinCount
For Scanner_IOE, cover the last 1 bit in Scanner_IOE::strobePin For Scanner_IOE, cover the last 1 bit in Scanner_IOE::strobePin
*/ */
typedef uint8_t read_pins_t;
//typedef uint8_t read_pins_t;
//typedef uint16_t read_pins_t; //typedef uint16_t read_pins_t;
//typedef uint32_t read_pins_t;
typedef uint32_t read_pins_t;


/* SAMPLE_COUNT_MACRO is used in Debouncer_Samples.h /* SAMPLE_COUNT_MACRO is used in Debouncer_Samples.h
SAMPLE_COUNT_MACRO = 4 is very reliable for a keyboard. SAMPLE_COUNT_MACRO = 4 is very reliable for a keyboard.

+ 29
- 38
tutorials/keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino View File



| Left | **0** | **1** | | Right | **0** | **1** | | Left | **0** | **1** | | Right | **0** | **1** |
|:-----:|-------|-------| |:-----:|-------|-------| |:-----:|-------|-------| |:-----:|-------|-------|
| **0** | a | b | | **0** | 1 | 2 |
| **1** | shift | c | | **1** | 3 | shift |

| Left | **0** | **1** | | Right | **0** | **1** | todo
|:-----:|-------|-------| |:-----:|-------|-------|
| **1** | 1 | 2 | | **1** | 3 | 4 | | **1** | 1 | 2 | | **1** | 3 | 4 |
| **0** | a | b | | **0** | c | d | | **0** | a | b | | **0** | c | d |
*/ */
// ================= INCLUDES ================== // ================= INCLUDES ==================
#include <ScanDelay.h> #include <ScanDelay.h>
#include <Code_Sc.h> #include <Code_Sc.h>
#include <Row.h>


//left matrix //left matrix
#include <Row_uC.h>
#include <Scanner_uC.h>


//right matrix //right matrix
#include <Row_IOE.h>
#include <PortIOE.h> #include <PortIOE.h>
#include <PortWrite_MCP23S17.h> #include <PortWrite_MCP23S17.h>
#include <PortRead_MCP23S17.h> #include <PortRead_MCP23S17.h>
#include <Scanner_IOE.h>


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


// ================ LEFT MATRIX ================
// ---------------- ACTIVE STATE ---------------
const bool Scanner_uC::STROBE_ON = LOW; //active low
const bool Scanner_uC::STROBE_OFF = HIGH;

// ------------------- PINS --------------------
// ================ LEFT SCANNER ===============
uint8_t readPins[] = {14, 15}; uint8_t readPins[] = {14, 15};
uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);


// ================ RIGHT MATRIX ===============
const bool Scanner_Port::STROBE_ON = HIGH; //active high
const bool Scanner_Port::STROBE_OFF = LOW;
Scanner_uC scanner_L(LOW, readPins, readPinCount);


const uint8_t PortIOE::DEVICE_ADDR = 0x18;
// =============== RIGHT SCANNER ===============
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded


// ------------------ PORT 1 -------------------
PortIOE port1_R(1, 0);
PortWrite_MCP23S17 portWrite1_R(port1_R);
PortIOE port_A(0, 0);
PortRead_MCP23S17 portRead_A(port_A, 1<<0 | 1<<1 );


// ------------------ PORT 0 -------------------
PortIOE port0_R(0, 0);
PortWrite_MCP23S17 portWrite0_R(port0_R);
PortRead_MCP23S17 portRead0_R(port0_R, 1<<0 | 1<<1 );
PortIOE port_B(1, 0);
//PortWrite_MCP23S17 portWrite_B(port_B); //for LEDs
PortWrite_MCP23S17 portWrite_B(port_B);


// =================== CODES ===================
Code_Sc s_shiftL(MODIFIERKEY_LEFT_SHIFT);
Code_Sc s_shiftR(MODIFIERKEY_RIGHT_SHIFT);
Scanner_IOE scanner_R(LOW, portWrite_B, portRead_A);


// =================== CODES ===================
Code_Sc s_a(KEY_A); Code_Sc s_a(KEY_A);
Code_Sc s_b(KEY_B); Code_Sc s_b(KEY_B);
Code_Sc s_c(KEY_C); Code_Sc s_c(KEY_C);
Code_Sc s_d(KEY_D);

Code_Sc s_1(KEY_1); Code_Sc s_1(KEY_1);
Code_Sc s_2(KEY_2); Code_Sc s_2(KEY_2);
Code_Sc s_3(KEY_3); Code_Sc s_3(KEY_3);
Code_Sc s_4(KEY_4);


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


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


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


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


// ################### MAIN #################### // ################### MAIN ####################
void setup() void setup()
{ {
delay(7000); //todo
Keyboard.begin(); Keyboard.begin();
Wire.begin(); //Wire.begin() must be called before port begin()
portWrite1_R.begin();
portRead0_R.begin();
scanner_R.begin();
} }


void loop() void loop()
scanDelay.delay(); scanDelay.delay();
//debug.print_scans_per_second(); //debug.print_scans_per_second();
//debug.print_microseconds_per_scan(); //debug.print_microseconds_per_scan();
delay(100); //todo
} }

+ 4
- 8
unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino View File

/* unit test for PortRead_MCP23S17 /* unit test for PortRead_MCP23S17
Picture of hardware is in unit_tests/PortRead_MCP23S17/PortRead_MCP23S17_bb.JPG
The setup is an MCP23S17 I/O expander on a Teensy LC controller. The setup is an MCP23S17 I/O expander on a Teensy LC controller.
MCP23S17 port-B pins are alternately grounded and energized. MCP23S17 port-B pins are alternately grounded and energized.
portBState is a bitwise reading of port B. portBState is a bitwise reading of port B.
output is: 10101010 output is: 10101010

posted on http://arduino.stackexchange.com/questions/tagged/spi
http://arduino.stackexchange.com/questions/28792/reading-an-mcp23s17-i-o-expander-port-with-the-arduino-spi-library
*/ */

#include "PortIOE.h" #include "PortIOE.h"
#include "PortRead_MCP23S17.h" #include "PortRead_MCP23S17.h"
#include "Scanner_Port.h"

const bool Scanner_Port::STROBE_ON = LOW;
const bool Scanner_Port::STROBE_OFF = HIGH;
#include "Scanner_IOE.h"


const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
PortIOE portB(1, 0); PortIOE portB(1, 0);
uint8_t portBState; //bit wise uint8_t portBState; //bit wise


delay(6000); delay(6000);
portBRead.begin();
portBRead.begin(LOW);


portBState = portBRead.read(); portBState = portBRead.read();
Keyboard.print("portBState = "); Keyboard.print("portBState = ");

BIN
unit_tests/PortRead_MCP23S17/PortRead_MCP23S17_bb.JPG View File


unit_tests/PortWrite_MCP23S17/PortRead_MCP23S17.ino → unit_tests/PortWrite_MCP23S17/PortWrite_MCP23S17.ino View File

/* unit test for PortRead_MCP23S17
/* unit test for PortWrite_MCP23S17
Picture of hardware is in unit_tests/PortRead_MCP23S17/PortRead_MCP23S17_bb.JPG
The setup is an MCP23S17 I/O expander on a Teensy LC controller. The setup is an MCP23S17 I/O expander on a Teensy LC controller.
MCP23S17 port-A GPIO pins are not connected to anything. MCP23S17 port-A GPIO pins are not connected to anything.
Port-A GPIO-pin ouputs alternate between 0 and 3.3 volts. Port-A GPIO-pin ouputs alternate between 0 and 3.3 volts.


Use a volt meter to measure port-A GPIO-pin ouputs.
Use a volt meter to measure port-A GPIO-pin outputs.
MCP23S17 on 3.3v does not output enough power to reliable light LEDs MCP23S17 on 3.3v does not output enough power to reliable light LEDs
LED lights w/o resistor LED lights w/o resistor
LED not light with 56 ohm resistor LED not light with 56 ohm resistor


PortWrite_MCP23S17 portAWrite(portA); //PortAWrite needed for begin() PortWrite_MCP23S17 portAWrite(portA); //PortAWrite needed for begin()


const uint8_t GPIOA = 0x12; //LEDs are on port A
//const uint8_t GPIOA = 0x12; //LEDs are on port A


void setup() void setup()
{ {