combined PortWrite_MCP23S17 and PortRead_MCP23S17 into Port_MCP23S17
This commit is contained in:
parent
7a9228e7dc
commit
59565dacb4
@ -187,6 +187,13 @@ Hardware items to check:
|
|||||||
* Diode orientation
|
* Diode orientation
|
||||||
* To validate keyboard hardware, modify the simple [keybrd_1_breadboard.ino](../tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino) sketch.
|
* To validate keyboard hardware, modify the simple [keybrd_1_breadboard.ino](../tutorials/keybrd_1_breadboard/keybrd_1_breadboard.ino) sketch.
|
||||||
|
|
||||||
|
Debugging:
|
||||||
|
Arduino doesn't have a debugger. You can print values like this:
|
||||||
|
Keyboard.print(" var="); Keyboard.print(var);
|
||||||
|
Keyboard.print(" bitPattern="); Keyboard.println(bitPattern, BIN);
|
||||||
|
delay(200);
|
||||||
|
The delay is so prints in a loop don't print too fast.
|
||||||
|
|
||||||
Keybrd nomenclature
|
Keybrd nomenclature
|
||||||
-------------------
|
-------------------
|
||||||
**[scancode](http://en.wikipedia.org/wiki/Scancode)** -
|
**[scancode](http://en.wikipedia.org/wiki/Scancode)** -
|
||||||
|
@ -4,19 +4,19 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <LED.h>
|
#include <LED.h>
|
||||||
#include <PortWriteInterface.h>
|
#include <PortInterface.h>
|
||||||
|
|
||||||
/* A LED_IOE object is an I/O expander pin that is connected to an LED indicator light.
|
/* A LED_IOE object is an I/O expander pin that is connected to an LED indicator light.
|
||||||
Input/Ouput Direction configuration are set to ouput in PortWrite_*.begin() and PortRead_*.begin(). todo PortRead_*??
|
Input/Ouput Direction configuration are set to ouput in PortWrite_*.begin() and PortRead_*.begin(). todo PortRead_*??
|
||||||
*/
|
*/
|
||||||
class LED_IOE: public LED
|
class LED_IOE : public LED
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
PortWriteInterface& refPort;
|
PortInterface& refPort;
|
||||||
const uint8_t pin; //bit pattern, 1 is IOE pin to LED
|
const uint8_t pin; //bit pattern, 1 is IOE pin to LED
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LED_IOE(PortWriteInterface& refPort, const uint8_t pin)
|
LED_IOE(PortInterface& refPort, const uint8_t pin)
|
||||||
: refPort(refPort), pin(pin) {}
|
: refPort(refPort), pin(pin) {}
|
||||||
virtual void on();
|
virtual void on();
|
||||||
virtual void off();
|
virtual void off();
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
#include "LED_PCA9655E.h"
|
|
||||||
|
|
||||||
void LED_PCA9655E::on()
|
|
||||||
{
|
|
||||||
refPort.write(pin, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LED_PCA9655E::off()
|
|
||||||
{
|
|
||||||
refPort.write(pin, LOW);
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef LED_PCA9655E_H
|
|
||||||
#define LED_PCA9655E_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <Wire.h>
|
|
||||||
#include <LED.h>
|
|
||||||
#include <PortWrite_PCA9655E.h>
|
|
||||||
|
|
||||||
/* A LED_PCA9655E object is an PCA9655E pin that is connected to an LED indicator light.
|
|
||||||
Input/Ouput Direction configuration are set to ouput in PortWrite_PCA9655E.begin() and PortRead_PCA9655E.begin().
|
|
||||||
*/
|
|
||||||
class LED_PCA9655E: public LED
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
//PortIOE& port;
|
|
||||||
//const uint8_t outputByteCommand; //General Purpose Input/Ouput register address
|
|
||||||
PortWrite_PCA9655E& refPort;
|
|
||||||
const uint8_t pin; //bit pattern, IOE pin to LED
|
|
||||||
|
|
||||||
public:
|
|
||||||
LED_PCA9655E(PortWrite_PCA9655E& refPort, const uint8_t pin)
|
|
||||||
: refPort(refPort), pin(pin) {}
|
|
||||||
|
|
||||||
virtual void on();
|
|
||||||
virtual void off();
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -1,15 +1,16 @@
|
|||||||
#ifndef PORTREADINTERFACE_H
|
#ifndef PORTINTERFACE_H
|
||||||
#define PORTREADINTERFACE_H
|
#define PORTINTERFACE_H
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Port classes are the keybrd library's interface to microcontroller ports or I/O expander ports.
|
Port classes are the keybrd library's interface to microcontroller ports or I/O expander ports.
|
||||||
*/
|
*/
|
||||||
class PortReadInterface
|
class PortInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void begin(const uint8_t strobeOn)=0;
|
virtual void begin(const uint8_t strobeOn)=0;
|
||||||
|
virtual void write(const uint8_t strobePin, const bool pinLogicLevel)=0;
|
||||||
virtual uint8_t read()=0;
|
virtual uint8_t read()=0;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
@ -14,3 +14,71 @@ uint8_t PortMCP23S17::transfer(const uint8_t command, const uint8_t registerAddr
|
|||||||
|
|
||||||
return portState;
|
return portState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* begin() is called from Scanner_IOE::begin().
|
||||||
|
Initiates SPI bus and configures I/O pins for read and write.
|
||||||
|
strobeOn is logic level of strobe on, HIGH or LOW
|
||||||
|
|
||||||
|
MCP23S17 SPI interface is 10 MHz max.
|
||||||
|
The electrical limitation to bus speed is bus capacitance and the length of the wires involved.
|
||||||
|
Longer wires require lower clock speeds.
|
||||||
|
*/
|
||||||
|
void PortMCP23S17::begin(const uint8_t strobeOn)
|
||||||
|
{
|
||||||
|
uint8_t pullUp; //bits, GPPU 0=pull-up disabled, 1=pull-up enabled
|
||||||
|
|
||||||
|
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output
|
||||||
|
digitalWrite(SS, HIGH); //disable Slave Select
|
||||||
|
SPI.begin();
|
||||||
|
SPI.beginTransaction(SPISettings (5000000, MSBFIRST, SPI_MODE0)); //control SPI bus, 5 MHz
|
||||||
|
//SPI.endTransaction() not called to release SPI bus because keyboard only has one SPI device
|
||||||
|
|
||||||
|
if (strobeOn == LOW) //if active low, use internal pull-up resistors
|
||||||
|
{
|
||||||
|
pullUp = readPins;
|
||||||
|
}
|
||||||
|
else //active high requires external pull-down resistors
|
||||||
|
{
|
||||||
|
pullUp = 0;
|
||||||
|
}
|
||||||
|
//todo
|
||||||
|
Keyboard.print(" strobeOn="); Keyboard.print(strobeOn);
|
||||||
|
Keyboard.print(" readPins="); Keyboard.print(readPins, BIN);
|
||||||
|
Keyboard.print(" pullUp="); Keyboard.println(pullUp, BIN);
|
||||||
|
|
||||||
|
transfer(port.DEVICE_ADDR << 1, port.num, readPins); //configure IODIR
|
||||||
|
transfer(port.DEVICE_ADDR << 1, port.num + 0x0C, pullUp); //configure GPPU
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write() sets pin output to logicLevel (useful for strobePin, one LED pin, or multiple pins).
|
||||||
|
pin is bit pattern, where pin being set is 1.
|
||||||
|
logicLevel is HIGH or LOW.
|
||||||
|
write() does not overwrite the other pins.
|
||||||
|
*/
|
||||||
|
void PortMCP23S17::write(const uint8_t pin, const bool logicLevel)
|
||||||
|
{
|
||||||
|
if (logicLevel == LOW)
|
||||||
|
{
|
||||||
|
port.outputVal &= ~pin; //set pin output to low
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port.outputVal |= pin; //set pin output to high
|
||||||
|
}
|
||||||
|
//todo
|
||||||
|
//Keyboard.print(" readPins="); Keyboard.print(readPins, BIN);
|
||||||
|
Keyboard.print(" pin="); Keyboard.print(pin, BIN);
|
||||||
|
Keyboard.print(" logicLevel="); Keyboard.print(logicLevel);
|
||||||
|
Keyboard.print(" outputVal="); Keyboard.println(port.outputVal, BIN);
|
||||||
|
//Keyboard.print(" ="); Keyboard.print();
|
||||||
|
//delay(200);
|
||||||
|
|
||||||
|
transfer(port.DEVICE_ADDR << 1, port.num + 0x12, port.outputVal); //set GPIO port to outputVal
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read() returns portState. Only portState pins with pull resistors are valid.
|
||||||
|
*/
|
||||||
|
uint8_t PortMCP23S17::read()
|
||||||
|
{
|
||||||
|
return transfer( (port.DEVICE_ADDR << 1) | 1, port.num + 0x12, 0); //read from GPIO
|
||||||
|
}
|
||||||
|
@ -3,10 +3,47 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
#include <PortIOE.h>
|
||||||
|
#include <PortInterface.h>
|
||||||
|
|
||||||
class PortMCP23S17
|
/*
|
||||||
|
readPins are connected to matrix col
|
||||||
|
write pin is connected to matrix Row (strobe pin) or LED.
|
||||||
|
|
||||||
|
Slave Select is hardcoded to Arduino Pin 10.
|
||||||
|
Arduino Pin 10 avoids the speed penalty of digitalWrite.
|
||||||
|
|
||||||
|
Instantiation
|
||||||
|
------------
|
||||||
|
readPins parameter is configures port's pins.
|
||||||
|
Example instantiation:
|
||||||
|
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
||||||
|
|
||||||
|
PortIOE port_B(1);
|
||||||
|
Port_MCP23S17 portWrite_B(port_B, 0); //all pins are set to output for strobes and LEDs
|
||||||
|
|
||||||
|
PortIOE port_A(0);
|
||||||
|
Port_MCP23S17 portRead_A(port_A, 1<<0 | 1<<1 ); //pins 0,1 are set to input for reading,
|
||||||
|
//remaining pins can be used for LEDs
|
||||||
|
|
||||||
|
Diode orientation
|
||||||
|
----------------
|
||||||
|
Diode orientation is explained in keybrd_library_user_guide.md > Diode orientation
|
||||||
|
|
||||||
|
MCP23S17 data sheet
|
||||||
|
------------------
|
||||||
|
http://www.onsemi.com/pub_link/Collateral/MCP23S17-D.PDF
|
||||||
|
*/
|
||||||
|
class PortMCP23S17 : public PortInterface
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
|
PortIOE& port;
|
||||||
|
const uint8_t readPins; //bits, IODIR 0=output, 1=input
|
||||||
uint8_t transfer(const uint8_t command, const uint8_t registerAddr, const uint8_t data);
|
uint8_t transfer(const uint8_t command, const uint8_t registerAddr, const uint8_t data);
|
||||||
|
public:
|
||||||
|
PortMCP23S17(PortIOE& port, const uint8_t readPins) : port(port), readPins(readPins) {}
|
||||||
|
void begin(const uint8_t strobeOn);
|
||||||
|
virtual void write(const uint8_t pin, const bool logicLevel);
|
||||||
|
virtual uint8_t read();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#include "PortRead_MCP23S17.h"
|
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin().
|
|
||||||
Configures read pins to input with pullup enabled.
|
|
||||||
*/
|
|
||||||
void PortRead_MCP23S17::begin(const uint8_t strobeOn)
|
|
||||||
{
|
|
||||||
if (strobeOn == LOW) //if active low, use internal pull-up resistors
|
|
||||||
{
|
|
||||||
pullUp = readPins;
|
|
||||||
}
|
|
||||||
else //active high requires external pull-down resistors
|
|
||||||
{
|
|
||||||
pullUp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer(port.DEVICE_ADDR << 1, port.num, readPins); //write, configure IODIR, 0=output, 1=input
|
|
||||||
transfer(port.DEVICE_ADDR << 1, port.num + 0x0C, pullUp); //write, configure GPPU,
|
|
||||||
//0=pull-up disabled, 1=pull-up enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read() returns portState. Only portState pins with pull resistors are valid.
|
|
||||||
*/
|
|
||||||
uint8_t PortRead_MCP23S17::read()
|
|
||||||
{
|
|
||||||
return transfer( (port.DEVICE_ADDR << 1) | 1, port.num + 0x12, 0); //read from GPIO
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
#ifndef PORTREAD_MCP23S17_H
|
|
||||||
#define PORTREAD_MCP23S17_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <PortReadInterface.h>
|
|
||||||
#include "PortMCP23S17.h"
|
|
||||||
#include "PortIOE.h"
|
|
||||||
#include "Scanner_IOE.h"
|
|
||||||
|
|
||||||
/* One MCP23S17 I/O expander port connected to matrix columns.
|
|
||||||
|
|
||||||
This class has Slave Select hardcoded to Arduino Pin 10.
|
|
||||||
Arduino Pin 10 avoids the speed penalty of digitalWrite.
|
|
||||||
|
|
||||||
Instantiation
|
|
||||||
------------
|
|
||||||
readPins parameter is port's bit pattern pin configuration
|
|
||||||
1=configure as input (for read pins connected to column)
|
|
||||||
0=configure as output (for LED or not connected to a column)
|
|
||||||
readPins are read from pin 0 on up.
|
|
||||||
|
|
||||||
Example instantiation with port-A pins 0 and 1 connected to Scanner_IOE columns:
|
|
||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
|
||||||
PortIOE port_A(0);
|
|
||||||
PortRead_MCP23S17 portRead_A(port_A, 1<<0 | 1<<1 );
|
|
||||||
|
|
||||||
Diode orientation
|
|
||||||
----------------
|
|
||||||
Diode orientation is explained in keybrd_library_user_guide.md > Diode orientation
|
|
||||||
|
|
||||||
MCP23S17 data sheet
|
|
||||||
------------------
|
|
||||||
http://www.onsemi.com/pub_link/Collateral/MCP23S17-D.PDF
|
|
||||||
*/
|
|
||||||
class PortRead_MCP23S17 : public PortReadInterface, public PortMCP23S17
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
PortIOE& port;
|
|
||||||
uint8_t pullUp; //bits, 1 means internal pull-up resistor enabled
|
|
||||||
const uint8_t readPins; //bits, 1 means internal pull-up resistor enabled
|
|
||||||
public:
|
|
||||||
PortRead_MCP23S17(PortIOE& port, const uint8_t readPins)
|
|
||||||
: port(port), readPins(readPins) {}
|
|
||||||
void begin(const uint8_t strobeOn);
|
|
||||||
virtual uint8_t read();
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||||||
#include "PortRead_PCA9655E.h"
|
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin().
|
|
||||||
Configures read pins to input.
|
|
||||||
*/
|
|
||||||
void PortRead_PCA9655E::begin(const uint8_t strobeOn)
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(port.DEVICE_ADDR);
|
|
||||||
Wire.write(port.num + 6); //configuration byte command
|
|
||||||
Wire.write(readPins); //0=output (for LED), 1=input (for read)
|
|
||||||
Wire.endTransmission();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read() returns portState.
|
|
||||||
Only portState bits of readPins are valid.
|
|
||||||
*/
|
|
||||||
uint8_t PortRead_PCA9655E::read()
|
|
||||||
{
|
|
||||||
Wire.beginTransmission(port.DEVICE_ADDR);
|
|
||||||
Wire.write(port.num); //input byte command
|
|
||||||
Wire.endTransmission(false); //PCA9655E needs false to send a restart
|
|
||||||
|
|
||||||
Wire.requestFrom(port.DEVICE_ADDR, 1u); //request one byte from input port
|
|
||||||
|
|
||||||
return Wire.read();
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#ifndef PORTREAD_PCA9655E_H
|
|
||||||
#define PORTREAD_PCA9655E_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <Wire.h>
|
|
||||||
#include <PortReadInterface.h>
|
|
||||||
#include "PortIOE.h"
|
|
||||||
|
|
||||||
/* One PCA9655E I/O expander port connected to matrix columns.
|
|
||||||
PCA9655E does not have internal pull-up resistors (PCA9535E does).
|
|
||||||
|
|
||||||
Instantiation
|
|
||||||
------------
|
|
||||||
readPins parameter is bit pattern for port's pin configuration
|
|
||||||
1=configure as input (for pins connected to column)
|
|
||||||
0=configure as output (for LED or not connected to a column)
|
|
||||||
readPins are read from pin 0 on up.
|
|
||||||
|
|
||||||
Example instantiation for column port 1, with pins 2 and 3 connected to columns:
|
|
||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //PCA9655E address, all 3 ADDR pins are grounded
|
|
||||||
PortIOE port1(1);
|
|
||||||
PortRead_PCA9655E colPort1(port1, 1<<2 | 1<<3 );
|
|
||||||
|
|
||||||
Diode orientation
|
|
||||||
----------------
|
|
||||||
Diode orientation is explained in keybrd_library_user_guide.md > Diode orientation
|
|
||||||
|
|
||||||
PCA9655E data sheet
|
|
||||||
----------------
|
|
||||||
http://www.onsemi.com/pub_link/Collateral/PCA9655E-D.PDF
|
|
||||||
*/
|
|
||||||
class PortRead_PCA9655E : public PortReadInterface
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
PortIOE& port;
|
|
||||||
const uint8_t readPins; //bit pattern, pin configuration, 1 means read pin
|
|
||||||
public:
|
|
||||||
PortRead_PCA9655E (PortIOE& port, const uint8_t readPins)
|
|
||||||
: port(port), readPins(readPins) {}
|
|
||||||
void begin(const uint8_t strobeOn);
|
|
||||||
virtual uint8_t read();
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef PORTWRITEINTERFACE_H
|
|
||||||
#define PORTWRITEINTERFACE_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
Port classes are the keybrd library's interface to microcontroller ports or I/O expander ports.
|
|
||||||
*/
|
|
||||||
class PortWriteInterface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void begin()=0;
|
|
||||||
virtual void write(const uint8_t strobePin, const bool pinLogicLevel)=0;
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||||||
#include "PortWrite_MCP23S17.h"
|
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin().
|
|
||||||
Initiates SPI bus and configures port pins to output.
|
|
||||||
MCP23S17 SPI interface is 10 MHz max.
|
|
||||||
The electrical limitation to bus speed is bus capacitance and the length of the wires involved.
|
|
||||||
Longer wires require lower clock speeds.
|
|
||||||
*/
|
|
||||||
void PortWrite_MCP23S17::begin()
|
|
||||||
{
|
|
||||||
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output
|
|
||||||
digitalWrite(SS, HIGH); //disable Slave Select
|
|
||||||
SPI.begin();
|
|
||||||
SPI.beginTransaction(SPISettings (5000000, MSBFIRST, SPI_MODE0)); //control SPI bus, 5 MHz
|
|
||||||
//SPI.endTransaction() not called to release SPI bus because keyboard only has one SPI device.
|
|
||||||
|
|
||||||
transfer(port.DEVICE_ADDR << 1, port.num, 0); //configure port direction (port.num) to output (0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write() sets pin output to logicLevel.
|
|
||||||
pin is bit pattern, where pin being set is 1.
|
|
||||||
logicLevel is HIGH or LOW.
|
|
||||||
write() does not overwrite the other pins.
|
|
||||||
*/
|
|
||||||
void PortWrite_MCP23S17::write(const uint8_t pin, const bool logicLevel)
|
|
||||||
{
|
|
||||||
if (logicLevel == LOW)
|
|
||||||
{
|
|
||||||
port.outputVal &= ~pin; //set pin output to low
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
port.outputVal |= pin; //set pin output to high
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer(port.DEVICE_ADDR << 1, port.num + 0x12, port.outputVal); //set GPIO port to outputVal
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef PORTWRITE_MCP23S17_H
|
|
||||||
#define PORTWRITE_MCP23S17_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <PortWriteInterface.h>
|
|
||||||
#include "PortMCP23S17.h"
|
|
||||||
#include "PortIOE.h"
|
|
||||||
|
|
||||||
/* One MCP23S17 I/O expander port connected to matrix rows.
|
|
||||||
write() can output logiclevel to strobePin, one LED pin, or multiple pins.
|
|
||||||
|
|
||||||
This class has Slave Select hardcoded to Arduino Pin 10.
|
|
||||||
Arduino Pin 10 avoids the speed penalty of digitalWrite.
|
|
||||||
|
|
||||||
Instantiation
|
|
||||||
------------
|
|
||||||
Example instantiation:
|
|
||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
|
||||||
PortIOE port_B(1);
|
|
||||||
PortWrite_MCP23S17 portWrite_B(port_B);
|
|
||||||
|
|
||||||
Diode orientation
|
|
||||||
----------------
|
|
||||||
Diode orientation is explained in keybrd_library_user_guide.md > Diode orientation
|
|
||||||
|
|
||||||
MCP23S17 data sheet
|
|
||||||
------------------
|
|
||||||
http://www.onsemi.com/pub_link/Collateral/MCP23S17-D.PDF
|
|
||||||
*/
|
|
||||||
|
|
||||||
class PortWrite_MCP23S17 : public PortWriteInterface, public PortMCP23S17
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
PortIOE& port;
|
|
||||||
public:
|
|
||||||
PortWrite_MCP23S17(PortIOE& port) : port(port) {}
|
|
||||||
void begin();
|
|
||||||
virtual void write(const uint8_t pin, const bool logicLevel);
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||||||
#include "PortWrite_PCA9655E.h"
|
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin().
|
|
||||||
Initiates I2C bus and configures port pins to output.
|
|
||||||
PCA9655E supports I2C SCL Clock Frequencies: 100 kHz, 400 kHz, 1000 kHz (Datasheet page 1 & 6)
|
|
||||||
The electrical limitation to bus speed is bus capacitance and the length of the wires involved.
|
|
||||||
Longer wires require lower clock speeds.
|
|
||||||
http://playground.arduino.cc/Main/WireLibraryDetailedReference > Wire.setclock()
|
|
||||||
*/
|
|
||||||
void PortWrite_PCA9655E::begin()
|
|
||||||
{
|
|
||||||
Wire.begin(); //initiate I2C bus to 100 kHz
|
|
||||||
//Wire.setClock(400000L); //set I2C bus to 400 kHz (have not tested 400 kHz)
|
|
||||||
|
|
||||||
Wire.beginTransmission(port.DEVICE_ADDR);
|
|
||||||
Wire.write(port.num + 6); //configuration byte command
|
|
||||||
Wire.write(0); //configure all pins as output
|
|
||||||
Wire.endTransmission();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write() sets pin output to logicLevel.
|
|
||||||
pin is bit pattern, where pin being strobed is 1.
|
|
||||||
logicLevel is HIGH or LOW.
|
|
||||||
write() does not overwrite the other pins.
|
|
||||||
*/
|
|
||||||
void PortWrite_PCA9655E::write(const uint8_t pin, const bool logicLevel)
|
|
||||||
{
|
|
||||||
if (logicLevel == LOW) //if pin low
|
|
||||||
{
|
|
||||||
port.outputVal &= ~pin; //set pin output to low
|
|
||||||
}
|
|
||||||
else //if strobestrobe high
|
|
||||||
{
|
|
||||||
port.outputVal |= pin; //set pin output to high
|
|
||||||
}
|
|
||||||
|
|
||||||
Wire.beginTransmission(port.DEVICE_ADDR);
|
|
||||||
Wire.write(port.num + 2); //output Byte command
|
|
||||||
Wire.write(port.outputVal);
|
|
||||||
Wire.endTransmission();
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#ifndef PORTWRITE_PCA9655E_H
|
|
||||||
#define PORTWRITE_PCA9655E_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <Wire.h>
|
|
||||||
#include <PortWriteInterface.h>
|
|
||||||
#include "PortIOE.h"
|
|
||||||
|
|
||||||
/* One PCA9655E I/O expander port connected to matrix rows.
|
|
||||||
write() can output logiclevel to strobePin, one LED pin, or multiple pins.
|
|
||||||
|
|
||||||
Instantiation
|
|
||||||
------------
|
|
||||||
Example instantiation:
|
|
||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //PCA9655E address, all 3 ADDR pins are grounded
|
|
||||||
PortIOE port0(0);
|
|
||||||
PortWrite_PCA9655E rowPort0(port0);
|
|
||||||
|
|
||||||
Diode orientation
|
|
||||||
----------------
|
|
||||||
Diode orientation is explained in keybrd_library_user_guide.md > Diode orientation
|
|
||||||
|
|
||||||
PCA9655E data sheet
|
|
||||||
----------------
|
|
||||||
http://www.onsemi.com/pub_link/Collateral/PCA9655E-D.PDF
|
|
||||||
*/
|
|
||||||
|
|
||||||
class PortWrite_PCA9655E : public PortWriteInterface
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
PortIOE& port;
|
|
||||||
public:
|
|
||||||
PortWrite_PCA9655E(PortIOE& port) : port(port) {}
|
|
||||||
void begin();
|
|
||||||
|
|
||||||
virtual void write(const uint8_t pin, const bool logicLevel);
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -12,7 +12,6 @@ Initiates communication protocal and configs ports.
|
|||||||
*/
|
*/
|
||||||
void Scanner_IOE::begin()
|
void Scanner_IOE::begin()
|
||||||
{
|
{
|
||||||
refPortWrite.begin();
|
|
||||||
refPortRead.begin(strobeOn);
|
refPortRead.begin(strobeOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,11 +23,13 @@ read_pins_t Scanner_IOE::scan(const uint8_t strobePin)
|
|||||||
{
|
{
|
||||||
uint8_t readState; //bits, 1 means key is pressed, 0 means released
|
uint8_t readState; //bits, 1 means key is pressed, 0 means released
|
||||||
|
|
||||||
|
delay(2000);//todo
|
||||||
//strobe on
|
//strobe on
|
||||||
refPortWrite.write(strobePin, strobeOn);
|
refPortWrite.write(strobePin, strobeOn);
|
||||||
delayMicroseconds(3); //time to stabilize voltage
|
delayMicroseconds(3); //time to stabilize voltage
|
||||||
//delayMicroseconds(300); //todo
|
//delayMicroseconds(300); //todo
|
||||||
|
|
||||||
|
delay(2000);
|
||||||
//read the port pins
|
//read the port pins
|
||||||
readState = refPortRead.read();
|
readState = refPortRead.read();
|
||||||
|
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <ScannerInterface.h>
|
#include <ScannerInterface.h>
|
||||||
#include <PortWriteInterface.h>
|
#include <PortInterface.h>
|
||||||
#include <PortReadInterface.h>
|
|
||||||
|
|
||||||
/* Scanner_IOE uses bit manipulation to read all pins of one port.
|
/* Scanner_IOE uses bit manipulation to read all pins of one port.
|
||||||
The maximum keys per row is 8, because ports have a maximum of 8 pins each.
|
The maximum keys per row is 8, because ports have a maximum of 8 pins each.
|
||||||
@ -19,11 +18,11 @@ class Scanner_IOE : public ScannerInterface
|
|||||||
private:
|
private:
|
||||||
const bool strobeOn; //logic level of strobe on, HIGH or LOW
|
const bool strobeOn; //logic level of strobe on, HIGH or LOW
|
||||||
const bool strobeOff; //logic level of strobe off, complement of strobeOn
|
const bool strobeOff; //logic level of strobe off, complement of strobeOn
|
||||||
PortWriteInterface& refPortWrite; //the IC port containing the strobePin
|
PortInterface& refPortWrite; //the IC port containing the strobePin
|
||||||
PortReadInterface& refPortRead; //the IC's read port
|
PortInterface& refPortRead; //the IC's read port
|
||||||
public:
|
public:
|
||||||
Scanner_IOE(const bool strobeOn,
|
Scanner_IOE(const bool strobeOn,
|
||||||
PortWriteInterface &refPortWrite, PortReadInterface& refPortRead)
|
PortInterface &refPortWrite, PortInterface& refPortRead)
|
||||||
: strobeOn(strobeOn), strobeOff(!strobeOn),
|
: strobeOn(strobeOn), strobeOff(!strobeOn),
|
||||||
refPortWrite(refPortWrite), refPortRead(refPortRead) {}
|
refPortWrite(refPortWrite), refPortRead(refPortRead) {}
|
||||||
void init(const uint8_t strobePin);
|
void init(const uint8_t strobePin);
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
#include "Scanner_ShiftRegsPISOMultiRow.h"
|
|
||||||
|
|
||||||
/* constructor
|
|
||||||
*/
|
|
||||||
Scanner_ShiftRegsPISOMultiRow::Scanner_ShiftRegsPISOMultiRow(const bool strobeOn,
|
|
||||||
const uint8_t slaveSelect, const uint8_t byte_count)
|
|
||||||
: strobeOn(strobeOn), strobeOff(!strobeOn),
|
|
||||||
slaveSelect(slaveSelect), byte_count(byte_count)
|
|
||||||
{
|
|
||||||
pinMode(slaveSelect, OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init() is called once for each row from Row constructor.
|
|
||||||
Configures controller to communicate with shift register matrix.
|
|
||||||
*/
|
|
||||||
void Scanner_ShiftRegsPISOMultiRow::init(const uint8_t strobePin)
|
|
||||||
{
|
|
||||||
pinMode(strobePin, OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* begin() should be called once from sketch setup().
|
|
||||||
Initializes shift register's shift/load pin.
|
|
||||||
*/
|
|
||||||
void Scanner_ShiftRegsPISOMultiRow::begin()
|
|
||||||
{
|
|
||||||
digitalWrite(slaveSelect, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
Bit patterns are 1 bit per key.
|
|
||||||
*/
|
|
||||||
read_pins_t Scanner_ShiftRegsPISOMultiRow::scan(const uint8_t strobePin)
|
|
||||||
{
|
|
||||||
read_pins_t readState = 0; //bits, 1 means key is pressed, 0 means released
|
|
||||||
|
|
||||||
//strobe row on
|
|
||||||
digitalWrite(strobePin, strobeOn);
|
|
||||||
delayMicroseconds(3); //time to stablize voltage
|
|
||||||
|
|
||||||
//read all the column pins
|
|
||||||
digitalWrite(slaveSelect, LOW); //load parallel inputs to the register
|
|
||||||
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output
|
|
||||||
SPI.transfer(&readState, byte_count);
|
|
||||||
|
|
||||||
//strobe row off
|
|
||||||
digitalWrite(strobePin, strobeOff);
|
|
||||||
|
|
||||||
return readState;
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
#ifndef ROWSCANNER_SHIFTREGSPISOMULTIROW_H
|
|
||||||
#define ROWSCANNER_SHIFTREGSPISOMULTIROW_H
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <config_keybrd.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <ScannerInterface.h>
|
|
||||||
#include <PortWriteInterface.h>
|
|
||||||
#include <PortReadInterface.h>
|
|
||||||
|
|
||||||
/* Scanner_ShiftRegsPISOMultiRow reads shift registers.
|
|
||||||
This was tested on 74HC165 shift registers, which are Parallel-In-Serial-Out (PISO).
|
|
||||||
Upto 4 shift registers can be in a daisy chained for a total of 32 read pins.
|
|
||||||
|
|
||||||
Example instantiation:
|
|
||||||
Scanner_ShiftRegsPISOMultiRow scanner_R(HIGH, SS, 4);
|
|
||||||
|
|
||||||
There are three Scanner_ShiftRegsPISOMultiRow parameters.
|
|
||||||
"strobeOn" paramter is active state HIGH or LOW.
|
|
||||||
|
|
||||||
"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.
|
|
||||||
|
|
||||||
"byte_count" is the number of bytes to read from shift registers (1 to 4).
|
|
||||||
byte_count should cover all the row's keys:
|
|
||||||
byte_count*8 >= row's keyCount
|
|
||||||
|
|
||||||
Hardware setup:
|
|
||||||
Each row needs to be connected to a strobe pin from the controller.
|
|
||||||
Switche and diode in series are connected to shift-register parallel-input pins and strobed row.
|
|
||||||
|
|
||||||
For active low:
|
|
||||||
Shift-register parallel-input pins need 10k Ohm pull-up resistors powered.
|
|
||||||
Orient diodes with cathode (banded end) towards the write pins (row)
|
|
||||||
Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin
|
|
||||||
|
|
||||||
For active high:
|
|
||||||
Shift-register parallel-input pins need 10k pull-down resistors grounded.
|
|
||||||
Orient diodes with cathode (banded end) towards the read pins.
|
|
||||||
Controller's MISO pin is connected to shift register's serial output (QH) pin
|
|
||||||
*/
|
|
||||||
class Scanner_ShiftRegsPISOMultiRow : public ScannerInterface
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const bool strobeOn; //logic level of strobe on, active state HIGH or LOW
|
|
||||||
const bool strobeOff; //logic level of strobe off, complement of strobeOn
|
|
||||||
const uint8_t slaveSelect; //controller's pin number that is
|
|
||||||
// connected to shift register's SHIFT-LOAD pin
|
|
||||||
const uint8_t byte_count; //number of bytes to read from shift registers
|
|
||||||
public:
|
|
||||||
Scanner_ShiftRegsPISOMultiRow(const bool strobeOn,
|
|
||||||
const uint8_t slaveSelect, const uint8_t byte_count);
|
|
||||||
virtual void init(const uint8_t strobePin);
|
|
||||||
virtual void begin();
|
|
||||||
virtual read_pins_t scan(const uint8_t strobePin);
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -1,43 +0,0 @@
|
|||||||
#include "Scanner_ShiftRegsPISOSingleRow.h"
|
|
||||||
|
|
||||||
/* constructor
|
|
||||||
*/
|
|
||||||
Scanner_ShiftRegsPISOSingleRow::Scanner_ShiftRegsPISOSingleRow(const bool strobeOn,
|
|
||||||
const uint8_t slaveSelect, const uint8_t byte_count)
|
|
||||||
: slaveSelect(slaveSelect), byte_count(byte_count)
|
|
||||||
{
|
|
||||||
pinMode(slaveSelect, OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init() is called once for each row from Row constructor.
|
|
||||||
*/
|
|
||||||
void Scanner_ShiftRegsPISOSingleRow::init(const uint8_t strobePin)
|
|
||||||
{
|
|
||||||
//empty function
|
|
||||||
}
|
|
||||||
|
|
||||||
/* begin() should be called once from sketch setup().
|
|
||||||
Initializes shift register's shift/load pin.
|
|
||||||
*/
|
|
||||||
void Scanner_ShiftRegsPISOSingleRow::begin()
|
|
||||||
{
|
|
||||||
SPI.begin();
|
|
||||||
digitalWrite(slaveSelect, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* scan() returns state of the shift register's input pins.
|
|
||||||
No strobe pin is needed, the shift register is wired so the strobe is effectivley always "on".
|
|
||||||
Bit patterns are 1 bit per key.
|
|
||||||
*/
|
|
||||||
read_pins_t Scanner_ShiftRegsPISOSingleRow::scan(const uint8_t strobePin)
|
|
||||||
{
|
|
||||||
read_pins_t readState = 0; //bits, 1 means key is pressed, 0 means released
|
|
||||||
|
|
||||||
//read all the column pins
|
|
||||||
digitalWrite(slaveSelect, LOW); //load parallel inputs to the register
|
|
||||||
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output
|
|
||||||
SPI.transfer(&readState, byte_count);
|
|
||||||
|
|
||||||
return readState;
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
#ifndef ROWSCANNER_SHIFTREGSPISOSINGLEROW_H
|
|
||||||
#define ROWSCANNER_SHIFTREGSPISOSINGLEROW_H
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <config_keybrd.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <ScannerInterface.h>
|
|
||||||
#include <PortWriteInterface.h>
|
|
||||||
#include <PortReadInterface.h>
|
|
||||||
|
|
||||||
/* Scanner_ShiftRegsPISOSingleRow reads shift registers.
|
|
||||||
This was tested on 74HC165 shift registers, which are Parallel-In-Serial-Out (PISO).
|
|
||||||
Upto 4 shift registers can be in a daisy chained for a total of 32 read pins.
|
|
||||||
|
|
||||||
Example instantiation:
|
|
||||||
Row row_R0(scanner_R, 0, ptrsKeys_R0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0));
|
|
||||||
Scanner_ShiftRegsPISOSingleRow scanner_R(HIGH, SS, 4);
|
|
||||||
|
|
||||||
The Row "strobePin" parameter is ignored.
|
|
||||||
In the above example, the "strobePin" argument is 0, but it doesn't matter what value is given.
|
|
||||||
|
|
||||||
There are three Scanner_ShiftRegsPISOSingleRow parameters.
|
|
||||||
"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 pin SS (Arduino pin 10) has the fastest scan.
|
|
||||||
|
|
||||||
"byte_count" is the number of bytes to read from shift registers (1 to 4).
|
|
||||||
byte_count should cover all the row's keys:
|
|
||||||
byte_count*8 >= row's keyCount
|
|
||||||
|
|
||||||
Hardware setup:
|
|
||||||
There is only one row, and it is permanently active.
|
|
||||||
Switches are connected to shift-register parallel-input pins (diodes are not needed) and row.
|
|
||||||
|
|
||||||
For active low:
|
|
||||||
Shift-register parallel-input pins need 10k Ohm pull-up resistors powered.
|
|
||||||
Switches connect powered row to parallel-input pins.
|
|
||||||
Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin
|
|
||||||
|
|
||||||
For active high:
|
|
||||||
Shift-register parallel-input pins need 10k pull-down resistors grounded.
|
|
||||||
Switches connect grouned row to parallel-input pins.
|
|
||||||
Controller's MISO pin is connected to shift register's serial output (QH) pin
|
|
||||||
*/
|
|
||||||
class Scanner_ShiftRegsPISOSingleRow : public ScannerInterface
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const uint8_t slaveSelect; //controller's pin number that is
|
|
||||||
// connected to shift register's SHIFT-LOAD pin
|
|
||||||
const uint8_t byte_count; //number of bytes to read from shift registers
|
|
||||||
public:
|
|
||||||
Scanner_ShiftRegsPISOSingleRow(const bool strobeOn,
|
|
||||||
const uint8_t slaveSelect, const uint8_t byte_count);
|
|
||||||
void init(const uint8_t strobePin);
|
|
||||||
void begin();
|
|
||||||
virtual read_pins_t scan(const uint8_t strobePin);
|
|
||||||
};
|
|
||||||
#endif
|
|
Binary file not shown.
@ -24,8 +24,7 @@ This layout table shows left and right matrices:
|
|||||||
|
|
||||||
//right matrix
|
//right matrix
|
||||||
#include <PortIOE.h>
|
#include <PortIOE.h>
|
||||||
#include <PortWrite_MCP23S17.h>
|
#include <PortMCP23S17.h>
|
||||||
#include <PortRead_MCP23S17.h>
|
|
||||||
#include <Scanner_IOE.h>
|
#include <Scanner_IOE.h>
|
||||||
#include <LED_IOE.h>
|
#include <LED_IOE.h>
|
||||||
|
|
||||||
@ -42,20 +41,15 @@ Scanner_uC scanner_L(LOW, readPins, READPIN_COUNT);
|
|||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address with all 3 ADDR pins are grounded
|
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address with all 3 ADDR pins are grounded
|
||||||
|
|
||||||
PortIOE port_A(0);
|
PortIOE port_A(0);
|
||||||
PortRead_MCP23S17 portRead(port_A, 1<<0 | 1<<1 );
|
PortMCP23S17 portRead(port_A, 1<<0 | 1<<1 );
|
||||||
PortWrite_MCP23S17 portWriteA(port_A); //for LED
|
|
||||||
//todo portWriteA(port_A) instantiation would not be needed if PortRead_MCP23S17 had write()
|
|
||||||
// consider moving PortWrite_MCP23S17::write to Port_MCP23S17 (parent)
|
|
||||||
// and passing portRead to LED_IOE
|
|
||||||
// same for PCA9655E
|
|
||||||
|
|
||||||
PortIOE port_B(1);
|
PortIOE port_B(1);
|
||||||
PortWrite_MCP23S17 portWrite(port_B);
|
PortMCP23S17 portWrite(port_B, 0);
|
||||||
|
|
||||||
Scanner_IOE scanner_R(LOW, portWrite, portRead);
|
Scanner_IOE scanner_R(LOW, portWrite, portRead);
|
||||||
|
|
||||||
// ================ RIGHT LEDs =================
|
// ================ RIGHT LEDs =================
|
||||||
LED_IOE LED_CapsLck(portWriteA, 1<<6); //tested LED on port A (read)
|
//LED_IOE LED_CapsLck(portRead, 1<<6); //tested LED on port A (read)
|
||||||
//LED_IOE LED_CapsLck(portWrite, 1<<6);//tested LED on port B (write)
|
//LED_IOE LED_CapsLck(portWrite, 1<<6);//tested LED on port B (write)
|
||||||
|
|
||||||
// =================== CODES ===================
|
// =================== CODES ===================
|
||||||
@ -68,7 +62,8 @@ 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_LEDLock o_capsLock(KEY_CAPS_LOCK, LED_CapsLck);
|
Code_Sc o_capsLock(KEY_4);
|
||||||
|
//Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED_CapsLck);
|
||||||
|
|
||||||
// =================== ROWS ====================
|
// =================== ROWS ====================
|
||||||
// ---------------- LEFT ROWS ------------------
|
// ---------------- LEFT ROWS ------------------
|
||||||
@ -93,6 +88,7 @@ Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1);
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Keyboard.begin();
|
Keyboard.begin();
|
||||||
|
delay(7000);
|
||||||
scanner_R.begin();
|
scanner_R.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user