add sr0_LED_shiftRegs.ino, LED_shiftRegs, LED_shiftRegs
@ -4,8 +4,8 @@ We'd love for you to contribute to the keybrd project.
|
|||||||
|
|
||||||
Improvement suggestions
|
Improvement suggestions
|
||||||
-----------------------
|
-----------------------
|
||||||
We need to know what improvements to the keybrd library would help you create your keyboard design.
|
We need to know what keybrd library improvements would help you create keyboard designs.
|
||||||
Before requesting an improvement, please check [planned_features list](doc/planned_features.md)
|
Before requesting an improvement, please check the [planned_features list](doc/planned_features.md).
|
||||||
|
|
||||||
Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
||||||
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
||||||
@ -16,8 +16,8 @@ or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
|||||||
|
|
||||||
Bug reports
|
Bug reports
|
||||||
-----------
|
-----------
|
||||||
A bug report is the first step in finding a bug.
|
Submitting a bug report is the first step in fixing a bug.
|
||||||
Once it is found, correcting it is usually relatively easy.
|
Once it is found, correcting a bug is usually relatively easy.
|
||||||
Please submit bug reports to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
Please submit bug reports to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
||||||
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ Provide enough information so we can reproduce the buggy behaviour!
|
|||||||
|
|
||||||
Code contributions
|
Code contributions
|
||||||
------------------
|
------------------
|
||||||
Unsure where to begin contributing to keybrd code?
|
Unsure of where to begin contributing to keybrd code?
|
||||||
You can start by looking through the improvement suggestions, bug reports, and [planned_features](doc/planned_features.md).
|
You can start by looking through the improvement suggestions, bug reports, and [planned_features](doc/planned_features.md).
|
||||||
|
|
||||||
Git commit message style guide:
|
Git commit message style guide:
|
||||||
@ -49,18 +49,57 @@ Any project requires various kinds of contributions to succeed.
|
|||||||
A thriving project is more than a pile of code.
|
A thriving project is more than a pile of code.
|
||||||
It's the packaging, explanation, outreach, and empathy of maintainers that make a good project great.
|
It's the packaging, explanation, outreach, and empathy of maintainers that make a good project great.
|
||||||
|
|
||||||
### Beta testing
|
### keybrd tutorials usability survey
|
||||||
keybrd library has been Alpha tested on the DodoHand keyboard, tutorial sketches, Teensy 2.0, and Teensy LC. What we need now are Beta testers:
|
We want feedback on keybrd tutorial usability from real users (feedback from noobs is especially valuable).
|
||||||
* use the tutorials (feedback from noobs is especially valuable)
|
Please take the survey after completing a tutorial.
|
||||||
* use the keybrd library to implement your own keyboard design
|
Answer the questions you feel like answering, or make up your own questions.
|
||||||
|
|
||||||
Feedback from Beta testers will be used to make improvements to the keybrd library.
|
* How easy was it to find the relevant tutorial?
|
||||||
|
|
||||||
|
* Which tutorial did you read?
|
||||||
|
|
||||||
|
* Did the tutorial provide complete information?
|
||||||
|
|
||||||
|
* What other tutorial topics would be useful?
|
||||||
|
|
||||||
|
* Are you satisfied with the tutorial?
|
||||||
|
|
||||||
|
* Other comments or suggestions.
|
||||||
|
|
||||||
|
Post the completed Q & A on [geekhack thread](https://geekhack.org/index.php?topic=83599.0) with a heading "Tutorial usability survey".
|
||||||
|
If you prefer your answers remain confidential, pm the completed Q & A to [wolfv](https://geekhack.org/index.php?action=pm;sa=send;u=25471).
|
||||||
|
|
||||||
|
Usability survey results will be used to make improvements to the tutorials.
|
||||||
|
|
||||||
|
### keybrd library usability survey
|
||||||
|
We want feedback on keybrd library usability from real users.
|
||||||
|
Please fill the survey after using the keybrd library to implement a keyboard design.
|
||||||
|
Answer the questions you feel like answering, or make up your own questions.
|
||||||
|
|
||||||
|
* How easy was it to find relevant information?
|
||||||
|
|
||||||
|
* Did the User guide provide complete information?
|
||||||
|
|
||||||
|
* What other keyboard firmware have you used?
|
||||||
|
|
||||||
|
* What pros and cons did you find compared to other keyboard firmware?
|
||||||
|
|
||||||
|
* Did you publish your keyboard firmware? If so, please provide a link.
|
||||||
|
|
||||||
|
* Are you satisfied with the keybrd library?
|
||||||
|
|
||||||
|
* Other comments or suggestions.
|
||||||
|
|
||||||
|
Post the completed Q & A on [geekhack thread](https://geekhack.org/index.php?topic=83599.0) with a heading "keybrd library usability survey".
|
||||||
|
If you prefer your answers remain confidential, pm the completed Q & A to [wolfv](https://geekhack.org/index.php?action=pm;sa=send;u=25471).
|
||||||
|
|
||||||
|
Usability survey results will be used to make improvements to the keybrd library.
|
||||||
|
|
||||||
### Schematics
|
### Schematics
|
||||||
The most glaring deficiency is the tutorials' lack of schematics.
|
The most glaring deficiency is the tutorials' lack of schematics.
|
||||||
Schematics would be an improvement over the current photos.
|
Schematics would be easier to read than the current photos.
|
||||||
|
|
||||||
Schematics are not my area of expertise. Use what ever you think would be the best solution for the tutorials:
|
Schematics are not my area of expertise. Use what ever would be the best solution for the tutorials:
|
||||||
* schematics
|
* schematics
|
||||||
* breadboard drawings
|
* breadboard drawings
|
||||||
* Arduino simulation software
|
* Arduino simulation software
|
||||||
@ -71,12 +110,29 @@ Contributions of tutorial schematics would benefit users new to the keybrd libra
|
|||||||
Suggest a clarification, simplification, correction, or other improvement.
|
Suggest a clarification, simplification, correction, or other improvement.
|
||||||
We need the perspective of people new to the project to see these things.
|
We need the perspective of people new to the project to see these things.
|
||||||
Sometimes just changing a word or two makes a big difference.
|
Sometimes just changing a word or two makes a big difference.
|
||||||
|
Please submit improvement and errata to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
||||||
|
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
||||||
|
|
||||||
Text file documentation style guide:
|
Text file documentation style guide:
|
||||||
* Use Markdown with a .md suffix.
|
* Use Markdown with a .md suffix.
|
||||||
* "Underline" first-level (=) and second-level (-) headings (because easier to read in plain text).
|
* "Underline" first-level (=) and second-level (-) headings (because easier to read in plain text).
|
||||||
* Capitalize first letter of headings (no extra capitalization in headings).
|
* Capitalize first letter of headings (no extra capitalization in headings).
|
||||||
|
|
||||||
|
### Write a sketch for a keyboard that is popular with Arduino-compatible controllers
|
||||||
|
Write a keybrd sketch for a keyboard that is popular with Arduino-compatible controllers.
|
||||||
|
* You should own the keyboard so you can test the firmware
|
||||||
|
* The keyboard should have an Arduino compatible controller (e.g. ErgoDox and Phantom use Teensy 2.0)
|
||||||
|
* The layout should be a plain baseline layout (QWERTY)
|
||||||
|
|
||||||
|
Other owners of that model keyboard can then easily modify and compile the sketch on Arduino IDE.
|
||||||
|
|
||||||
|
The README should have:
|
||||||
|
* brief description of the electronics
|
||||||
|
* link to a hardware page
|
||||||
|
* list any firmware deficiencies
|
||||||
|
|
||||||
|
Follow the "Publish" instructions in tutorial_8c_sharing_your_keybrd_sketch.md
|
||||||
|
|
||||||
### Blog
|
### Blog
|
||||||
You have a fresh perspective of how the keybrd library works.
|
You have a fresh perspective of how the keybrd library works.
|
||||||
This makes you the perfect person to write an introductory blog explaining the project.
|
This makes you the perfect person to write an introductory blog explaining the project.
|
||||||
@ -85,5 +141,7 @@ A healthy project needs the perspective of many people.
|
|||||||
Submitting a pull request
|
Submitting a pull request
|
||||||
-------------------------
|
-------------------------
|
||||||
Pull request is the preferred way to contribute code and documentation.
|
Pull request is the preferred way to contribute code and documentation.
|
||||||
If you want to contribute some other way, please make a request in the [GitHub issues](https://github.com/wolfv6/Keybrd/issues).
|
If you want to contribute some other way, please make a request in
|
||||||
|
[GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
||||||
|
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
||||||
|
|
||||||
|
BIN
IOE_scan_development/IOE_scan_development.ods
Normal file
BIN
IOE_scan_development/openDrain_activeLow/back.JPG
Normal file
After Width: | Height: | Size: 327 KiB |
BIN
IOE_scan_development/openDrain_activeLow/front.JPG
Normal file
After Width: | Height: | Size: 334 KiB |
@ -0,0 +1,69 @@
|
|||||||
|
/* 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() { }
|
BIN
IOE_scan_development/source_activeHigh/DSCF0003.JPG
Normal file
After Width: | Height: | Size: 324 KiB |
BIN
IOE_scan_development/source_activeHigh/DSCF0004.JPG
Normal file
After Width: | Height: | Size: 330 KiB |
69
IOE_scan_development/source_activeHigh/source_activeHigh.ino
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* 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() { }
|
BIN
IOE_scan_development/source_activeLow/back.JPG
Normal file
After Width: | Height: | Size: 326 KiB |
BIN
IOE_scan_development/source_activeLow/front.JPG
Normal file
After Width: | Height: | Size: 329 KiB |
68
IOE_scan_development/source_activeLow/source_activeLow.ino
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* 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() { }
|
@ -6,11 +6,6 @@ This project adheres to [Semantic Versioning 2.0.0](http://semver.org/).
|
|||||||
keybrd version 0.x.x is for initial development.
|
keybrd version 0.x.x is for initial development.
|
||||||
keybrd version 1.0.0 will be released when the public API is stable.
|
keybrd version 1.0.0 will be released when the public API is stable.
|
||||||
|
|
||||||
< !--
|
|
||||||
Unreleased
|
|
||||||
----------
|
|
||||||
-->
|
|
||||||
|
|
||||||
0.6.0 (2016-09-28)
|
0.6.0 (2016-09-28)
|
||||||
------------------
|
------------------
|
||||||
* Enhancements
|
* Enhancements
|
||||||
|
@ -2,14 +2,12 @@ planned_features is a view of where the keybrd project is headed.
|
|||||||
|
|
||||||
Top priority
|
Top priority
|
||||||
------------
|
------------
|
||||||
* Beta testing
|
* User testing
|
||||||
* Add breadboard keyboard schematics to tutorials
|
|
||||||
|
|
||||||
Medium priority
|
Medium priority
|
||||||
---------------
|
---------------
|
||||||
* Add matrix-to-layout mapping array (to decouple key matrix from layout)
|
* Add matrix-to-layout mapping (to decouple key matrix from layout)
|
||||||
* Add tutorial_4b_split_keyboard_with_shift_registers
|
* Add breadboard keyboard schematics to tutorials
|
||||||
|
|
||||||
Low priority
|
Low priority
|
||||||
------------
|
------------
|
||||||
* Add MCP23S18 I/O expander with Serial Peripheral Interface (SPI)
|
|
||||||
|
131
examples/keybrd_MCP23018/keybrd_MCP23018.ino
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/* keybrd_MCP23018.ino
|
||||||
|
|
||||||
|
This sketch:
|
||||||
|
is a simple 1-layer keyboard
|
||||||
|
runs on two matrices of a breadboard keyboard
|
||||||
|
|
||||||
|
Controller I/O expander
|
||||||
|
| Left | **0** | **1** | | Right | **0** | **1** |
|
||||||
|
|-------|-------|-------| |-------|-------|-------|
|
||||||
|
| **1** | 1 | 2 | | **1** | 3 | 4 |
|
||||||
|
| **0** | a | b | | **0** | c | d |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <ScanDelay.h>
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
#include <Code_LEDLock.h>
|
||||||
|
#include <Row.h>
|
||||||
|
|
||||||
|
//left matrix
|
||||||
|
#include <Scanner_uC.h>
|
||||||
|
|
||||||
|
//right matrix
|
||||||
|
#include <Port_MCP23018.h>
|
||||||
|
#include <Scanner_IOE.h>
|
||||||
|
#include <LED_Port.h>
|
||||||
|
|
||||||
|
// ============ SPEED CONFIGURATION ============
|
||||||
|
ScanDelay scanDelay(9000);
|
||||||
|
|
||||||
|
/* ================ LEFT SCANNER ===============
|
||||||
|
Left matrix rows work the same as the ones in keybrd_2_single-layer.ino
|
||||||
|
*/
|
||||||
|
uint8_t readPins[] = {14, 15};
|
||||||
|
const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
|
Scanner_uC scanner_L(LOW, readPins, readPinCount);
|
||||||
|
|
||||||
|
/* =============== RIGHT SCANNER ===============
|
||||||
|
The right matrix is scanned by an I/O expander.
|
||||||
|
The MCP23018 address is set by grounding or powering pins.
|
||||||
|
*/
|
||||||
|
const uint8_t IOE_ADDR = 0x20; //MCP23018 address pin grounded
|
||||||
|
|
||||||
|
/*
|
||||||
|
Normally all strobe pins are on one port, and all the read pins are on the other port.
|
||||||
|
In this example, portB stobes the row while portA reads the colums.
|
||||||
|
Port_MCP23018 constructor parameters are: deviceAddr, portNum, readPins.
|
||||||
|
readPins is a bit pattern, where 0=output, 1=input.
|
||||||
|
In portA, the first two pins are set to input for reading.
|
||||||
|
"<<" (bit shift left) and "|" (OR) are bitwise operators.
|
||||||
|
Pin numbers to be read are delimited by "|" and to the right of "1<<".
|
||||||
|
*/
|
||||||
|
Port_MCP23018 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //read pins 0, 1
|
||||||
|
Port_MCP23018 portB(IOE_ADDR, 1, 0);
|
||||||
|
Scanner_IOE scanner_R(LOW, portB, portA);
|
||||||
|
|
||||||
|
/* ================= RIGHT LED =================
|
||||||
|
The LED_Port constructor parameters are a port and pin number that is connected to an LED.
|
||||||
|
*/
|
||||||
|
LED_Port LED_capsLck(portA, 1<<7);
|
||||||
|
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
Code_Sc s_d(KEY_D);
|
||||||
|
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_2(KEY_2);
|
||||||
|
Code_Sc s_3(KEY_3);
|
||||||
|
Code_Sc s_4(KEY_4);
|
||||||
|
|
||||||
|
Code_LEDLock o_capsLock(KEY_CAPS_LOCK, LED_capsLck);//todo was testing LED, restore s_4 when done
|
||||||
|
|
||||||
|
/* =================== ROWS ====================
|
||||||
|
Left row names contain the letter 'L', while right row names conatain the letter 'R'.
|
||||||
|
|
||||||
|
Row constructor parameters are: scanner, strobePin, ptrsKeys[], keyCount.
|
||||||
|
strobePin has one of two formats:
|
||||||
|
* if refScanner a Scanner_uC, then strobePin is an Arduino pin number connected to this row
|
||||||
|
* otherwise strobePin is a bit pattern, 1 indicating an IC pin connected to the row
|
||||||
|
*/
|
||||||
|
/* ---------------- LEFT ROWS ------------------
|
||||||
|
The left rows have a Scanner_uC and Arduino pin numbers to strobe.
|
||||||
|
*/
|
||||||
|
Key* ptrsKeys_L0[] = { &s_1, &s_2 };
|
||||||
|
const uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0);
|
||||||
|
Row row_L0(scanner_L, 0, ptrsKeys_L0, KEY_COUNT_L0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_L1[] = { &s_a, &s_b };
|
||||||
|
const uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1);
|
||||||
|
Row row_L1(scanner_L, 1, ptrsKeys_L1, KEY_COUNT_L1);
|
||||||
|
|
||||||
|
/* ---------------- RIGHT ROWS -----------------
|
||||||
|
The right rows have a Scanner_IOE and pin bits to strobe.
|
||||||
|
*/
|
||||||
|
Key* ptrsKeys_R0[] = { &s_3, &o_capsLock };
|
||||||
|
const uint8_t KEY_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0);
|
||||||
|
Row row_R0(scanner_R, 1<<0, ptrsKeys_R0, KEY_COUNT_R0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_R1[] = { &s_c, &s_d };
|
||||||
|
const uint8_t KEY_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1);
|
||||||
|
Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1);
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
scanner_R.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
//left matrix
|
||||||
|
row_L0.process();
|
||||||
|
row_L1.process();
|
||||||
|
|
||||||
|
//right matrix
|
||||||
|
row_R0.process();
|
||||||
|
//Keyboard.println(" 0");
|
||||||
|
//delay(2000);
|
||||||
|
row_R1.process();
|
||||||
|
//Keyboard.println(" 1");
|
||||||
|
//delay(2000);
|
||||||
|
|
||||||
|
scanDelay.delay();
|
||||||
|
//Keyboard.println(" end loop");//todo
|
||||||
|
//debug.print_scans_per_second();
|
||||||
|
//debug.print_microseconds_per_scan();
|
||||||
|
}
|
33
src/LED_shiftRegs.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "LED_shiftRegs.h"
|
||||||
|
|
||||||
|
/* constructor
|
||||||
|
*/
|
||||||
|
LED_shiftRegs::LED_shiftRegs(const uint8_t slaveSelect, const uint8_t pin)
|
||||||
|
:slaveSelect(slaveSelect), pin(pin)
|
||||||
|
{
|
||||||
|
pinMode(slaveSelect, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* begin() should be called once from sketch setup().
|
||||||
|
Initializes shift register's shift/load pin.
|
||||||
|
*/
|
||||||
|
void LED_shiftRegs::begin()
|
||||||
|
{
|
||||||
|
SPI.begin();
|
||||||
|
digitalWrite(slaveSelect, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo preserve other LED values, similar to Port_PCA9655E outputVal
|
||||||
|
void LED_shiftRegs::on()
|
||||||
|
{
|
||||||
|
digitalWrite(slaveSelect, LOW);
|
||||||
|
SPI.transfer(pin);
|
||||||
|
digitalWrite (slaveSelect, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LED_shiftRegs::off()
|
||||||
|
{
|
||||||
|
digitalWrite(slaveSelect, LOW);
|
||||||
|
SPI.transfer(0);
|
||||||
|
digitalWrite (slaveSelect, HIGH);
|
||||||
|
}
|
22
src/LED_shiftRegs.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef LED_SHIFTREGS_H
|
||||||
|
#define LED_SHIFTREGS_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <LEDInterface.h>
|
||||||
|
|
||||||
|
/* A LED_shiftRegs turns LED on and off.
|
||||||
|
shift register RCLK pin a.k.a. SS or ST
|
||||||
|
*/
|
||||||
|
class LED_shiftRegs: public LEDInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const uint8_t slaveSelect;//controller pin number connected to shift register RCLK
|
||||||
|
const uint8_t pin; //bit pattern, shift register pin that is connected to an LED
|
||||||
|
public:
|
||||||
|
LED_shiftRegs(const uint8_t slaveSelect, const uint8_t pin);
|
||||||
|
void begin();
|
||||||
|
virtual void on();
|
||||||
|
virtual void off();
|
||||||
|
};
|
||||||
|
#endif
|
@ -14,7 +14,7 @@ class LED_uC: public LEDInterface
|
|||||||
public:
|
public:
|
||||||
LED_uC(const uint8_t pin): pin(pin)
|
LED_uC(const uint8_t pin): pin(pin)
|
||||||
{
|
{
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);//todo move to .cpp file
|
||||||
}
|
}
|
||||||
virtual void on();
|
virtual void on();
|
||||||
virtual void off();
|
virtual void off();
|
||||||
|
83
src/Port_MCP23018.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "Port_MCP23018.h"
|
||||||
|
//todo add Port_MCP23018::write() like Port_MCP23S17::transer() ??
|
||||||
|
|
||||||
|
/* beginProtocol() is called from Scanner_IOE::begin(). Initiates I2C bus.
|
||||||
|
|
||||||
|
MCP23018 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 Port_MCP23018::beginProtocol()
|
||||||
|
{
|
||||||
|
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().
|
||||||
|
Configures port's IODIR and GPPU.
|
||||||
|
*/
|
||||||
|
void Port_MCP23018::begin(const uint8_t strobeOn)
|
||||||
|
{
|
||||||
|
uint8_t pullUp; //bits, GPPU 0=pull-up disabled, 1=pull-up enabled
|
||||||
|
|
||||||
|
if (strobeOn == LOW) //if active low
|
||||||
|
{
|
||||||
|
pullUp = readPins; //0=pull-up disabled (for LED), 1=pull-up enabled (for read)
|
||||||
|
}
|
||||||
|
else //if active high
|
||||||
|
{
|
||||||
|
pullUp = 0; //0=pull-up disabled (for external pull-down resistors)
|
||||||
|
}
|
||||||
|
|
||||||
|
Wire.beginTransmission(deviceAddr);
|
||||||
|
Wire.write(portNum); //IODIR
|
||||||
|
Wire.write(readPins); //0=output (for strobe and LED), 1=input (for read)
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.beginTransmission(deviceAddr);
|
||||||
|
Wire.write(portNum + 0x0C); //GPPU
|
||||||
|
Wire.write(pullUp);
|
||||||
|
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 Port_MCP23018::write(const uint8_t pin, const bool logicLevel)
|
||||||
|
{
|
||||||
|
if (logicLevel == LOW)
|
||||||
|
{
|
||||||
|
outputVal &= ~pin; //set pin output to low
|
||||||
|
//Keyboard.print(" low");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outputVal |= pin; //set pin output to high
|
||||||
|
//Keyboard.print(" high");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Keyboard.print(" outputVal=");//todo
|
||||||
|
//Keyboard.println(outputVal);
|
||||||
|
Wire.beginTransmission(deviceAddr);
|
||||||
|
Wire.write(portNum + 0x12); //GPIO
|
||||||
|
Wire.write(outputVal);
|
||||||
|
Wire.endTransmission();
|
||||||
|
//delay(4000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read() returns portState.
|
||||||
|
Only portState bits of readPins are valid.
|
||||||
|
*/
|
||||||
|
uint8_t Port_MCP23018::read()
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(deviceAddr);
|
||||||
|
Wire.write(portNum + 0x12); //GPIO
|
||||||
|
Wire.endTransmission(false); //MCP23018 needs false to send a restart ??really?
|
||||||
|
|
||||||
|
Wire.requestFrom(deviceAddr, 1u); //request one byte from input port
|
||||||
|
|
||||||
|
return Wire.read();
|
||||||
|
}
|
48
src/Port_MCP23018.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#ifndef PORT_MCP23018_H
|
||||||
|
#define PORT_MCP23018_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <PortInterface.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
write pins are connected to matrix Row (strobe pin) or LED.
|
||||||
|
readPins are connected to matrix column to read which keys are pressed.
|
||||||
|
|
||||||
|
MCP23018 has open-drain outputs (open-drain can only sink current). If LEDs are used, connect:
|
||||||
|
LED anodes (the longer lead) to power
|
||||||
|
LED cathodes (the shorter lead) to GPIO pin
|
||||||
|
|
||||||
|
Instantiation
|
||||||
|
------------
|
||||||
|
Example instantiation:
|
||||||
|
const uint8_t IOE_ADDR = 0x20; //MCP23018 address pin grounded
|
||||||
|
Port_MCP23018 portB(IOE_ADDR, 1, 0); //all pins are set to output for strobes and LEDs
|
||||||
|
Port_MCP23018 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //pin 0 and pin 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
|
||||||
|
|
||||||
|
MCP23018 data sheet
|
||||||
|
----------------
|
||||||
|
http://ww1.microchip.com/downloads/en/DeviceDoc/22103a.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Port_MCP23018 : public PortInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const uint8_t deviceAddr;
|
||||||
|
const uint8_t portNum; //port identification number, 0=A, 1=B
|
||||||
|
uint8_t outputVal; //bit pattern for strobe and LEDs
|
||||||
|
const uint8_t readPins; //bit pattern, IODIR 0=output, 1=input
|
||||||
|
public:
|
||||||
|
Port_MCP23018(const uint8_t deviceAddr, const uint8_t portNum, const uint8_t readPins)
|
||||||
|
: deviceAddr(deviceAddr), portNum(portNum), outputVal(0), readPins(readPins) {}
|
||||||
|
void beginProtocol();
|
||||||
|
void begin(const uint8_t strobeOn);
|
||||||
|
virtual void write(const uint8_t pin, const bool logicLevel);
|
||||||
|
virtual uint8_t read();
|
||||||
|
};
|
||||||
|
#endif
|
@ -22,7 +22,7 @@ uint8_t Port_MCP23S17::transfer(const uint8_t command, const uint8_t registerAdd
|
|||||||
return portState;
|
return portState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin(). Initiates SPI bus.
|
/* beginProtocol() is called from Scanner_IOE::begin(). Initiates SPI bus.
|
||||||
*/
|
*/
|
||||||
void Port_MCP23S17::beginProtocol()
|
void Port_MCP23S17::beginProtocol()
|
||||||
{
|
{
|
||||||
@ -39,13 +39,13 @@ void Port_MCP23S17::begin(const uint8_t strobeOn)
|
|||||||
{
|
{
|
||||||
uint8_t pullUp; //bits, GPPU 0=pull-up disabled, 1=pull-up enabled
|
uint8_t pullUp; //bits, GPPU 0=pull-up disabled, 1=pull-up enabled
|
||||||
|
|
||||||
if (strobeOn == LOW) //if active low, use internal pull-up resistors
|
if (strobeOn == LOW) //if active low
|
||||||
{
|
{
|
||||||
pullUp = readPins;
|
pullUp = readPins; //0=pull-up disabled (for LED), 1=pull-up enabled (for read)
|
||||||
}
|
}
|
||||||
else //active high requires external pull-down resistors
|
else //if active high
|
||||||
{
|
{
|
||||||
pullUp = 0;
|
pullUp = 0; //0=pull-up disabled (for external pull-down resistors)
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer(deviceAddr << 1, portNum, readPins); //configure IODIR
|
transfer(deviceAddr << 1, portNum, readPins); //configure IODIR
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "Port_PCA9655E.h"
|
#include "Port_PCA9655E.h"
|
||||||
|
|
||||||
/* begin() is called from Scanner_IOE::begin(). Initiates I2C bus.
|
/* beginProtocol() is called from Scanner_IOE::begin(). Initiates I2C bus.
|
||||||
|
|
||||||
PCA9655E supports I2C SCL Clock Frequencies: 100 kHz, 400 kHz, 1000 kHz (Datasheet page 1 & 6)
|
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.
|
The electrical limitation to bus speed is bus capacitance and the length of the wires involved.
|
||||||
|
@ -16,6 +16,7 @@ Configures controller to communicate with shift register matrix.
|
|||||||
void Scanner_ShiftRegsPISOMultiRow::init(const uint8_t strobePin)
|
void Scanner_ShiftRegsPISOMultiRow::init(const uint8_t strobePin)
|
||||||
{
|
{
|
||||||
pinMode(strobePin, OUTPUT);
|
pinMode(strobePin, OUTPUT);
|
||||||
|
//digitalWrite(strobePin, strobeOff);//todo is this needed?
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin() should be called once from sketch setup().
|
/* begin() should be called once from sketch setup().
|
||||||
@ -23,7 +24,7 @@ Initializes shift register's shift/load pin.
|
|||||||
*/
|
*/
|
||||||
void Scanner_ShiftRegsPISOMultiRow::begin()
|
void Scanner_ShiftRegsPISOMultiRow::begin()
|
||||||
{
|
{
|
||||||
digitalWrite(slaveSelect, HIGH);
|
SPI.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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.
|
||||||
@ -34,16 +35,25 @@ read_pins_t Scanner_ShiftRegsPISOMultiRow::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 row on
|
//strobe on
|
||||||
digitalWrite(strobePin, strobeOn);
|
digitalWrite(strobePin, strobeOn);
|
||||||
delayMicroseconds(3); //time to stablize voltage
|
|
||||||
|
//SPI.beginTransaction( SPISettings(5000000, MSBFIRST, SPI_MODE0) ); //control SPI bus, 5 MHz
|
||||||
|
//digitalWrite(slaveSelect, LOW); //assert slave
|
||||||
|
|
||||||
|
delayMicroseconds(3); //time to stabilize photo-transistor todo needed?
|
||||||
|
delayMicroseconds(50); //todo for sr2_LEDs_strobe.ino
|
||||||
|
|
||||||
//read all the column pins
|
//read all the column pins
|
||||||
digitalWrite(slaveSelect, LOW); //load parallel inputs to the register
|
|
||||||
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output
|
digitalWrite(slaveSelect, HIGH); //shift the data toward a serial output
|
||||||
SPI.transfer(&readState, byte_count);
|
|
||||||
|
|
||||||
//strobe row off
|
SPI.transfer(&readState, byte_count);
|
||||||
|
digitalWrite(slaveSelect, LOW); //load parallel inputs to registers
|
||||||
|
|
||||||
|
//digitalWrite(slaveSelect, HIGH); //de-assert slave
|
||||||
|
//SPI.endTransaction();
|
||||||
|
|
||||||
|
//strobe off
|
||||||
digitalWrite(strobePin, strobeOff);
|
digitalWrite(strobePin, strobeOff);
|
||||||
|
|
||||||
return readState;
|
return readState;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/* Scanner_ShiftRegsPISOMultiRow reads shift registers.
|
/* Scanner_ShiftRegsPISOMultiRow reads shift registers.
|
||||||
This was tested on 74HC165 shift registers, which are Parallel-In-Serial-Out (PISO).
|
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.
|
Shift registers can be daisy chained for a total of 32 read pins.
|
||||||
|
|
||||||
Example instantiation:
|
Example instantiation:
|
||||||
Scanner_ShiftRegsPISOMultiRow scanner_R(HIGH, SS, 4);
|
Scanner_ShiftRegsPISOMultiRow scanner_R(HIGH, SS, 4);
|
||||||
@ -18,7 +18,6 @@ There are three Scanner_ShiftRegsPISOMultiRow parameters.
|
|||||||
"strobeOn" paramter is active state HIGH or LOW.
|
"strobeOn" paramter is active state HIGH or LOW.
|
||||||
|
|
||||||
"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.
|
|
||||||
|
|
||||||
"byte_count" is the number of bytes to read from shift registers (1 to 4).
|
"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 should cover all the row's keys:
|
||||||
@ -26,7 +25,7 @@ byte_count should cover all the row's keys:
|
|||||||
|
|
||||||
Hardware setup:
|
Hardware setup:
|
||||||
Each row needs to be connected to a strobe pin from the controller.
|
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.
|
Switch and diode in series, connect shift-register parallel-input pins to strobed row.
|
||||||
|
|
||||||
For active low:
|
For active low:
|
||||||
Shift-register parallel-input pins need 10k Ohm pull-up resistors powered.
|
Shift-register parallel-input pins need 10k Ohm pull-up resistors powered.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "Scanner_ShiftRegsPISOSingleRow.h"
|
#include "Scanner_ShiftRegsPISOSingleRow.h"
|
||||||
|
|
||||||
/* constructor
|
/* constructor
|
||||||
|
Parameter strobeOn is not used.
|
||||||
*/
|
*/
|
||||||
Scanner_ShiftRegsPISOSingleRow::Scanner_ShiftRegsPISOSingleRow(const bool strobeOn,
|
Scanner_ShiftRegsPISOSingleRow::Scanner_ShiftRegsPISOSingleRow(const bool strobeOn,
|
||||||
const uint8_t slaveSelect, const uint8_t byte_count)
|
const uint8_t slaveSelect, const uint8_t byte_count)
|
||||||
@ -26,6 +27,7 @@ void Scanner_ShiftRegsPISOSingleRow::begin()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* scan() returns state of the shift register's input pins.
|
/* scan() returns state of the shift register's input pins.
|
||||||
|
Parameter strobePin is not used.
|
||||||
No strobe pin is needed, the shift register is wired so the strobe is effectivley always "on".
|
No strobe pin is needed, the shift register is wired so the strobe is effectivley always "on".
|
||||||
Bit patterns are 1 bit per key.
|
Bit patterns are 1 bit per key.
|
||||||
*/
|
*/
|
||||||
|
@ -22,7 +22,6 @@ There are three Scanner_ShiftRegsPISOSingleRow parameters.
|
|||||||
"strobeOn" paramter is ignored, but should be active state HIGH or LOW required by ScannerInterface.
|
"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.
|
|
||||||
|
|
||||||
"byte_count" is the number of bytes to read from shift registers (1 to 4).
|
"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 should cover all the row's keys:
|
||||||
@ -30,7 +29,8 @@ byte_count should cover all the row's keys:
|
|||||||
|
|
||||||
Hardware setup:
|
Hardware setup:
|
||||||
There is only one row, and it is permanently active.
|
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.
|
Switches are connected to shift-register parallel-input pins and row.
|
||||||
|
Diodes are not needed because there is only one row.
|
||||||
|
|
||||||
For active low:
|
For active low:
|
||||||
Shift-register parallel-input pins need 10k Ohm pull-up resistors powered.
|
Shift-register parallel-input pins need 10k Ohm pull-up resistors powered.
|
||||||
|
Before Width: | Height: | Size: 322 KiB |
@ -3,7 +3,7 @@ Tested on Teensy LC and two 74HC165 shift registers.
|
|||||||
|
|
||||||
Controller Two shift registers daisy chained
|
Controller Two shift registers daisy chained
|
||||||
| Left |**0**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|
|
| Left |**0**| | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|
|
||||||
|:-----:|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|
|
|-------|-----| |-------|-----|-----|-----|-----|-----|-----|-----|
|
||||||
| **0** | x | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|
| **0** | x | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||||
| **1** | y | | **1** | a | b | c | d | e | f | g |
|
| **1** | y | | **1** | a | b | c | d | e | f | g |
|
||||||
*/
|
*/
|
||||||
@ -49,10 +49,8 @@ uint8_t readPinCount_L = sizeof(readPins_L)/sizeof(*readPins_L);
|
|||||||
|
|
||||||
Scanner_uC scanner_L(LOW, readPins_L, readPinCount_L); //active LOW
|
Scanner_uC scanner_L(LOW, readPins_L, readPinCount_L); //active LOW
|
||||||
|
|
||||||
/* --------------- RIGHT SCANNER ---------------
|
// --------------- RIGHT SCANNER ---------------
|
||||||
use slaveSelect pin SS (Arduino pin 10) for fastest scan
|
Scanner_ShiftRegsPISOSingleRow scanner_R(HIGH, 10, 2); //active HIGH
|
||||||
*/
|
|
||||||
Scanner_ShiftRegsPISOSingleRow scanner_R(HIGH, SS, 2); //active HIGH
|
|
||||||
|
|
||||||
// =================== ROWS ====================
|
// =================== ROWS ====================
|
||||||
// ----------------- LEFT ROWS -----------------
|
// ----------------- LEFT ROWS -----------------
|
||||||
|
@ -6,7 +6,7 @@ This sketch:
|
|||||||
|
|
||||||
Controller I/O expander
|
Controller I/O expander
|
||||||
| Left | **0** | **1** | | Right | **0** | **1** |
|
| Left | **0** | **1** | | Right | **0** | **1** |
|
||||||
|:-----:|-------|-------|-|:-----:|-------|-------|
|
|-------|-------|-------| |-------|-------|-------|
|
||||||
| **1** | 1 | 2 | | **1** | 3 | 4 |
|
| **1** | 1 | 2 | | **1** | 3 | 4 |
|
||||||
| **0** | a | b | | **0** | c | d |
|
| **0** | a | b | | **0** | c | d |
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* keybrd_5b_LED_on_IOE.ino
|
/* keybrd_5b_LED_on_IOE.ino
|
||||||
|
|
||||||
This sketch:
|
This sketch:
|
||||||
is a simple 1-layer keyboard with CapsLck indicator LED on I/O expander
|
is a simple 1-layer keyboard with indicator LED on controller and 2 LEDs on I/O expander
|
||||||
runs on a two-matrix breadboard keyboard
|
runs on a two-matrix breadboard keyboard
|
||||||
modified keybrd_4c_split_keyboard_with_IOE.ino by adding LED_capsLck
|
modified keybrd_4c_split_keyboard_with_IOE.ino by adding LED_capsLck
|
||||||
|
|
||||||
@ -10,8 +10,8 @@ This layout table shows left and right matrices:
|
|||||||
Controller I/O expander
|
Controller I/O expander
|
||||||
| Left | **0** | **1** | | Right | **0** | **1** |
|
| Left | **0** | **1** | | Right | **0** | **1** |
|
||||||
|:-----:|-------|-------|-|:-----:|-------|-------|
|
|:-----:|-------|-------|-|:-----:|-------|-------|
|
||||||
| **1** |CapsLck| a 1 | | **1** | b 2 | c 3 |
|
| **0** |CapsLck| a 1 | | **1** | b 2 | c 3 |
|
||||||
| **0** | fn | x = | | **0** | y - | z / |
|
| **1** | fn | x = | | **0** | y - | z / |
|
||||||
*/
|
*/
|
||||||
// ################## GLOBAL ###################
|
// ################## GLOBAL ###################
|
||||||
// ================= INCLUDES ==================
|
// ================= INCLUDES ==================
|
||||||
@ -35,7 +35,7 @@ This layout table shows left and right matrices:
|
|||||||
// ============ SPEED CONFIGURATION ============
|
// ============ SPEED CONFIGURATION ============
|
||||||
ScanDelay scanDelay(9000);
|
ScanDelay scanDelay(9000);
|
||||||
|
|
||||||
// ==================== IC =====================
|
// ==================== ICs ====================
|
||||||
// ---------------- LEFT SCANNER ---------------
|
// ---------------- LEFT SCANNER ---------------
|
||||||
uint8_t readPins[] = {14, 15};
|
uint8_t readPins[] = {14, 15};
|
||||||
const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins);
|
||||||
@ -47,8 +47,8 @@ LED_uC LED_capsLck(21);
|
|||||||
|
|
||||||
// --------------- RIGHT SCANNER ---------------
|
// --------------- RIGHT SCANNER ---------------
|
||||||
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
||||||
Port_MCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read and LED
|
Port_MCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read
|
||||||
Port_MCP23S17 portB(IOE_ADDR, 1, 0); //for strobe and LED
|
Port_MCP23S17 portB(IOE_ADDR, 1, 0); //for strobe
|
||||||
|
|
||||||
Scanner_IOE scanner_R(LOW, portB, portA);
|
Scanner_IOE scanner_R(LOW, portB, portA);
|
||||||
|
|
||||||
|
@ -43,21 +43,21 @@ These are explained in [How to Use a Breadboard](https://learn.sparkfun.com/tuto
|
|||||||
|
|
||||||
Electrostatic discharge (ESD) safety
|
Electrostatic discharge (ESD) safety
|
||||||
------------------------------------
|
------------------------------------
|
||||||
Static electricity can damage a microcontroller in ways that are hard to trouble shoot.
|
Static electricity can damage a ICs in ways that are hard to trouble shoot.
|
||||||
|
|
||||||
I live in a desert on a carpeted floor and get zapped by door knobs regularly.
|
Here is a ESD precaution for handling ICs:
|
||||||
Here is the ESD precaution I take whenever I handle a microcontroller:
|
|
||||||
|
|
||||||
1. Touch the bare metal on the back of my desktop computer (its grounded).
|
1. Touch the bare metal on the back of my desktop computer (its grounded).
|
||||||
2. Then touch the metal USB connector case on the microcontroller.
|
2. Then touch the IC or circuit (if its a micro-controller, touch the metal USB connector case).
|
||||||
|
|
||||||
Anti-static mat or anti-static wristband are also effective.
|
|
||||||
Being tethered by an anti-static wristband can be inconvenient (wireless antistatic wrist straps are a scam).
|
|
||||||
|
|
||||||
|
I take these ESD precaution because I live in a dry environment on a carpeted floor.
|
||||||
Not everyone needs to take ESD precautions:
|
Not everyone needs to take ESD precautions:
|
||||||
* http://forum.arduino.cc/index.php?topic=4643.0
|
* http://forum.arduino.cc/index.php?topic=4643.0
|
||||||
* https://forums.adafruit.com/viewtopic.php?f=8&t=12128
|
* https://forums.adafruit.com/viewtopic.php?f=8&t=12128
|
||||||
|
|
||||||
|
Anti-static mat or anti-static wristband are also effective.
|
||||||
|
But being tethered by an anti-static wristband can be inconvenient (wireless antistatic wrist straps are a scam).
|
||||||
|
|
||||||
Building a basic breadboard keyboard
|
Building a basic breadboard keyboard
|
||||||
------------------------------------
|
------------------------------------
|
||||||
The basic breadboard keyboard has 4 switches.
|
The basic breadboard keyboard has 4 switches.
|
||||||
|
@ -20,7 +20,9 @@ The scanner should have enough readPins to cover all the keys of the longest row
|
|||||||
| Layout |**0**|**1**|**2**|
|
| Layout |**0**|**1**|**2**|
|
||||||
|:------:|:---:|:---:|:---:|
|
|:------:|:---:|:---:|:---:|
|
||||||
| **0** | 1 | 2 | 3 |
|
| **0** | 1 | 2 | 3 |
|
||||||
| **1** | a | b |
|
| **1** | a | b | |
|
||||||
|
|
||||||
|
[keybrd tutorials usability survey](../CONTRIBUTING.md##keybrd-tutorials-usability-survey)
|
||||||
|
|
||||||
<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>.
|
||||||
|
@ -28,9 +28,10 @@ But if there are enough pins on the controller, using just a cable with more wir
|
|||||||
|
|
||||||
I/O Expanders can power LEDs, while PISO shift registers can not.
|
I/O Expanders can power LEDs, while PISO shift registers can not.
|
||||||
|
|
||||||
I2C is a little slow if the I/O expander is scanning more than 4 rows.
|
I2C is fast enough for scanning up to 5 rows.
|
||||||
The keybrd_DH (DodoHand) sketch polls 5 rows over I2C at 7.5ms per keyboard scan.
|
SPI is much faster, but requires 2 additional wires.
|
||||||
Which is acceptable, but faster would be nicer.
|
|
||||||
|
More scanning options are reviewed at http://www.openmusiclabs.com/learning/digital/input-matrix-scanning/
|
||||||
|
|
||||||
## Cables table
|
## Cables table
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ There are also wireless options if you don't mind adding complexity and maintain
|
|||||||
|
|
||||||
The 8-wire "GearIT Cat 6 Ethernet Flat Patch Cable 7 Feet" is very flexible.
|
The 8-wire "GearIT Cat 6 Ethernet Flat Patch Cable 7 Feet" is very flexible.
|
||||||
It's available at Walmart (9/19/16) if you want to feel the merchandise before you buy.
|
It's available at Walmart (9/19/16) if you want to feel the merchandise before you buy.
|
||||||
All the modular connectors are flat.
|
All the modular connector cables are available in the flat form factor.
|
||||||
|
|
||||||
For prototyping on perfboards, consider a 0.1" header.
|
For prototyping on perfboards, consider a 0.1" header.
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ This table lists what gets connected to the 74HC165 pins:
|
|||||||
**74HC165 left (lower half of breadboard)**
|
**74HC165 left (lower half of breadboard)**
|
||||||
|
|
||||||
|NAME |PIN#|DESCRIPTION |TO TEENSY LC PIN#|CHAIN |
|
|NAME |PIN#|DESCRIPTION |TO TEENSY LC PIN#|CHAIN |
|
||||||
|--------|:--:|--------------------|-----------------|-----------|
|
|:-------|:--:|:-------------------|:----------------|:----------|
|
||||||
|SH/LD |1 |shift or load input |CS0 10 |green wire |
|
|SH/LD |1 |shift or load input |CS0 10 |green wire |
|
||||||
|CLK |2 |clock input |SCK0 13 |yellow wire|
|
|CLK |2 |clock input |SCK0 13 |yellow wire|
|
||||||
| D4 |3 |parallel input | | |
|
| D4 |3 |parallel input | | |
|
||||||
@ -49,7 +49,7 @@ This table lists what gets connected to the 74HC165 pins:
|
|||||||
**74HC165 right (upper half of breadboard)**
|
**74HC165 right (upper half of breadboard)**
|
||||||
|
|
||||||
|NAME |PIN#|DESCRIPTION |TO TEENSY LC PIN#|CHAIN |
|
|NAME |PIN#|DESCRIPTION |TO TEENSY LC PIN#|CHAIN |
|
||||||
|--------|:--:|--------------------|-----------------|-------------------------|
|
|:-------|:--:|:-------------------|:----------------|:------------------------|
|
||||||
|VCC |16 |power pin |3.3V |red wire |
|
|VCC |16 |power pin |3.3V |red wire |
|
||||||
|CLK INH |15 |clock inhibit | |blue bus |
|
|CLK INH |15 |clock inhibit | |blue bus |
|
||||||
| D3 |14 |parallel input | | |
|
| D3 |14 |parallel input | | |
|
||||||
|
@ -17,6 +17,31 @@ Two rows (red buses) are connected to the I/O expander.
|
|||||||
|
|
||||||
![breadboard keyboard with IOE](keybrd_4c_split_keyboard_with_IOE/front.JPG "breadboard keyboard with IOE")
|
![breadboard keyboard with IOE](keybrd_4c_split_keyboard_with_IOE/front.JPG "breadboard keyboard with IOE")
|
||||||
|
|
||||||
|
I/O expanders
|
||||||
|
-------------
|
||||||
|
The MCP23S17 I/O expander has two ports with 8 I/O pins each.
|
||||||
|
I/O expander input/output pins are connected to a switch matrix.
|
||||||
|
Port B strobes one row at a time.
|
||||||
|
Port A reads the columns.
|
||||||
|
|
||||||
|
SPI and I2C communication protocols
|
||||||
|
-----------------------------------
|
||||||
|
SPI and I2C are popular communication protocols.
|
||||||
|
Either one can be used to connect split keyboards.
|
||||||
|
|
||||||
|
I2C is fast enough for scanning up to 5 rows.
|
||||||
|
The keybrd_DH (DodoHand) sketch polls 5 rows over I2C at 7.5ms per keyboard scan.
|
||||||
|
|
||||||
|
SPI is much faster, but requires 2 additional wires.
|
||||||
|
Use SPI if your key matrix has more then 5 rows.
|
||||||
|
|
||||||
|
| connection type | controller pins | wire count |
|
||||||
|
|------------------------|:---------------:|:----------:|
|
||||||
|
| I/O expander SPI | 4 | 6 |
|
||||||
|
| I/O expander I2C | 2 | 4 |
|
||||||
|
|
||||||
|
The example in this tutorial uses the SPI protocol.
|
||||||
|
|
||||||
Building a split keyboard with I/O Expander
|
Building a split keyboard with I/O Expander
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
Starting with the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md), add parts as described above.
|
Starting with the basic breadboard keyboard described in [tutorial_1_breadboard_keyboard.md](tutorial_1_breadboard_keyboard.md), add parts as described above.
|
||||||
|
@ -39,7 +39,7 @@ Less resistance makes the LED brighter.
|
|||||||
Too little resistance will burn out the LED.
|
Too little resistance will burn out the LED.
|
||||||
The current supplied to an LED should always be limited by a resistor or some other device.
|
The current supplied to an LED should always be limited by a resistor or some other device.
|
||||||
|
|
||||||
LED current limiting resistor values
|
LED current-limiting resistor values
|
||||||
------------------------------------
|
------------------------------------
|
||||||
In the section we will compute the minimum resistor value for maximum LED brightness.
|
In the section we will compute the minimum resistor value for maximum LED brightness.
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ keybrd sketch with LEDs on IOE
|
|||||||
------------------------------
|
------------------------------
|
||||||
The [keybrd_5b_LED_on_IOE.ino](keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino) sketch will run on the above breadboard keyboard.
|
The [keybrd_5b_LED_on_IOE.ino](keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino) sketch will run on the above breadboard keyboard.
|
||||||
|
|
||||||
The sketch features:
|
The sketch demonstrates:
|
||||||
* multiple layers
|
* multiple layers
|
||||||
* split keyboard
|
* split keyboard
|
||||||
* LED on controller
|
* LED on controller
|
||||||
|
33
unit_tests/PortMCP23018_write/PortMCP23018_write.ino
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
@ -2,28 +2,24 @@
|
|||||||
Picture of hardware is in unit_tests/PortMCP23S17_read/PortMCP23S17_bb.JPG
|
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.
|
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.
|
|
||||||
output is: 10101010
|
output is: 10101010
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PortIOE.h"
|
#include "Port_MCP23S17.h"
|
||||||
#include "PortMCP23S17.h"
|
|
||||||
|
|
||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins grounded
|
||||||
PortIOE portB(1);
|
Port_MCP23S17 portB(IOE_ADDR, 1, ~0); //read all pins
|
||||||
|
|
||||||
PortMCP23S17 portBRead(portB, ~0);
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
uint8_t portBState; //bit pattern
|
uint8_t BitPattern; //reading of port B
|
||||||
|
|
||||||
delay(6000);
|
delay(6000);
|
||||||
portBRead.begin(HIGH); //HIGH or LOW, not matter
|
portB.begin(HIGH); //HIGH or LOW, does not matter
|
||||||
|
|
||||||
portBState = portBRead.read();
|
BitPattern = portB.read();
|
||||||
Keyboard.print("portBState = ");
|
Keyboard.print("BitPattern = ");
|
||||||
Keyboard.println(portBState, BIN); //prints 10101010
|
Keyboard.println(BitPattern, BIN); //prints 10101010
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() { }
|
void loop() { }
|
||||||
|
@ -1,34 +1,29 @@
|
|||||||
/* unit test for PortMCP23S17
|
/* unit test for Port_MCP23S17
|
||||||
Picture of hardware is in unit_tests/PortMCP23S17_read/PortMCP23S17_bb.JPG
|
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.
|
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 outputs.
|
Use a volt meter to measure port-A GPIO-pin outputs or red LED.
|
||||||
OR low-voltage LED, with forward voltage less than 2 volts.
|
|
||||||
*/
|
*/
|
||||||
#include "PortIOE.h"
|
#include "Port_MCP23S17.h"
|
||||||
#include "PortMCP23S17.h"
|
|
||||||
|
|
||||||
const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins grounded
|
||||||
PortIOE portA(0);
|
Port_MCP23S17 portA(IOE_ADDR , 0, 0); //PortAWrite needed for begin()
|
||||||
|
|
||||||
PortMCP23S17 portAWrite(portA, 0); //PortAWrite needed for begin()
|
|
||||||
|
|
||||||
//const uint8_t GPIOA = 0x12; //LEDs are on port A
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
delay(6000);
|
delay(6000);
|
||||||
portAWrite.begin(LOW); //HIGH or LOW, not matter if readPins=0
|
Keyboard.println("start setup");
|
||||||
Keyboard.print("start writing");
|
portA.begin(LOW); //HIGH or LOW, not matter if readPins=0
|
||||||
|
Keyboard.println("start loop");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
portAWrite.write(~0, HIGH); //set all GPIOA pins HIGH
|
portA.write(~0, HIGH); //set all GPIOA pins HIGH
|
||||||
delay(2000);
|
delay(2000);
|
||||||
|
|
||||||
portAWrite.write(~0, LOW); //set all GPIOA pins LOW
|
portA.write(~0, LOW); //set all GPIOA pins LOW
|
||||||
delay(2000);
|
delay(2000);
|
||||||
}
|
}
|
||||||
|