Update housing and code
--add local timezone --add sunrise/sunset calculation and LED illumination accordingly --remove touch sensor check --change mqtt messages
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
SparkFun SX1509 IO Expander Breakout Arduino Library
|
||||
========================================
|
||||
|
||||
[](https://www.sparkfun.com/products/13601)
|
||||
|
||||
[*SparkFun SX1509 IO Expander Breakout (SKU)*](https://www.sparkfun.com/products/13601)
|
||||
|
||||
Arduino library for the SX1509 16-I/O expander. Capable of driving LEDs - with blink, and breathe functions - or monitoring up to 64 buttons in an 8x8 array.
|
||||
|
||||
Are you low on I/O? No problem! The SX1509 Breakout is a 16-channel GPIO expander with an I2C interface – that means with just two wires, your microcontroller can interface with 16 fully configurable digital input/output pins. But the SX1509 can do so much more than just simple digital pin control. It can produce PWM signals, so you can dim LEDs. It can be set to blink or even breathe pins at varying rates. This breakout is similar to a multiplexer or "mux," in that it allows you to get more IO from less pins. And, with a built-in keypad engine, it can interface with up to 64 buttons set up in an 8x8 matrix.
|
||||
|
||||
Two headers at the top and bottom of the breakout board function as the input and control headers to the board. This is where you can supply power to the SX1509, and where your I2C signals – SDA and SCL – will terminate. GPIO and power buses are broken out in every-which direction, and configurable jumpers cover most of the rest of the board.
|
||||
|
||||
Since the I/O banks can operate between 1.2V and 3.6V (5.5V tolerant) independent of both the core and each other, this device can also work as a level-shifter. The SX1509 breakout makes it easy to prototype so you can add more I/O onto your Arduino or I/O limited controller. We've even spun up an Arduino Library to get you started!
|
||||
|
||||
Please be aware that v3 of the library breaks previous version compatiblity on a few things:
|
||||
|
||||
* Wire.begin() must be called explicitly within the Arduino sketch before io.begin() is called. This may break code that does not have Wire.begin().
|
||||
* io.begin() has been expanded to include io.begin(deviceAddress, wirePort, resetPin). This may break code where resetPin was the 2nd argument.
|
||||
|
||||
Repository Contents
|
||||
-------------------
|
||||
|
||||
* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
|
||||
* **/extras** - Additional documentation for the user. These files are ignored by the IDE.
|
||||
* **/src** - Source files for the library (.cpp, .h).
|
||||
* **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE.
|
||||
* **library.properties** - General library properties for the Arduino package manager.
|
||||
|
||||
Documentation
|
||||
--------------
|
||||
|
||||
* **[SparkFun SX1509 Breakout Board Hookup Guide](https://learn.sparkfun.com/tutorials/sx1509-io-expander-breakout-hookup-guide)** - SparkFun tutorial demonstrating how to hook up the SX1509 Breakout and use this library.
|
||||
* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
|
||||
* **[Product Repository](https://github.com/sparkfun/SX1509_IO-Expander)** - Main repository (including hardware files) for the SX1509 IO Expander Breakout.
|
||||
|
||||
Products that use this Library
|
||||
---------------------------------
|
||||
|
||||
* [BOB-13601](https://www.sparkfun.com/products/13601) - SX1509 16 I/O Breakout Board (v2.0)
|
||||
* [BOB-11502](https://www.sparkfun.com/products/retired/11502)- (Retired) 16 I/O I2C port expander.
|
||||
|
||||
Version History
|
||||
---------------
|
||||
|
||||
* [V_3.x] - Incorporate PRs including the ability to pass in a wire port in begin().
|
||||
* [V_2.0.1](https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library/tree/V_2.0.1) - Version 2.0.1. More user-friendly function calls. Increased clock functionality. More examples. Mostly backwards compatible with older versions.
|
||||
* [V_1.0.0](https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library/tree/V_1.0.0) - Version 1.0.0
|
||||
|
||||
License Information
|
||||
-------------------
|
||||
|
||||
This product is _**open source**_!
|
||||
|
||||
The **code** is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!
|
||||
|
||||
Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license.
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
|
||||
- Your friends at SparkFun.
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/*************************************************************
|
||||
digitalReadWriteCombined.ino
|
||||
SparkFun SX1509 I/O Expander Example: digital I/O (digitalRead/digitalWrite)
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates the SX1509's digitalRead and digitalWrite
|
||||
functionality. We'll attach an active-low button to an
|
||||
INPUT_PULLUP input and attach an LED to a pin set as OUTPUT.
|
||||
Then whenever the button read's LOW, we'll toggle the LED.
|
||||
Note that the code will wait until the button is released
|
||||
before reading the SX1509 pins again.
|
||||
|
||||
After uploading the sketch, open your serial monitor and set
|
||||
it to 115200 baud.
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
0 ---------------------------------]BTN[----GND
|
||||
15 -------------------------------- LED+
|
||||
LED- -/\/\/\- GND
|
||||
330
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 pin definitions:
|
||||
// Note: these aren't Arduino pins. They're the SX1509 I/O:
|
||||
const byte SX1509_LED_PIN = 15; // LED connected to 15 (source ing current)
|
||||
const byte SX1509_BUTTON_PIN = 0; // Button connected to 0 (Active-low button)
|
||||
|
||||
bool ledState = false;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Serial is used in this example to display the input value
|
||||
// of the SX1509_INPUT_PIN input:
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin(); //Initialize I2C bus
|
||||
|
||||
pinMode(13, OUTPUT); // Use pin 13 LED as debug output
|
||||
digitalWrite(13, LOW); // Start it as low
|
||||
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
digitalWrite(13, HIGH); // If we failed to communicate, turn the pin 13 LED on
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Call io.pinMode(<pin>, <mode>) to set any SX1509 pin as
|
||||
// either an INPUT, OUTPUT, INPUT_PULLUP, or ANALOG_OUTPUT
|
||||
// Set output for LED:
|
||||
io.pinMode(SX1509_LED_PIN, OUTPUT);
|
||||
// Use a pull-up resistor on the button's input pin. When
|
||||
// the button is pressed, the pin will be read as LOW:
|
||||
io.pinMode(SX1509_BUTTON_PIN, INPUT_PULLUP);
|
||||
|
||||
// Blink the LED a few times before we start:
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
// Use io.digitalWrite(<pin>, <LOW | HIGH>) to set an
|
||||
// SX1509 pin either HIGH or LOW:
|
||||
io.digitalWrite(SX1509_LED_PIN, HIGH);
|
||||
delay(100);
|
||||
io.digitalWrite(SX1509_LED_PIN, LOW);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Use io.digitalRead() to check if an SX1509 input I/O is
|
||||
// either LOW or HIGH.
|
||||
if (io.digitalRead(SX1509_BUTTON_PIN) == LOW)
|
||||
{
|
||||
// Print the status of the other pin:
|
||||
Serial.print("SX1509_BUTTON_PIN status: ");
|
||||
// Read the pin to print either 0 or 1
|
||||
Serial.println(io.digitalRead(SX1509_BUTTON_PIN));
|
||||
|
||||
// If the button is pressed toggle the LED:
|
||||
ledState = !ledState;
|
||||
io.digitalWrite(SX1509_LED_PIN, ledState);
|
||||
|
||||
// Print the status of the other pin:
|
||||
Serial.print("SX1509_LED_PIN status: ");
|
||||
// Read the pin to print either 0 or 1
|
||||
Serial.println(ledState);
|
||||
|
||||
|
||||
Serial.print("Waiting for button to release...");
|
||||
while (io.digitalRead(SX1509_BUTTON_PIN) == LOW)
|
||||
; // Wait for button to release
|
||||
Serial.println("Button released!");
|
||||
|
||||
//delay(200); //uncomment to add a small delay for button debouncing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*************************************************************
|
||||
analogWrite.ino
|
||||
SparkFun SX1509 I/O Expander Example: pwm output (analogWrite)
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates the SX1509's analogWrite function.
|
||||
Connect an LED to the SX1509's pin 15 (or any other pin, they
|
||||
can all PWM!). The SX1509 can either sink or source current,
|
||||
just don't forget your limiting resistor!
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
15 -------------------------------- LED+
|
||||
LED- -/\/\/\- GND
|
||||
330
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 Pin definition:
|
||||
const byte SX1509_LED_PIN = 15; // LED to SX1509's pin 15
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Use the pinMode(<pin>, <mode>) function to set our led
|
||||
// pin as an ANALOG_OUTPUT, which is required for PWM output
|
||||
io.pinMode(SX1509_LED_PIN, ANALOG_OUTPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Ramp brightness up, from 0-255, delay 2ms in between
|
||||
// analogWrite's
|
||||
for (int brightness = 0; brightness < 256; brightness++)
|
||||
{
|
||||
// Call io.analogWrite(<pin>, <0-255>) to configure the
|
||||
// PWM duty cycle
|
||||
io.analogWrite(SX1509_LED_PIN, brightness);
|
||||
delay(2); // Delay 2 milliseconds
|
||||
}
|
||||
delay(500); // Delay half-a-second
|
||||
|
||||
// Ramp brightness down, from 255-0, delay 2ms in between
|
||||
// analogWrite's
|
||||
for (int brightness = 255; brightness >= 0; brightness--)
|
||||
{
|
||||
io.analogWrite(SX1509_LED_PIN, brightness);
|
||||
delay(2); // Delay 2 milliseconds
|
||||
}
|
||||
delay(500); // Delay half-a-second
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*************************************************************
|
||||
blink.ino
|
||||
SparkFun SX1509 I/O Expander Example: blink output
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates the SX1509's set-it-and-forget-it
|
||||
blink function. We'll set the pin up as an OUTPUT, and call
|
||||
io.blink() all in setup(), then watch the LED blink by itself
|
||||
in loop().
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
15 -------------------------------- LED+
|
||||
LED- -/\/\/\- GND
|
||||
330
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 Pin definition:
|
||||
const byte SX1509_LED_PIN = 15; // LED to SX1509's pin 15
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Set up the SX1509's clock to use the internal 2MHz
|
||||
// oscillator. The second parameter divides the oscillator
|
||||
// clock to generate a slower LED clock. 4 divides the 2MHz
|
||||
// clock by 2 ^ (4-1) (8, ie. 250kHz). The divider parameter
|
||||
// can be anywhere between 1-7.
|
||||
io.clock(INTERNAL_CLOCK_2MHZ, 4);
|
||||
|
||||
io.pinMode(SX1509_LED_PIN, OUTPUT); // Set LED pin to OUTPUT
|
||||
|
||||
// Blink the LED pin -- ~1000 ms LOW, ~500 ms HIGH:
|
||||
io.blink(SX1509_LED_PIN, 1000, 500);
|
||||
// The timing parameters are in milliseconds, but they
|
||||
// aren't 100% exact. The library will estimate to try to
|
||||
// get them as close as possible. Play with the clock
|
||||
// divider to maybe get more accurate timing.
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Relax! The SX1509's got this...
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*************************************************************
|
||||
breathe.ino
|
||||
SparkFun SX1509 I/O Expander Example: breathe output
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates the SX1509's set-it-and-forget-it
|
||||
breathe function. The SX1509 will pulse an LED, smoothly
|
||||
ramping its brightness up-then-down. We'll set the pin up as
|
||||
an ANALOG_OUTPUT, and call io.breathe() all in setup(), then
|
||||
watch the LED pulse by itself in loop().
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
15 --------------------------------- LED+
|
||||
LED- -/\/\/\- GND
|
||||
330
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 Pin definition:
|
||||
const byte SX1509_LED_PIN = 15; // LED to SX1509's pin 15
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Use the internal 2MHz oscillator.
|
||||
// Set LED clock to 500kHz (2MHz / (2^(3-1)):
|
||||
io.clock(INTERNAL_CLOCK_2MHZ, 3);
|
||||
|
||||
// To breathe an LED, make sure you set it as an
|
||||
// ANALOG_OUTPUT, so we can PWM the pin:
|
||||
io.pinMode(SX1509_LED_PIN, ANALOG_OUTPUT);
|
||||
|
||||
// Breathe an LED: 1000ms LOW, 500ms HIGH,
|
||||
// 500ms to rise from low to high
|
||||
// 250ms to fall from high to low
|
||||
io.breathe(SX1509_LED_PIN, 1000, 500, 500, 250);
|
||||
// The timing parameters are in milliseconds, but they
|
||||
// aren't 100% exact. The library will estimate to try to
|
||||
// get them as close as possible. Play with the clock
|
||||
// divider to maybe get more accurate timing.
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Enjoy your hypnotically breathing LED!
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*************************************************************
|
||||
clock.ino
|
||||
SparkFun SX1509 I/O Expander Example: clock output
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates the SX1509's clock output
|
||||
functionality. The OSC pins (OSCIO in the datasheet), can be
|
||||
configured as either a clock input, clock output, or an
|
||||
extra output!
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
OSC ------------- Check with a multimeter or o-scope
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Configure clock:
|
||||
// - INTERNAL_CLOCK_2MHZ: Set clock to internal 2MHz
|
||||
// - 2: Set LED clock to divide by 2^(2-1) (2)
|
||||
// - OUTPUT: Configure OSCIO pin as a clock OUTPUT
|
||||
// - outputFreq: Sets the frequncy of output
|
||||
// - 0: 0Hz LOW
|
||||
// - 0x1-0xE: fOSCout = Fosc / 2 ^ (outputFreq - 1) Hz
|
||||
// - 0xF: 0Hz HIGH
|
||||
byte outputFreq = 6; // Set output freq. to 62.5 kHz
|
||||
io.clock(INTERNAL_CLOCK_2MHZ, 2, OUTPUT, outputFreq);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/*************************************************************
|
||||
demo.ino
|
||||
SparkFun SX1509 I/O Expander Example: fun time demo!
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This is a massive demo sketch to show off what the SX1509 can
|
||||
do! It combines the keypad engine, LED driving, digital
|
||||
inputs, interrupt triggering, and we even emulate a simple SPI
|
||||
interface with it!
|
||||
|
||||
All 16 of the SX1509's pins are used. Connected to a 12-button
|
||||
keypad, Serial 7-Segment Display, and three buttons-with-LEDs:
|
||||
|
||||
- 12-Button Keypad: https://sfe.io/p8653
|
||||
- Serial 7-Segment (S7S): https://sfe.io/p11441
|
||||
- 3x LED Buttons: https://sfe.io/p10443
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino ------------ Component
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
0 --------------------------------- Keypad 2 (row 1)
|
||||
1 --------------------------------- Keypad 7 (row 2)
|
||||
2 --------------------------------- Keypad 6 (row 3)
|
||||
3 --------------------------------- Keypad 4 (row 4)
|
||||
4 --------------------------------- S7S SS
|
||||
5 --------------------------------- Button 1
|
||||
6 --------------------------------- Button 2
|
||||
7 --------------------------------- Button 3
|
||||
8 --------------------------------- Keypad 3 (col 1)
|
||||
9 --------------------------------- Keypad 1 (col 2)
|
||||
10 -------------------------------- Keypad 5 (col 3)
|
||||
11 -------------------------------- S7S SDI
|
||||
12 -------------------------------- S7S SCK
|
||||
13 -------------------------------- LED 1
|
||||
14 -------------------------------- LED 2
|
||||
15 -------------------------------- LED 3
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
#define KEY_ROWS 4 // Number of rows in the keypad matrix
|
||||
#define KEY_COLS 3 // Number of columns in the keypad matrix
|
||||
|
||||
// keyMap maps row/column combinations to characters:
|
||||
char keyMap[KEY_ROWS][KEY_COLS] = {
|
||||
{'0', '1', '2'},
|
||||
{'3', '4', '5'},
|
||||
{'6', '7', '8'},
|
||||
{'*', '0', '#'}};
|
||||
|
||||
// SX1509 Pins:
|
||||
#define SX1509_RED_LED 13 // Red LED on breath-able pin
|
||||
#define SX1509_GRN_LED 14 // Green LED on breath-able pin
|
||||
#define SX1509_BLU_LED 15 // Blue LED on breath-able pin
|
||||
|
||||
#define SX1509_RED_BTN 5 // Red button, active-low
|
||||
#define SX1509_GRN_BTN 6 // Green button, active-low
|
||||
#define SX1509_BLU_BTN 7 // Blue button, active-low
|
||||
|
||||
#define SX1509_SDO_PIN 11 // S7S SDI pin (serial-data in)
|
||||
#define SX1509_SCK_PIN 12 // S7S SCK pin (serial clock)
|
||||
#define SX1509_SS_PIN 4 // S7S SS pin (slave-select)
|
||||
|
||||
// Arduino Pins:
|
||||
#define ARDUINO_INT_PIN 2 // External interrupt pin
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Serial is used to display the keypad presses
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Initialize the keypad.
|
||||
// Sleep time off (0). 16ms scan time, 8ms debounce:
|
||||
io.keypad(KEY_ROWS, KEY_COLS, 0, 16, 8);
|
||||
|
||||
// Set up the LED pins as ANALOG_OUTPUTs:
|
||||
io.pinMode(SX1509_RED_LED, ANALOG_OUTPUT);
|
||||
io.pinMode(SX1509_GRN_LED, ANALOG_OUTPUT);
|
||||
io.pinMode(SX1509_BLU_LED, ANALOG_OUTPUT);
|
||||
|
||||
// Then configure each of the LED pins to breathe at
|
||||
// different rates. Red LED is HIGH 2000ms, LOW 2000ms, and
|
||||
// takes 1000ms to rise/fall
|
||||
io.breathe(SX1509_RED_LED, 2000, 2000, 1000, 1000);
|
||||
// Green LED is on/off for 8s, and takes 4s to rise/fall:
|
||||
// We can also set the on/off intensity. On intensity is
|
||||
// 127 off is 16 out of 255.
|
||||
io.breathe(SX1509_GRN_LED, 8000, 8000, 4000, 4000,
|
||||
127, 16);
|
||||
// You can set the breathe pulse to either LOGARITHMIC or
|
||||
// LINEAR. They default to LINEAR.
|
||||
// Blue LED is on/off for 500 ms, rises/falls in 500ms:
|
||||
io.breathe(SX1509_BLU_LED, 500, 500, 500, 500,
|
||||
255, 0, LOGARITHMIC);
|
||||
|
||||
// Instead of breathing the entire duration, we can write a
|
||||
// breathing pin HIGH to initiate SINGLE-SHOT mode. After a
|
||||
// HIGH write, each pin will do its breathe pulse once,
|
||||
// then stop.
|
||||
io.digitalWrite(SX1509_GRN_LED, HIGH);
|
||||
io.digitalWrite(SX1509_RED_LED, HIGH);
|
||||
io.digitalWrite(SX1509_BLU_LED, HIGH);
|
||||
// Call io.sync() to synchronize all LED outputs.
|
||||
io.sync();
|
||||
|
||||
// Set up the button inputs. They'll all be active-low, so
|
||||
// configure them with internal pull-ups
|
||||
io.pinMode(SX1509_RED_BTN, INPUT_PULLUP);
|
||||
io.pinMode(SX1509_GRN_BTN, INPUT_PULLUP);
|
||||
io.pinMode(SX1509_BLU_BTN, INPUT_PULLUP);
|
||||
// Enable interrupts on each button pin. Generate an
|
||||
// interrupt on either a rise or fall using CHANGE.
|
||||
io.enableInterrupt(SX1509_RED_BTN, CHANGE);
|
||||
io.enableInterrupt(SX1509_GRN_BTN, CHANGE);
|
||||
io.enableInterrupt(SX1509_BLU_BTN, CHANGE);
|
||||
|
||||
// Set up the outputs for the serial 7-segment display's
|
||||
// SPI interface.
|
||||
io.pinMode(SX1509_SDO_PIN, OUTPUT); // SDO (S7S's SDI)
|
||||
io.digitalWrite(SX1509_SDO_PIN, HIGH);
|
||||
io.pinMode(SX1509_SCK_PIN, OUTPUT); // SCK (serial clock)
|
||||
io.digitalWrite(SX1509_SCK_PIN, HIGH);
|
||||
io.pinMode(SX1509_SS_PIN, OUTPUT); // SS (Slave-select)
|
||||
io.digitalWrite(SX1509_SS_PIN, HIGH);
|
||||
|
||||
// Finally, set up our Arduino pin(s). Set the interrupt as
|
||||
// an INPUT_PULLUP. SX1509's interrupt output is active-low.
|
||||
pinMode(ARDUINO_INT_PIN, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// If the interrupt triggers (goes LOW):
|
||||
if (!digitalRead(ARDUINO_INT_PIN))
|
||||
{
|
||||
// Don't know if keypad or a button triggered the int
|
||||
doKeypad(); // Check the keypad first.
|
||||
|
||||
// Then check the buttons.
|
||||
// The io.checkInterrupt(<pin>) function can check if a
|
||||
// single pin triggered the interrupt. Note that this
|
||||
// function will not clear the interrupt.
|
||||
if (io.checkInterrupt(SX1509_RED_BTN)) // Red button
|
||||
{
|
||||
// If the button was pressed turn the LED of.
|
||||
// If the button was released. Single-shot
|
||||
// the LED's breathe mode.
|
||||
io.digitalWrite(SX1509_RED_LED,
|
||||
io.digitalRead(SX1509_RED_BTN));
|
||||
}
|
||||
if (io.checkInterrupt(SX1509_GRN_BTN)) // Green button
|
||||
{
|
||||
io.digitalWrite(SX1509_GRN_LED,
|
||||
io.digitalRead(SX1509_GRN_BTN));
|
||||
}
|
||||
if (io.checkInterrupt(SX1509_BLU_BTN)) // Blue button
|
||||
{
|
||||
io.digitalWrite(SX1509_BLU_LED,
|
||||
io.digitalRead(SX1509_BLU_BTN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void doKeypad()
|
||||
{
|
||||
static int lastKeyPress = 255;
|
||||
static unsigned long lastKeyPressTime = 0;
|
||||
|
||||
static int digitPos = 0;
|
||||
|
||||
// Use io.readKeypad() to check which (if any) row and
|
||||
// columns are active.
|
||||
unsigned int keyData = io.readKeypad();
|
||||
// readKeypad may be 0, which means the keypad didn't
|
||||
// generate the interrupt. If not, though...
|
||||
if (keyData != 0)
|
||||
{
|
||||
// Use getRow() and getCol() to parse the row and column:
|
||||
byte row = io.getRow(keyData);
|
||||
byte col = io.getCol(keyData);
|
||||
// Use those values to get the key pressed:
|
||||
int key = keyMap[row][col];
|
||||
|
||||
// If it's a new key press, or enough time has passed
|
||||
if ((keyData != lastKeyPress) ||
|
||||
(lastKeyPressTime < millis() - 100)) //100ms
|
||||
{
|
||||
// Print the key press to serial for debugging:
|
||||
Serial.print(String(row) + " | " + String(col) + " | ");
|
||||
Serial.println(key);
|
||||
lastKeyPress = keyData;
|
||||
lastKeyPressTime = millis();
|
||||
|
||||
// Use the SX1509's I/O pins to write an "SPI" byte
|
||||
// to the serial 7-segment display.
|
||||
sendSPIByte(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendSPIByte(byte data)
|
||||
{
|
||||
// Mock up a simple SPI output transfer using a data
|
||||
// output (SDO), clock (SCK), and slave-select (SS).
|
||||
// Begin with all pins LOW.
|
||||
io.digitalWrite(SX1509_SDO_PIN, LOW);
|
||||
io.digitalWrite(SX1509_SCK_PIN, LOW);
|
||||
// Setting SS LOW initiates the SPI transfer:
|
||||
io.digitalWrite(SX1509_SS_PIN, LOW);
|
||||
|
||||
// Cycle through all 8-bits of the data value, from
|
||||
// high to low:
|
||||
for (int b = 7; b >= 0; b--)
|
||||
{
|
||||
if (data & 1 << b) // If the bit is 1
|
||||
io.digitalWrite(SX1509_SDO_PIN, HIGH); // Set SDO HIGH
|
||||
else // If the bit is 0
|
||||
io.digitalWrite(SX1509_SDO_PIN, LOW); // Set SDO LOW
|
||||
|
||||
// Now cycle the clock HIGH, then LOW:
|
||||
delay(1); // Small delay, S7S's max clock speed is 250kHz
|
||||
io.digitalWrite(SX1509_SCK_PIN, HIGH); // Write SCK HIGH
|
||||
delay(1); // Equivalent-ish small delay
|
||||
io.digitalWrite(SX1509_SCK_PIN, LOW); // Write SCK LOW
|
||||
}
|
||||
// Write SS HIGH to end the transfer
|
||||
io.digitalWrite(SX1509_SS_PIN, HIGH);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*************************************************************
|
||||
digitalRead.ino
|
||||
SparkFun SX1509 I/O Expander Example: digital in (digitalRead)
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates the SX1509's digitalRead
|
||||
functionality. A pin can either be set as an INPUT or
|
||||
INPUT_PULLUP. We'll attach an active-low button to an
|
||||
INPUT_PULLUP input, then whenever the button read's LOW, we'll
|
||||
read the state of another INPUT pin.
|
||||
|
||||
After uploading the sketch, open your serial monitor and set
|
||||
it to 115200 baud.
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
0 ---------------------------------]BTN[----GND
|
||||
8 -----------------------------Jumper (GND or 3.3V)
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 Pins:
|
||||
const byte SX1509_BUTTON_PIN = 0; // Active-low button
|
||||
const byte SX1509_INPUT_PIN = 8; // Floating or jumpered input
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Serial is used in this example to display the input value
|
||||
// of the SX1509_INPUT_PIN input:
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// use io.pinMode(<pin>, <mode>) to set input pins as either
|
||||
// INPUT or INPUT_PULLUP. Set up a floating (or jumpered to
|
||||
// either GND or 3.3V) pin to an INPUT:
|
||||
io.pinMode(SX1509_INPUT_PIN, INPUT);
|
||||
// Use a pull-up resistor on the button's input pin. When
|
||||
// the button is pressed, the pin will be read as LOW:
|
||||
io.pinMode(SX1509_BUTTON_PIN, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// use io.digitalRead(<pin>) to check if an SX1509 input
|
||||
// pin is either HIGH or LOW.
|
||||
if (io.digitalRead(SX1509_BUTTON_PIN) == LOW)
|
||||
{
|
||||
// If the button is pressed (the pin reads LOW)
|
||||
// Print the status of the other pin:
|
||||
Serial.print("SX1509_INPUT_PIN status: ");
|
||||
// Read the pin to print either 0 or 1
|
||||
Serial.println(io.digitalRead(SX1509_INPUT_PIN));
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*************************************************************
|
||||
digitalReadInterrupt.ino
|
||||
SparkFun SX1509 I/O Expander Example: digital in w/ interrupt
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example combines the SX1509's digitalRead and interrupt
|
||||
output functionalities. When a button connected to pin 0 is
|
||||
pressed, the SX1509 will generate an active-low interrupt,
|
||||
signalling to the Arduino that a button has been pressed.
|
||||
|
||||
After uploading the sketch, open your serial monitor and
|
||||
set it to 115200 baud.
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
INT --------------- 2
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
0 ---------------------------------BTN----GND
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 Pins:
|
||||
const byte SX1509_BUTTON_PIN = 0; // IO 0 connected to button
|
||||
|
||||
// Arduino Pins (not SX1509!)
|
||||
const byte ARDUINO_INT_PIN = 2; // SX1509 int output to D2
|
||||
|
||||
// Global variables:
|
||||
bool buttonPressed = false; // Track button press in ISR
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Serial is used in this example to display the input
|
||||
// value of the SX1509_INPUT_PIN input:
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If
|
||||
// it successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Use io.pinMode(<pin>, <mode>) to set our button to an
|
||||
// input with internal pullup resistor activated:
|
||||
io.pinMode(SX1509_BUTTON_PIN, INPUT_PULLUP);
|
||||
|
||||
// Use io.enableInterrupt(<pin>, <signal>) to enable an
|
||||
// interrupt on a pin. The <signal> variable can be either
|
||||
// FALLING, RISING, or CHANGE. Set it to falling, which will
|
||||
// mean the button was pressed:
|
||||
io.enableInterrupt(SX1509_BUTTON_PIN, FALLING);
|
||||
|
||||
// The SX1509 has built-in debounce features, so a single
|
||||
// button-press doesn't accidentally create multiple ints.
|
||||
// Use io.debounceTime(<time_ms>) to set the GLOBAL SX1509
|
||||
// debounce time.
|
||||
// <time_ms> can be either 0, 1, 2, 4, 8, 16, 32, or 64 ms.
|
||||
io.debounceTime(32); // Set debounce time to 32 ms.
|
||||
|
||||
// After configuring the debounce time, use
|
||||
// debouncePin(<pin>) to enable debounce on an input pin.
|
||||
io.debouncePin(SX1509_BUTTON_PIN); // Enable debounce
|
||||
|
||||
// Don't forget to configure your Arduino pins! Set the
|
||||
// Arduino's interrupt input to INPUT_PULLUP. The SX1509's
|
||||
// interrupt output is active-low.
|
||||
pinMode(ARDUINO_INT_PIN, INPUT_PULLUP);
|
||||
|
||||
// Attach an Arduino interrupt to the interrupt pin. Call
|
||||
// the button function, whenever the pin goes from HIGH to
|
||||
// LOW.
|
||||
attachInterrupt(digitalPinToInterrupt(ARDUINO_INT_PIN),
|
||||
button, FALLING);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (buttonPressed) // If the button() ISR was executed
|
||||
{
|
||||
// read io.interruptSource() find out which pin generated
|
||||
// an interrupt and clear the SX1509's interrupt output.
|
||||
unsigned int intStatus = io.interruptSource();
|
||||
// For debugging handiness, print the intStatus variable.
|
||||
// Each bit in intStatus represents a single SX1509 IO.
|
||||
Serial.println("intStatus = " + String(intStatus, BIN));
|
||||
|
||||
// If the bit corresponding to our button IO generated
|
||||
// the input:
|
||||
if (intStatus & (1 << SX1509_BUTTON_PIN))
|
||||
{
|
||||
Serial.println("Button pressed!"); // Print a message.
|
||||
}
|
||||
|
||||
buttonPressed = false; // Clear the buttonPressed flag
|
||||
}
|
||||
}
|
||||
|
||||
// button() is an Arduino interrupt routine, called whenever
|
||||
// the interrupt pin goes from HIGH to LOW.
|
||||
void button()
|
||||
{
|
||||
buttonPressed = true; // Set the buttonPressed flag to true
|
||||
// We can't do I2C communication in an Arduino ISR. The best
|
||||
// we can do is set a flag, to tell the loop() to check next
|
||||
// time through.
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*************************************************************
|
||||
digitalWrite.ino
|
||||
SparkFun SX1509 I/O Expander Example: digital out (digitalWrite)
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This simple example demonstrates the SX1509's digital output
|
||||
functionality. Attach an LED to SX1509 IO 15, or just look at
|
||||
it with a multimeter. We're gonna blink it!
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Breadboard
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
15 -------------------------------- LED+
|
||||
LED- -/\/\/\- GND
|
||||
330
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
// SX1509 pin definitions:
|
||||
const byte SX1509_LED_PIN = 15; // LED connected to pin 15
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Call io.pinMode(<pin>, <mode>) to set an SX1509 pin as
|
||||
// an output:
|
||||
io.pinMode(SX1509_LED_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// It's blinken time!
|
||||
// Call io.digitalWrite(<pin>, <HIGH | LOW>) to set a SX1509
|
||||
// output pin as either 3.3V or 0V.
|
||||
io.digitalWrite(SX1509_LED_PIN, HIGH);
|
||||
delay(500); // Delay half-a-second
|
||||
io.digitalWrite(SX1509_LED_PIN, LOW); // Set the I/O low
|
||||
delay(500); // Delay half-a-second
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*************************************************************
|
||||
keypad.ino
|
||||
SparkFun SX1509 I/O Expander Example: keypad matrix
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates how to use the SX1509's keypad engine to monitor a
|
||||
matrix of button inputs.
|
||||
|
||||
For this example, we'll wire the SX1509 up to a 12-pad keypad
|
||||
(https://www.sparkfun.com/products/8653).
|
||||
|
||||
After uploading the sketch, open your serial monitor and set it to 115200 baud.
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Keypad Pin
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
0 ---------------------------------- 2 (row 1)
|
||||
1 ---------------------------------- 7 (row 2)
|
||||
2 ---------------------------------- 6 (row 3)
|
||||
3 ---------------------------------- 4 (row 4)
|
||||
8 ---------------------------------- 3 (col 1)
|
||||
9 ---------------------------------- 1 (col 2)
|
||||
10 --------------------------------- 5 (col 3)
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
#define KEY_ROWS 4 // Number of rows in the keypad matrix
|
||||
#define KEY_COLS 3 // Number of columns in the keypad matrix
|
||||
|
||||
// keyMap maps row/column combinations to characters:
|
||||
char keyMap[KEY_ROWS][KEY_COLS] = {
|
||||
{'1', '2', '3'},
|
||||
{'4', '5', '6'},
|
||||
{'7', '8', '9'},
|
||||
{'*', '0', '#'}};
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// To initialize the keypad, call io.keypad(<rows>, <cols>)
|
||||
// You can also define the duration of inactivity before the
|
||||
// keypad engine sleeps, time spent scanning each row, and
|
||||
// the debounce time per button.
|
||||
|
||||
// After a set number of milliseconds, the keypad engine
|
||||
// will go into a low-current sleep mode.
|
||||
// Sleep time range: 128 ms - 8192 ms (powers of 2) 0=OFF
|
||||
unsigned int sleepTime = 256;
|
||||
// Scan time defines the number of milliseconds devoted to
|
||||
// each row in the matrix.
|
||||
// Scan time range: 1-128 ms, powers of 2
|
||||
byte scanTime = 2; // Scan time per row, in ms
|
||||
// Debounce sets the minimum amount of time that must pass
|
||||
// before a button can be pressed again.
|
||||
// Debounce time range: 0.5 - 64 ms (powers of 2)
|
||||
byte debounceTime = 1; // Debounce time
|
||||
// Note: Scan time must be greater than debounce time!
|
||||
// Take all of those values to set up the keypad engine:
|
||||
io.keypad(KEY_ROWS, KEY_COLS, sleepTime, scanTime, debounceTime);
|
||||
|
||||
// Note: we don't get to pick which pins the SX1509 connects
|
||||
// to each row/column. They go up sequetially on pins 0-7
|
||||
// (rows), and 8-15 (cols).
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Use io.readKeypad() to check if any keys have been pressed:
|
||||
unsigned int keyData = io.readKeypad();
|
||||
// If keyData is 0, then nothing has been pressed. Otherwise
|
||||
// at least two bits in the 16-bit value will be set, each
|
||||
// corresponding to either a row or a column.
|
||||
if (keyData != 0) // If a key was pressed:
|
||||
{
|
||||
// Use io.getRow(<readKeypad>) and io.getCol(<readKeypad>)
|
||||
// to find the active row and columns:
|
||||
byte row = io.getRow(keyData);
|
||||
byte col = io.getCol(keyData);
|
||||
|
||||
// Once you've found out the active row/col, put them in
|
||||
// keyMap to get the character pressed.
|
||||
char key = keyMap[row][col];
|
||||
Serial.println("Row: " + String(row));
|
||||
Serial.println("Col: " + String(col));
|
||||
Serial.print("Key: ");
|
||||
Serial.println(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*************************************************************
|
||||
keypadInterrupt.ino
|
||||
SparkFun SX1509 I/O Expander Example: keypad matrix with int
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
This example demonstrates how to use the SX1509's keypad
|
||||
engine to monitor a matrix of button inputs. The SX1509's
|
||||
interrupt output is monitored to check for button presses.
|
||||
|
||||
For this example, we use the 12-button keypad
|
||||
(https://www.sparkfun.com/products/8653).
|
||||
|
||||
After uploading the sketch, open your serial monitor and
|
||||
set it to 115200 baud.
|
||||
|
||||
Hardware Hookup:
|
||||
SX1509 Breakout ------ Arduino -------- Keypad Pin
|
||||
INT --------------- D2
|
||||
GND -------------- GND
|
||||
3V3 -------------- 3.3V
|
||||
SDA ------------ SDA (A4)
|
||||
SCL ------------ SCL (A5)
|
||||
0 ---------------------------------- 2 (row 1)
|
||||
1 ---------------------------------- 7 (row 2)
|
||||
2 ---------------------------------- 6 (row 3)
|
||||
3 ---------------------------------- 4 (row 4)
|
||||
8 ---------------------------------- 3 (col 1)
|
||||
9 ---------------------------------- 1 (col 2)
|
||||
10 --------------------------------- 5 (col 3)
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun
|
||||
employee) at the local, and you've found our code helpful,
|
||||
please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
*************************************************************/
|
||||
|
||||
#include <Wire.h> // Include the I2C library (required)
|
||||
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509
|
||||
|
||||
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
|
||||
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
|
||||
SX1509 io; // Create an SX1509 object to be used throughout
|
||||
|
||||
#define KEY_ROWS 4 // Number of rows in the keypad matrix
|
||||
#define KEY_COLS 3 // Number of columns in the keypad matrix
|
||||
|
||||
// keyMap maps row/column combinations to characters:
|
||||
char keyMap[KEY_ROWS][KEY_COLS] = {
|
||||
{'1', '2', '3'},
|
||||
{'4', '5', '6'},
|
||||
{'7', '8', '9'},
|
||||
{'*', '0', '#'}};
|
||||
|
||||
const byte ARDUINO_INTERRUPT_PIN = 2;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SX1509 Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
// Call io.begin(<address>) to initialize the SX1509. If it
|
||||
// successfully communicates, it'll return 1.
|
||||
if (io.begin(SX1509_ADDRESS) == false)
|
||||
{
|
||||
Serial.println("Failed to communicate. Check wiring and address of SX1509.");
|
||||
while (1)
|
||||
; // If we fail to communicate, loop forever.
|
||||
}
|
||||
|
||||
// Scan time range: 1-128 ms, powers of 2
|
||||
byte scanTime = 8; // Scan time per row, in ms
|
||||
// Debounce time range: 0.5 - 64 ms (powers of 2)
|
||||
byte debounceTime = 1; // Debounce time
|
||||
// Sleep time range: 128 ms - 8192 ms (powers of 2) 0=OFF
|
||||
byte sleepTime = 0;
|
||||
// Scan time must be greater than debounce time!
|
||||
io.keypad(KEY_ROWS, KEY_COLS,
|
||||
sleepTime, scanTime, debounceTime);
|
||||
|
||||
// Set up the Arduino interrupt pin as an input w/
|
||||
// internal pull-up. (The SX1509 interrupt is active-low.)
|
||||
pinMode(ARDUINO_INTERRUPT_PIN, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// Compared to the keypad in keypad.ino, this keypad example
|
||||
// is a bit more advanced. We'll use these varaibles to check
|
||||
// if a key is being held down, or has been released. Then we
|
||||
// can kind of emulate the operation of a computer keyboard.
|
||||
unsigned int previousKeyData = 0; // Stores last key pressed
|
||||
unsigned int holdCount, releaseCount = 0; // Count durations
|
||||
const unsigned int holdCountMax = 15; // Key hold limit
|
||||
const unsigned int releaseCountMax = 100; // Release limit
|
||||
|
||||
void loop()
|
||||
{
|
||||
// If the SX1509 INT pin goes low, a keypad button has
|
||||
// been pressed:
|
||||
if (digitalRead(ARDUINO_INTERRUPT_PIN) == LOW)
|
||||
{
|
||||
// Use io.readKeypad() to get the raw keypad row/column
|
||||
unsigned int keyData = io.readKeypad();
|
||||
// Then use io.getRow() and io.getCol() to parse that
|
||||
// data into row and column values.
|
||||
byte row = io.getRow(keyData);
|
||||
byte col = io.getCol(keyData);
|
||||
// Then plug row and column into keyMap to get which
|
||||
// key was pressed.
|
||||
char key = keyMap[row][col];
|
||||
|
||||
// If it's a new key pressed
|
||||
if (keyData != previousKeyData)
|
||||
{
|
||||
holdCount = 0; // Reset hold-down count
|
||||
Serial.println(String(key)); // Print the key
|
||||
}
|
||||
else // If the button's beging held down:
|
||||
{
|
||||
holdCount++; // Increment holdCount
|
||||
if (holdCount > holdCountMax) // If it exceeds threshold
|
||||
Serial.println(key); // Print the key
|
||||
}
|
||||
releaseCount = 0; // Clear the releaseCount variable
|
||||
previousKeyData = keyData; // Update previousKeyData
|
||||
}
|
||||
|
||||
// If no keys have been pressed we'll continuously increment
|
||||
// releaseCount. Eventually creating a release, once the
|
||||
// count hits the max.
|
||||
releaseCount++;
|
||||
if (releaseCount >= releaseCountMax)
|
||||
{
|
||||
releaseCount = 0;
|
||||
previousKeyData = 0;
|
||||
}
|
||||
delay(1); // Gives releaseCountMax a more intuitive unit
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For SX1509
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
SX1509 KEYWORD1
|
||||
sx1509Class KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
init KEYWORD2
|
||||
begin KEYWORD2
|
||||
reset KEYWORD2
|
||||
pinDir KEYWORD2
|
||||
writePin KEYWORD2
|
||||
readPin KEYWORD2
|
||||
ledDriverInit KEYWORD2
|
||||
pwm KEYWORD2
|
||||
sync KEYWORD2
|
||||
blink KEYWORD2
|
||||
breathe KEYWORD2
|
||||
setupBlink KEYWORD2
|
||||
enableInterrupt KEYWORD2
|
||||
interruptSource KEYWORD2
|
||||
configClock KEYWORD2
|
||||
configureClock KEYWORD2
|
||||
debounceEnable KEYWORD2
|
||||
debounceConfig KEYWORD2
|
||||
debounceTime KEYWORD2
|
||||
debouncePin KEYWORD2
|
||||
debounceKeypad KEYWORD2
|
||||
keypad KEYWORD2
|
||||
readKeypad KEYWORD2
|
||||
getRow KEYWORD2
|
||||
getCol KEYWORD2
|
||||
checkInterrupt KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
SparkFunSX1509 LITERAL1
|
||||
LINEAR LITERAL1
|
||||
LOGARITHMIC LITERAL1
|
||||
INTERNAL_CLOCK_2MHZ LITERAL1
|
||||
SOFTWARE_RESET LITERAL1
|
||||
HARDWARE_RESET LITERAL1
|
||||
|
||||
#######################################
|
||||
# Blue Constants (LITERAL2, Constants, RESERVED_WORD_2)
|
||||
#######################################
|
||||
ANALOG_OUTPUT LITERAL2 Constants RESERVED_WORD_2
|
||||
@@ -0,0 +1,9 @@
|
||||
name=SX1509 IO Expander
|
||||
version=3.0.6
|
||||
author=SparkFun Electronics
|
||||
maintainer=SparkFun Electronics
|
||||
sentence=Arduino library and hardware files for the SparkFun SX1509 IO Expander Breakout board.
|
||||
paragraph=The SX1509 Breakout is a 16-channel GPIO expander with an I2C interface – that means with just two wires, your microcontroller can interface with 16 fully configurable digital input/output pins. The SX1509 can also produce PWM signals, dim LEDs. It can be set to blink or even breathe pins at varying rates. And, with a built-in keypad engine, it can interface with up to 64 buttons set up in an 8x8 matrix.
|
||||
category=Signal Input/Output
|
||||
url=https://github.com/sparkfun/SX1509_IO-Expander
|
||||
architectures=*
|
||||
@@ -0,0 +1,860 @@
|
||||
/******************************************************************************
|
||||
SparkFunSX1509.cpp
|
||||
SparkFun SX1509 I/O Expander Library Source File
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
Here you'll find the Arduino code used to interface with the SX1509 I2C
|
||||
16 I/O expander. There are functions to take advantage of everything the
|
||||
SX1509 provides - input/output setting, writing pins high/low, reading
|
||||
the input value of pins, LED driver utilities (blink, breath, pwm), and
|
||||
keypad engine utilites.
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun employee) at the
|
||||
local, and you've found our code helpful, please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
******************************************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
#include "Arduino.h"
|
||||
#include "SparkFunSX1509.h"
|
||||
#include "util/sx1509_registers.h"
|
||||
|
||||
SX1509::SX1509()
|
||||
{
|
||||
_clkX = 0;
|
||||
}
|
||||
|
||||
SX1509::SX1509(uint8_t address, uint8_t resetPin, uint8_t interruptPin, uint8_t oscillatorPin)
|
||||
{
|
||||
// Store the received parameters into member variables
|
||||
deviceAddress = address;
|
||||
pinInterrupt = interruptPin;
|
||||
pinOscillator = oscillatorPin;
|
||||
pinReset = resetPin;
|
||||
}
|
||||
|
||||
uint8_t SX1509::begin(uint8_t address, TwoWire &wirePort, uint8_t resetPin)
|
||||
{
|
||||
// Store the received parameters into member variables
|
||||
_i2cPort = &wirePort;
|
||||
deviceAddress = address;
|
||||
pinReset = resetPin;
|
||||
|
||||
return init();
|
||||
}
|
||||
|
||||
uint8_t SX1509::init(void)
|
||||
{
|
||||
// Begin I2C should be done externally, before beginning SX1509
|
||||
//Wire.begin();
|
||||
|
||||
// If the reset pin is connected
|
||||
if (pinReset != 255)
|
||||
reset(1);
|
||||
else
|
||||
reset(0);
|
||||
|
||||
// Communication test. We'll read from two registers with different
|
||||
// default values to verify communication.
|
||||
uint16_t testRegisters = 0;
|
||||
testRegisters = readWord(REG_INTERRUPT_MASK_A); // This should return 0xFF00
|
||||
|
||||
// Then read a byte that should be 0x00
|
||||
if (testRegisters == 0xFF00)
|
||||
{
|
||||
// Set the clock to a default of 2MHz using internal
|
||||
clock(INTERNAL_CLOCK_2MHZ);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SX1509::reset(bool hardware)
|
||||
{
|
||||
// if hardware bool is set
|
||||
if (hardware)
|
||||
{
|
||||
// Check if bit 2 of REG_MISC is set
|
||||
// if so nReset will not issue a POR, we'll need to clear that bit first
|
||||
uint8_t regMisc = readByte(REG_MISC);
|
||||
if (regMisc & (1 << 2))
|
||||
{
|
||||
regMisc &= ~(1 << 2);
|
||||
writeByte(REG_MISC, regMisc);
|
||||
}
|
||||
// Reset the SX1509, the pin is active low
|
||||
::pinMode(pinReset, OUTPUT); // set reset pin as output
|
||||
::digitalWrite(pinReset, LOW); // pull reset pin low
|
||||
delay(1); // Wait for the pin to settle
|
||||
::digitalWrite(pinReset, HIGH); // pull reset pin back high
|
||||
}
|
||||
else
|
||||
{
|
||||
// Software reset command sequence:
|
||||
writeByte(REG_RESET, 0x12);
|
||||
writeByte(REG_RESET, 0x34);
|
||||
}
|
||||
}
|
||||
|
||||
void SX1509::pinDir(uint8_t pin, uint8_t inOut, uint8_t initialLevel)
|
||||
{
|
||||
// The SX1509 RegDir registers: REG_DIR_B, REG_DIR_A
|
||||
// 0: IO is configured as an output
|
||||
// 1: IO is configured as an input
|
||||
uint8_t modeBit;
|
||||
if ((inOut == OUTPUT) || (inOut == ANALOG_OUTPUT))
|
||||
{
|
||||
uint16_t tempRegData = readWord(REG_DATA_B);
|
||||
if (initialLevel == LOW)
|
||||
{
|
||||
tempRegData &= ~(1 << pin);
|
||||
writeWord(REG_DATA_B, tempRegData);
|
||||
}
|
||||
modeBit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
modeBit = 1;
|
||||
}
|
||||
|
||||
uint16_t tempRegDir = readWord(REG_DIR_B);
|
||||
if (modeBit)
|
||||
tempRegDir |= (1 << pin);
|
||||
else
|
||||
tempRegDir &= ~(1 << pin);
|
||||
|
||||
writeWord(REG_DIR_B, tempRegDir);
|
||||
|
||||
// If INPUT_PULLUP was called, set up the pullup too:
|
||||
if (inOut == INPUT_PULLUP)
|
||||
writePin(pin, HIGH);
|
||||
|
||||
if (inOut == ANALOG_OUTPUT)
|
||||
{
|
||||
ledDriverInit(pin);
|
||||
}
|
||||
}
|
||||
|
||||
void SX1509::pinMode(uint8_t pin, uint8_t inOut, uint8_t initialLevel)
|
||||
{
|
||||
pinDir(pin, inOut, initialLevel);
|
||||
}
|
||||
|
||||
bool SX1509::writePin(uint8_t pin, uint8_t highLow)
|
||||
{
|
||||
|
||||
uint16_t tempRegDir = readWord(REG_DIR_B);
|
||||
|
||||
if ((0xFFFF ^ tempRegDir) & (1 << pin)) // If the pin is an output, write high/low
|
||||
{
|
||||
uint16_t tempRegData = readWord(REG_DATA_B);
|
||||
if (highLow)
|
||||
tempRegData |= (1 << pin);
|
||||
else
|
||||
tempRegData &= ~(1 << pin);
|
||||
return writeWord(REG_DATA_B, tempRegData);
|
||||
}
|
||||
else // Otherwise the pin is an input, pull-up/down
|
||||
{
|
||||
uint16_t tempPullUp = readWord(REG_PULL_UP_B);
|
||||
uint16_t tempPullDown = readWord(REG_PULL_DOWN_B);
|
||||
|
||||
if (highLow) // if HIGH, do pull-up, disable pull-down
|
||||
{
|
||||
tempPullUp |= (1 << pin);
|
||||
tempPullDown &= ~(1 << pin);
|
||||
return writeWord(REG_PULL_UP_B, tempPullUp) && writeWord(REG_PULL_DOWN_B, tempPullDown);
|
||||
}
|
||||
else // If LOW do pull-down, disable pull-up
|
||||
{
|
||||
tempPullDown |= (1 << pin);
|
||||
tempPullUp &= ~(1 << pin);
|
||||
return writeWord(REG_PULL_UP_B, tempPullUp) && writeWord(REG_PULL_DOWN_B, tempPullDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SX1509::digitalWrite(uint8_t pin, uint8_t highLow)
|
||||
{
|
||||
return writePin(pin, highLow);
|
||||
}
|
||||
|
||||
uint8_t SX1509::readPin(uint8_t pin)
|
||||
{
|
||||
uint16_t tempRegDir = readWord(REG_DIR_B);
|
||||
|
||||
if (tempRegDir & (1 << pin)) // If the pin is an input
|
||||
{
|
||||
uint16_t tempRegData = readWord(REG_DATA_B);
|
||||
if (tempRegData & (1 << pin))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// log_d("Pin %d not INPUT, REG_DIR_B: %d", pin, tempRegDir);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SX1509::readPin(const uint8_t pin, bool *value)
|
||||
{
|
||||
uint16_t tempRegDir;
|
||||
if (readWord(REG_DIR_B, &tempRegDir))
|
||||
{
|
||||
if (tempRegDir & (1 << pin))
|
||||
{ // If the pin is an input
|
||||
uint16_t tempRegData;
|
||||
if (readWord(REG_DATA_B, &tempRegData))
|
||||
{
|
||||
*value = (tempRegData & (1 << pin)) != 0;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t SX1509::digitalRead(uint8_t pin)
|
||||
{
|
||||
return readPin(pin);
|
||||
}
|
||||
|
||||
bool SX1509::digitalRead(uint8_t pin, bool *value)
|
||||
{
|
||||
return readPin(pin, value);
|
||||
}
|
||||
|
||||
void SX1509::ledDriverInit(uint8_t pin, uint8_t freq /*= 1*/, bool log /*= false*/)
|
||||
{
|
||||
uint16_t tempWord;
|
||||
uint8_t tempByte;
|
||||
|
||||
// Disable input buffer
|
||||
// Writing a 1 to the pin bit will disable that pins input buffer
|
||||
tempWord = readWord(REG_INPUT_DISABLE_B);
|
||||
tempWord |= (1 << pin);
|
||||
writeWord(REG_INPUT_DISABLE_B, tempWord);
|
||||
|
||||
// Disable pull-up
|
||||
// Writing a 0 to the pin bit will disable that pull-up resistor
|
||||
tempWord = readWord(REG_PULL_UP_B);
|
||||
tempWord &= ~(1 << pin);
|
||||
writeWord(REG_PULL_UP_B, tempWord);
|
||||
|
||||
// Set direction to output (REG_DIR_B)
|
||||
tempWord = readWord(REG_DIR_B);
|
||||
tempWord &= ~(1 << pin); // 0=output
|
||||
writeWord(REG_DIR_B, tempWord);
|
||||
|
||||
// Enable oscillator (REG_CLOCK)
|
||||
tempByte = readByte(REG_CLOCK);
|
||||
tempByte |= (1 << 6); // Internal 2MHz oscillator part 1 (set bit 6)
|
||||
tempByte &= ~(1 << 5); // Internal 2MHz oscillator part 2 (clear bit 5)
|
||||
writeByte(REG_CLOCK, tempByte);
|
||||
|
||||
// Configure LED driver clock and mode (REG_MISC)
|
||||
tempByte = readByte(REG_MISC);
|
||||
if (log)
|
||||
{
|
||||
tempByte |= (1 << 7); // set logarithmic mode bank B
|
||||
tempByte |= (1 << 3); // set logarithmic mode bank A
|
||||
}
|
||||
else
|
||||
{
|
||||
tempByte &= ~(1 << 7); // set linear mode bank B
|
||||
tempByte &= ~(1 << 3); // set linear mode bank A
|
||||
}
|
||||
|
||||
// Use configClock to setup the clock divder
|
||||
if (_clkX == 0) // Make clckX non-zero
|
||||
{
|
||||
// _clkX = 2000000.0 / (1 << (1 - 1)); // Update private clock variable
|
||||
_clkX = 2000000.0;
|
||||
|
||||
// uint8_t freq = (1 & 0x07) << 4; // freq should only be 3 bits from 6:4
|
||||
// tempByte |= freq;
|
||||
}
|
||||
|
||||
freq = (freq & 0x7) << 4; // mask only 3 bits and shift to bit position 6:4
|
||||
tempByte |= freq;
|
||||
|
||||
writeByte(REG_MISC, tempByte);
|
||||
|
||||
// Enable LED driver operation (REG_LED_DRIVER_ENABLE)
|
||||
tempWord = readWord(REG_LED_DRIVER_ENABLE_B);
|
||||
tempWord |= (1 << pin);
|
||||
writeWord(REG_LED_DRIVER_ENABLE_B, tempWord);
|
||||
|
||||
// Set REG_DATA bit low ~ LED driver started
|
||||
tempWord = readWord(REG_DATA_B);
|
||||
tempWord &= ~(1 << pin);
|
||||
writeWord(REG_DATA_B, tempWord);
|
||||
}
|
||||
|
||||
void SX1509::pwm(uint8_t pin, uint8_t iOn)
|
||||
{
|
||||
// Write the on intensity of pin
|
||||
// Linear mode: Ion = iOn
|
||||
// Log mode: Ion = f(iOn)
|
||||
writeByte(REG_I_ON[pin], iOn);
|
||||
}
|
||||
|
||||
void SX1509::analogWrite(uint8_t pin, uint8_t iOn)
|
||||
{
|
||||
pwm(pin, iOn);
|
||||
}
|
||||
|
||||
void SX1509::blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity, uint8_t offIntensity)
|
||||
{
|
||||
uint8_t onReg = calculateLEDTRegister(tOn);
|
||||
uint8_t offReg = calculateLEDTRegister(tOff);
|
||||
|
||||
setupBlink(pin, onReg, offReg, onIntensity, offIntensity, 0, 0);
|
||||
}
|
||||
|
||||
void SX1509::breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, uint8_t onInt, uint8_t offInt, bool log)
|
||||
{
|
||||
offInt = constrain(offInt, 0, 7);
|
||||
|
||||
uint8_t onReg = calculateLEDTRegister(tOn);
|
||||
uint8_t offReg = calculateLEDTRegister(tOff);
|
||||
|
||||
uint8_t riseTime = calculateSlopeRegister(rise, onInt, offInt);
|
||||
uint8_t fallTime = calculateSlopeRegister(fall, onInt, offInt);
|
||||
|
||||
setupBlink(pin, onReg, offReg, onInt, offInt, riseTime, fallTime, log);
|
||||
}
|
||||
|
||||
void SX1509::setupBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t onIntensity, uint8_t offIntensity, uint8_t tRise, uint8_t tFall, bool log)
|
||||
{
|
||||
ledDriverInit(pin, log);
|
||||
|
||||
// Keep parameters within their limits:
|
||||
tOn &= 0x1F; // tOn should be a 5-bit value
|
||||
tOff &= 0x1F; // tOff should be a 5-bit value
|
||||
offIntensity &= 0x07;
|
||||
// Write the time on
|
||||
// 1-15: TON = 64 * tOn * (255/ClkX)
|
||||
// 16-31: TON = 512 * tOn * (255/ClkX)
|
||||
writeByte(REG_T_ON[pin], tOn);
|
||||
|
||||
// Write the time/intensity off register
|
||||
// 1-15: TOFF = 64 * tOff * (255/ClkX)
|
||||
// 16-31: TOFF = 512 * tOff * (255/ClkX)
|
||||
// linear Mode - IOff = 4 * offIntensity
|
||||
// log mode - Ioff = f(4 * offIntensity)
|
||||
writeByte(REG_OFF[pin], (tOff << 3) | offIntensity);
|
||||
|
||||
// Write the on intensity:
|
||||
writeByte(REG_I_ON[pin], onIntensity);
|
||||
|
||||
// Prepare tRise and tFall
|
||||
tRise &= 0x1F; // tRise is a 5-bit value
|
||||
tFall &= 0x1F; // tFall is a 5-bit value
|
||||
|
||||
// Write regTRise
|
||||
// 0: Off
|
||||
// 1-15: TRise = (regIOn - (4 * offIntensity)) * tRise * (255/ClkX)
|
||||
// 16-31: TRise = 16 * (regIOn - (4 * offIntensity)) * tRise * (255/ClkX)
|
||||
if (REG_T_RISE[pin] != 0xFF)
|
||||
writeByte(REG_T_RISE[pin], tRise);
|
||||
// Write regTFall
|
||||
// 0: off
|
||||
// 1-15: TFall = (regIOn - (4 * offIntensity)) * tFall * (255/ClkX)
|
||||
// 16-31: TFall = 16 * (regIOn - (4 * offIntensity)) * tFall * (255/ClkX)
|
||||
if (REG_T_FALL[pin] != 0xFF)
|
||||
writeByte(REG_T_FALL[pin], tFall);
|
||||
}
|
||||
|
||||
void SX1509::keypad(uint8_t rows, uint8_t columns, uint16_t sleepTime, uint8_t scanTime, uint8_t debounceTime)
|
||||
{
|
||||
uint16_t tempWord;
|
||||
uint8_t tempByte;
|
||||
|
||||
// If clock hasn't been set up, set it to internal 2MHz
|
||||
if (_clkX == 0)
|
||||
clock(INTERNAL_CLOCK_2MHZ);
|
||||
|
||||
// Set regDir 0:7 outputs, 8:15 inputs:
|
||||
tempWord = readWord(REG_DIR_B);
|
||||
for (uint8_t i = 0; i < rows; i++)
|
||||
tempWord &= ~(1 << i);
|
||||
for (uint8_t i = 8; i < (columns * 2); i++)
|
||||
tempWord |= (1 << i);
|
||||
writeWord(REG_DIR_B, tempWord);
|
||||
|
||||
// Set regOpenDrain on 0:7:
|
||||
tempByte = readByte(REG_OPEN_DRAIN_A);
|
||||
for (uint8_t i = 0; i < rows; i++)
|
||||
tempByte |= (1 << i);
|
||||
writeByte(REG_OPEN_DRAIN_A, tempByte);
|
||||
|
||||
// Set regPullUp on 8:15:
|
||||
tempByte = readByte(REG_PULL_UP_B);
|
||||
for (uint8_t i = 0; i < columns; i++)
|
||||
tempByte |= (1 << i);
|
||||
writeByte(REG_PULL_UP_B, tempByte);
|
||||
|
||||
// Debounce Time must be less than scan time
|
||||
debounceTime = constrain(debounceTime, 1, 64);
|
||||
scanTime = constrain(scanTime, 1, 128);
|
||||
if (debounceTime >= scanTime)
|
||||
{
|
||||
debounceTime = scanTime >> 1; // Force debounceTime to be less than scanTime
|
||||
}
|
||||
debounceKeypad(debounceTime, rows, columns);
|
||||
|
||||
// Calculate scanTimeBits, based on scanTime
|
||||
uint8_t scanTimeBits = 0;
|
||||
for (uint8_t i = 7; i > 0; i--)
|
||||
{
|
||||
if (scanTime & (1 << i))
|
||||
{
|
||||
scanTimeBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate sleepTimeBits, based on sleepTime
|
||||
uint8_t sleepTimeBits = 0;
|
||||
if (sleepTime != 0)
|
||||
{
|
||||
for (uint8_t i = 7; i > 0; i--)
|
||||
{
|
||||
if (sleepTime & ((uint16_t)1 << (i + 6)))
|
||||
{
|
||||
sleepTimeBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If sleepTime was non-zero, but less than 128,
|
||||
// assume we wanted to turn sleep on, set it to minimum:
|
||||
if (sleepTimeBits == 0)
|
||||
sleepTimeBits = 1;
|
||||
}
|
||||
|
||||
// RegKeyConfig1 sets the auto sleep time and scan time per row
|
||||
sleepTimeBits = (sleepTimeBits & 0b111) << 4;
|
||||
scanTimeBits &= 0b111; // Scan time is bits 2:0
|
||||
tempByte = sleepTime | scanTimeBits;
|
||||
writeByte(REG_KEY_CONFIG_1, tempByte);
|
||||
|
||||
// RegKeyConfig2 tells the SX1509 how many rows and columns we've got going
|
||||
rows = (rows - 1) & 0b111; // 0 = off, 0b001 = 2 rows, 0b111 = 8 rows, etc.
|
||||
columns = (columns - 1) & 0b111; // 0b000 = 1 column, ob111 = 8 columns, etc.
|
||||
writeByte(REG_KEY_CONFIG_2, (rows << 3) | columns);
|
||||
}
|
||||
|
||||
uint16_t SX1509::readKeypad()
|
||||
{
|
||||
return readKeyData();
|
||||
}
|
||||
|
||||
uint16_t SX1509::readKeyData()
|
||||
{
|
||||
return (0xFFFF ^ readWord(REG_KEY_DATA_1));
|
||||
}
|
||||
|
||||
uint8_t SX1509::getRow(uint16_t keyData)
|
||||
{
|
||||
uint8_t rowData = uint8_t(keyData & 0x00FF);
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (rowData & (1 << i))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SX1509::getCol(uint16_t keyData)
|
||||
{
|
||||
uint8_t colData = uint8_t((keyData & 0xFF00) >> 8);
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (colData & (1 << i))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SX1509::sync(void)
|
||||
{
|
||||
// First check if nReset functionality is set
|
||||
uint8_t regMisc = readByte(REG_MISC);
|
||||
if (!(regMisc & 0x04))
|
||||
{
|
||||
regMisc |= (1 << 2);
|
||||
writeByte(REG_MISC, regMisc);
|
||||
}
|
||||
|
||||
// Toggle nReset pin to sync LED timers
|
||||
::pinMode(pinReset, OUTPUT); // set reset pin as output
|
||||
::digitalWrite(pinReset, LOW); // pull reset pin low
|
||||
delay(1); // Wait for the pin to settle
|
||||
::digitalWrite(pinReset, HIGH); // pull reset pin back high
|
||||
|
||||
// Return nReset to POR functionality
|
||||
writeByte(REG_MISC, (regMisc & ~(1 << 2)));
|
||||
}
|
||||
|
||||
void SX1509::debounceConfig(uint8_t configValue)
|
||||
{
|
||||
// First make sure clock is configured
|
||||
uint8_t tempByte = readByte(REG_MISC);
|
||||
if ((tempByte & 0x70) == 0)
|
||||
{
|
||||
tempByte |= (1 << 4); // Just default to no divider if not set
|
||||
writeByte(REG_MISC, tempByte);
|
||||
}
|
||||
tempByte = readByte(REG_CLOCK);
|
||||
if ((tempByte & 0x60) == 0)
|
||||
{
|
||||
tempByte |= (1 << 6); // default to internal osc.
|
||||
writeByte(REG_CLOCK, tempByte);
|
||||
}
|
||||
|
||||
configValue &= 0b111; // 3-bit value
|
||||
writeByte(REG_DEBOUNCE_CONFIG, configValue);
|
||||
}
|
||||
|
||||
void SX1509::debounceTime(uint8_t time)
|
||||
{
|
||||
if (_clkX == 0) // If clock hasn't been set up.
|
||||
clock(INTERNAL_CLOCK_2MHZ, 1); // Set clock to 2MHz.
|
||||
|
||||
// Debounce time-to-byte map: (assuming fOsc = 2MHz)
|
||||
// 0: 0.5ms 1: 1ms
|
||||
// 2: 2ms 3: 4ms
|
||||
// 4: 8ms 5: 16ms
|
||||
// 6: 32ms 7: 64ms
|
||||
// 2^(n-1)
|
||||
uint8_t configValue = 0;
|
||||
// We'll check for the highest set bit position,
|
||||
// and use that for debounceConfig
|
||||
for (int8_t i = 7; i >= 0; i--)
|
||||
{
|
||||
if (time & (1 << i))
|
||||
{
|
||||
configValue = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
configValue = constrain(configValue, 0, 7);
|
||||
|
||||
debounceConfig(configValue);
|
||||
}
|
||||
|
||||
void SX1509::debounceEnable(uint8_t pin)
|
||||
{
|
||||
uint16_t debounceEnable = readWord(REG_DEBOUNCE_ENABLE_B);
|
||||
debounceEnable |= (1 << pin);
|
||||
writeWord(REG_DEBOUNCE_ENABLE_B, debounceEnable);
|
||||
}
|
||||
|
||||
void SX1509::debouncePin(uint8_t pin)
|
||||
{
|
||||
debounceEnable(pin);
|
||||
}
|
||||
|
||||
void SX1509::debounceKeypad(uint8_t time, uint8_t numRows, uint8_t numCols)
|
||||
{
|
||||
// Set up debounce time:
|
||||
debounceTime(time);
|
||||
|
||||
// Set up debounce pins:
|
||||
for (uint8_t i = 0; i < numRows; i++)
|
||||
debouncePin(i);
|
||||
for (uint8_t i = 0; i < (8 + numCols); i++)
|
||||
debouncePin(i);
|
||||
}
|
||||
|
||||
void SX1509::enableInterrupt(uint8_t pin, uint8_t riseFall)
|
||||
{
|
||||
// Set REG_INTERRUPT_MASK
|
||||
uint16_t tempWord = readWord(REG_INTERRUPT_MASK_B);
|
||||
tempWord &= ~(1 << pin); // 0 = event on IO will trigger interrupt
|
||||
writeWord(REG_INTERRUPT_MASK_B, tempWord);
|
||||
|
||||
uint8_t sensitivity = 0;
|
||||
switch (riseFall)
|
||||
{
|
||||
case CHANGE:
|
||||
sensitivity = 0b11;
|
||||
break;
|
||||
case FALLING:
|
||||
sensitivity = 0b10;
|
||||
break;
|
||||
case RISING:
|
||||
sensitivity = 0b01;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set REG_SENSE_XXX
|
||||
// Sensitivity is set as follows:
|
||||
// 00: None
|
||||
// 01: Rising
|
||||
// 10: Falling
|
||||
// 11: Both
|
||||
uint8_t pinMask = (pin & 0x07) * 2;
|
||||
uint8_t senseRegister;
|
||||
|
||||
// Need to select between two words. One for bank A, one for B.
|
||||
if (pin >= 8)
|
||||
senseRegister = REG_SENSE_HIGH_B;
|
||||
else
|
||||
senseRegister = REG_SENSE_HIGH_A;
|
||||
|
||||
tempWord = readWord(senseRegister);
|
||||
tempWord &= ~(0b11 << pinMask); // Mask out the bits we want to write
|
||||
tempWord |= (sensitivity << pinMask); // Add our new bits
|
||||
writeWord(senseRegister, tempWord);
|
||||
}
|
||||
|
||||
uint16_t SX1509::interruptSource(bool clear /* =true*/)
|
||||
{
|
||||
uint16_t intSource = readWord(REG_INTERRUPT_SOURCE_B);
|
||||
if (clear)
|
||||
writeWord(REG_INTERRUPT_SOURCE_B, 0xFFFF); // Clear interrupts
|
||||
return intSource;
|
||||
}
|
||||
|
||||
bool SX1509::checkInterrupt(uint8_t pin)
|
||||
{
|
||||
if (interruptSource(false) & (1 << pin))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SX1509::clock(uint8_t oscSource, uint8_t oscDivider, uint8_t oscPinFunction, uint8_t oscFreqOut)
|
||||
{
|
||||
configClock(oscSource, oscPinFunction, oscFreqOut, oscDivider);
|
||||
}
|
||||
|
||||
void SX1509::configClock(uint8_t oscSource /*= 2*/, uint8_t oscPinFunction /*= 0*/, uint8_t oscFreqOut /*= 0*/, uint8_t oscDivider /*= 1*/)
|
||||
{
|
||||
// RegClock constructed as follows:
|
||||
// 6:5 - Oscillator frequency souce
|
||||
// 00: off, 01: external input, 10: internal 2MHz, 1: reserved
|
||||
// 4 - OSCIO pin function
|
||||
// 0: input, 1 ouptut
|
||||
// 3:0 - Frequency of oscout pin
|
||||
// 0: LOW, 0xF: high, else fOSCOUT = FoSC/(2^(RegClock[3:0]-1))
|
||||
oscSource = (oscSource & 0b11) << 5; // 2-bit value, bits 6:5
|
||||
oscPinFunction = (oscPinFunction & 1) << 4; // 1-bit value bit 4
|
||||
oscFreqOut = (oscFreqOut & 0b1111); // 4-bit value, bits 3:0
|
||||
uint8_t regClock = oscSource | oscPinFunction | oscFreqOut;
|
||||
writeByte(REG_CLOCK, regClock);
|
||||
|
||||
// Config RegMisc[6:4] with oscDivider
|
||||
// 0: off, else ClkX = fOSC / (2^(RegMisc[6:4] -1))
|
||||
oscDivider = constrain(oscDivider, 1, 7);
|
||||
_clkX = 2000000.0 / (1 << (oscDivider - 1)); // Update private clock variable
|
||||
oscDivider = (oscDivider & 0b111) << 4; // 3-bit value, bits 6:4
|
||||
|
||||
uint8_t regMisc = readByte(REG_MISC);
|
||||
regMisc &= ~(0b111 << 4);
|
||||
regMisc |= oscDivider;
|
||||
writeByte(REG_MISC, regMisc);
|
||||
}
|
||||
|
||||
uint8_t SX1509::calculateLEDTRegister(unsigned long ms)
|
||||
{
|
||||
uint8_t regOn1, regOn2;
|
||||
float timeOn1, timeOn2;
|
||||
|
||||
if (_clkX == 0)
|
||||
return 0;
|
||||
|
||||
regOn1 = (float)(ms / 1000.0) / (64.0 * 255.0 / (float)_clkX);
|
||||
regOn2 = regOn1 / 8;
|
||||
regOn1 = constrain(regOn1, 1, 15);
|
||||
regOn2 = constrain(regOn2, 16, 31);
|
||||
|
||||
timeOn1 = 64.0 * regOn1 * 255.0 / _clkX * 1000.0;
|
||||
timeOn2 = 512.0 * regOn2 * 255.0 / _clkX * 1000.0;
|
||||
|
||||
if (abs(timeOn1 - ms) < abs(timeOn2 - ms))
|
||||
return regOn1;
|
||||
else
|
||||
return regOn2;
|
||||
}
|
||||
|
||||
uint8_t SX1509::calculateSlopeRegister(unsigned long ms, uint8_t onIntensity, uint8_t offIntensity)
|
||||
{
|
||||
uint16_t regSlope1, regSlope2;
|
||||
float regTime1, regTime2;
|
||||
|
||||
if (_clkX == 0)
|
||||
return 0;
|
||||
|
||||
float tFactor = ((float)onIntensity - (4.0 * (float)offIntensity)) * 255.0 / (float)_clkX;
|
||||
float timeS = float(ms) / 1000.0;
|
||||
|
||||
regSlope1 = timeS / tFactor;
|
||||
regSlope2 = regSlope1 / 16;
|
||||
|
||||
regSlope1 = constrain(regSlope1, 1, 15);
|
||||
regSlope2 = constrain(regSlope2, 16, 31);
|
||||
|
||||
regTime1 = regSlope1 * tFactor * 1000.0;
|
||||
regTime2 = 16 * regTime1;
|
||||
|
||||
if (abs(regTime1 - ms) < abs(regTime2 - ms))
|
||||
return regSlope1;
|
||||
else
|
||||
return regSlope2;
|
||||
}
|
||||
|
||||
// readByte(uint8_t registerAddress)
|
||||
// This function reads a single byte located at the registerAddress register.
|
||||
// - deviceAddress should already be set by the constructor.
|
||||
// - Return value is the byte read from registerAddress
|
||||
// - Currently returns 0 if communication has timed out
|
||||
uint8_t SX1509::readByte(uint8_t registerAddress)
|
||||
{
|
||||
uint8_t readValue;
|
||||
// Commented the line as variable seems unused;
|
||||
//uint16_t timeout = RECEIVE_TIMEOUT_VALUE;
|
||||
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
_i2cPort->write(registerAddress);
|
||||
_i2cPort->endTransmission();
|
||||
_i2cPort->requestFrom(deviceAddress, (uint8_t)1);
|
||||
|
||||
readValue = _i2cPort->read();
|
||||
|
||||
return readValue;
|
||||
}
|
||||
|
||||
// readWord(uint8_t registerAddress)
|
||||
// This function will read a two-byte word beginning at registerAddress
|
||||
// - A 16-bit uint16_t will be returned.
|
||||
// - The msb of the return value will contain the value read from registerAddress
|
||||
// - The lsb of the return value will contain the value read from registerAddress + 1
|
||||
uint16_t SX1509::readWord(uint8_t registerAddress)
|
||||
{
|
||||
uint16_t readValue;
|
||||
uint16_t msb, lsb;
|
||||
// Commented the line as variable seems unused;
|
||||
//uint16_t timeout = RECEIVE_TIMEOUT_VALUE * 2;
|
||||
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
_i2cPort->write(registerAddress);
|
||||
_i2cPort->endTransmission();
|
||||
_i2cPort->requestFrom(deviceAddress, (uint8_t)2);
|
||||
|
||||
msb = (_i2cPort->read() & 0x00FF) << 8;
|
||||
lsb = (_i2cPort->read() & 0x00FF);
|
||||
readValue = msb | lsb;
|
||||
|
||||
return readValue;
|
||||
}
|
||||
|
||||
bool SX1509::readByte(uint8_t registerAddress, uint8_t *value)
|
||||
{
|
||||
return readBytes(registerAddress, value, 1);
|
||||
}
|
||||
|
||||
// readWord(uint8_t registerAddress)
|
||||
// This function will read a two-byte word beginning at registerAddress
|
||||
// - A 16-bit uint16_t will be set in value.
|
||||
// - The msb of the return value will contain the value read from registerAddress
|
||||
// - The lsb of the return value will contain the value read from registerAddress + 1
|
||||
// - Return boolean true if succesfull
|
||||
bool SX1509::readWord(uint8_t registerAddress, uint16_t *value)
|
||||
{
|
||||
uint8_t dest[2];
|
||||
if (readBytes(registerAddress, dest, 2))
|
||||
{
|
||||
*value = dest[1] | dest[0] << 8;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// readBytes(uint8_t firstRegisterAddress, uint8_t * destination, uint8_t length)
|
||||
// This function reads a series of bytes incrementing from a given address
|
||||
// - firstRegisterAddress is the first address to be read
|
||||
// - destination is an array of bytes where the read values will be stored into
|
||||
// - length is the number of bytes to be read
|
||||
// - Return boolean true if succesfull
|
||||
bool SX1509::readBytes(uint8_t firstRegisterAddress, uint8_t *destination, uint8_t length)
|
||||
{
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
_i2cPort->write(firstRegisterAddress);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
bool result = (endResult == I2C_ERROR_OK) && (_i2cPort->requestFrom(deviceAddress, length) == length);
|
||||
|
||||
if (result)
|
||||
{
|
||||
for (uint8_t i = 0; i < length; i++)
|
||||
{
|
||||
destination[i] = _i2cPort->read();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// writeByte(uint8_t registerAddress, uint8_t writeValue)
|
||||
// This function writes a single byte to a single register on the SX509.
|
||||
// - writeValue is written to registerAddress
|
||||
// - deviceAddres should already be set from the constructor
|
||||
// - Return value: true if succeeded, false if failed
|
||||
bool SX1509::writeByte(uint8_t registerAddress, uint8_t writeValue)
|
||||
{
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
bool result = _i2cPort->write(registerAddress) && _i2cPort->write(writeValue);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
return result && (endResult == I2C_ERROR_OK);
|
||||
}
|
||||
|
||||
// writeWord(uint8_t registerAddress, uint16_t writeValue)
|
||||
// This function writes a two-byte word to registerAddress and registerAddress + 1
|
||||
// - the upper byte of writeValue is written to registerAddress
|
||||
// - the lower byte of writeValue is written to registerAddress + 1
|
||||
// - Return value: true if succeeded, false if failed
|
||||
bool SX1509::writeWord(uint8_t registerAddress, uint16_t writeValue)
|
||||
{
|
||||
uint8_t msb, lsb;
|
||||
msb = ((writeValue & 0xFF00) >> 8);
|
||||
lsb = (writeValue & 0x00FF);
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
bool result = _i2cPort->write(registerAddress) && _i2cPort->write(msb) && _i2cPort->write(lsb);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
return result && (endResult == I2C_ERROR_OK);
|
||||
}
|
||||
|
||||
// writeBytes(uint8_t firstRegisterAddress, uint8_t * writeArray, uint8_t length)
|
||||
// This function writes an array of bytes, beggining at a specific adddress
|
||||
// - firstRegisterAddress is the initial register to be written.
|
||||
// - All writes following will be at incremental register addresses.
|
||||
// - writeArray should be an array of byte values to be written.
|
||||
// - length should be the number of bytes to be written.
|
||||
// - Return value: true if succeeded, false if failed
|
||||
bool SX1509::writeBytes(uint8_t firstRegisterAddress, uint8_t *writeArray, uint8_t length)
|
||||
{
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
bool result = _i2cPort->write(firstRegisterAddress);
|
||||
result = _i2cPort->write(writeArray, length);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
return result && (endResult == I2C_ERROR_OK);
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
/******************************************************************************
|
||||
SparkFunSX1509.h
|
||||
SparkFun SX1509 I/O Expander Library Header File
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
Here you'll find the Arduino code used to interface with the SX1509 I2C
|
||||
16 I/O expander. There are functions to take advantage of everything the
|
||||
SX1509 provides - input/output setting, writing pins high/low, reading
|
||||
the input value of pins, LED driver utilities (blink, breath, pwm), and
|
||||
keypad engine utilites.
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun employee) at the
|
||||
local, and you've found our code helpful, please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
******************************************************************************/
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifndef SparkFunSX1509_H
|
||||
#define SparkFunSX1509_H
|
||||
|
||||
#ifndef I2C_ERROR_OK
|
||||
#define I2C_ERROR_OK 0
|
||||
#endif
|
||||
|
||||
#define RECEIVE_TIMEOUT_VALUE 1000 // Timeout for I2C receive
|
||||
|
||||
// These are used for setting LED driver to linear or log mode:
|
||||
#define LINEAR 0
|
||||
#define LOGARITHMIC 1
|
||||
|
||||
// These are used for clock config:
|
||||
#define INTERNAL_CLOCK_2MHZ 2
|
||||
#define EXTERNAL_CLOCK 1
|
||||
|
||||
#define SOFTWARE_RESET 0
|
||||
#define HARDWARE_RESET 1
|
||||
|
||||
#define ANALOG_OUTPUT 0x3 // To set a pin mode for PWM output
|
||||
|
||||
class SX1509
|
||||
{
|
||||
private: // These private functions are not available to Arduino sketches.
|
||||
// If you need to read or write directly to registers, consider
|
||||
// putting the writeByte, readByte functions in the public section
|
||||
TwoWire *_i2cPort;
|
||||
uint8_t deviceAddress; // I2C Address of SX1509
|
||||
// Pin definitions:
|
||||
uint8_t pinInterrupt;
|
||||
uint8_t pinOscillator;
|
||||
uint8_t pinReset;
|
||||
// Misc variables:
|
||||
unsigned long _clkX;
|
||||
// Read Functions:
|
||||
uint8_t readByte(uint8_t registerAddress);
|
||||
uint16_t readWord(uint8_t registerAddress);
|
||||
|
||||
// Read Functions returning success or failure:
|
||||
bool readBytes(uint8_t firstRegisterAddress, uint8_t *destination, uint8_t length);
|
||||
|
||||
bool readByte(uint8_t registerAddress, uint8_t *value);
|
||||
bool readWord(uint8_t registerAddress, uint16_t *value);
|
||||
// Write functions, returning success or failure:
|
||||
bool writeByte(uint8_t registerAddress, uint8_t writeValue);
|
||||
bool writeWord(uint8_t registerAddress, uint16_t writeValue);
|
||||
bool writeBytes(uint8_t firstRegisterAddress, uint8_t *writeArray, uint8_t length);
|
||||
// Helper functions:
|
||||
// calculateLEDTRegister - Try to estimate an LED on/off duration register,
|
||||
// given the number of milliseconds and LED clock frequency.
|
||||
uint8_t calculateLEDTRegister(unsigned long ms);
|
||||
// calculateSlopeRegister - Try to estimate an LED rise/fall duration
|
||||
// register, given the number of milliseconds and LED clock frequency.
|
||||
uint8_t calculateSlopeRegister(unsigned long ms, uint8_t onIntensity, uint8_t offIntensity);
|
||||
|
||||
public:
|
||||
// -----------------------------------------------------------------------------
|
||||
// Constructor - SX1509: This function sets up the pins connected to the
|
||||
// SX1509, and sets up the private deviceAddress variable.
|
||||
// -----------------------------------------------------------------------------
|
||||
SX1509();
|
||||
// Legacy below. Use 0-parameter constructor, and set these parameters in the
|
||||
// begin function:
|
||||
SX1509(uint8_t address, uint8_t resetPin = 255, uint8_t interruptPin = 255, uint8_t oscillatorPin = 255);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// begin(uint8_t address, uint8_t resetPin): This function initializes the SX1509.
|
||||
// It requires wire to already be begun (previous versions did not do this), resets the IC, and tries to read some
|
||||
// registers to prove it's connected.
|
||||
// Inputs:
|
||||
// - address: should be the 7-bit address of the SX1509. This should be
|
||||
// one of four values - 0x3E, 0x3F, 0x70, 0x71 - all depending on what the
|
||||
// ADDR0 and ADDR1 pins ar se to. This variable is required.
|
||||
// - resetPin: This is the Arduino pin tied to the SX1509 RST pin. This
|
||||
// pin is optional. If not declared, the library will attempt to
|
||||
// software reset the SX1509.
|
||||
// Output: Returns a 1 if communication is successful, 0 on error.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t begin(uint8_t address = 0x3E, TwoWire &wirePort = Wire, uint8_t resetPin = 0xFF);
|
||||
uint8_t init(void); // Legacy -- use begin now
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// reset(bool hardware): This function resets the SX1509 - either a hardware
|
||||
// reset or software. A hardware reset (hardware parameter = 1) pulls the
|
||||
// reset line low, pausing, then pulling the reset line high. A software
|
||||
// reset writes a 0x12 then 0x34 to the REG_RESET as outlined in the
|
||||
// datasheet.
|
||||
//
|
||||
// Input:
|
||||
// - hardware: 0 executes a software reset, 1 executes a hardware reset
|
||||
// -----------------------------------------------------------------------------
|
||||
void reset(bool hardware);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// pinMode(uint8_t pin, uint8_t inOut): This function sets one of the SX1509's 16
|
||||
// outputs to either an INPUT or OUTPUT.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: should be a value between 0 and 15
|
||||
// - inOut: The Arduino INPUT and OUTPUT constants should be used for the
|
||||
// inOut parameter. They do what they say!
|
||||
// -----------------------------------------------------------------------------
|
||||
void pinMode(uint8_t pin, uint8_t inOut, uint8_t initialLevel = HIGH);
|
||||
void pinDir(uint8_t pin, uint8_t inOut, uint8_t initialLevel = HIGH); // Legacy - use pinMode
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// digitalWrite(uint8_t pin, uint8_t highLow): This function writes a pin to either high
|
||||
// or low if it's configured as an OUTPUT. If the pin is configured as an
|
||||
// INPUT, this method will activate either the PULL-UP or PULL-DOWN
|
||||
// resistor (HIGH or LOW respectively).
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin number. Should be a value between 0 and 15.
|
||||
// - highLow: should be Arduino's defined HIGH or LOW constants.
|
||||
// -----------------------------------------------------------------------------
|
||||
bool digitalWrite(uint8_t pin, uint8_t highLow);
|
||||
bool writePin(uint8_t pin, uint8_t highLow); // Legacy - use digitalWrite
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// digitalRead(uint8_t pin): This function reads the HIGH/LOW status of a pin.
|
||||
// The pin should be configured as an INPUT, using the pinDir function.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin to be read. should be a value between 0 and 15.
|
||||
// Outputs:
|
||||
// This function returns a 1 if HIGH, 0 if LOW
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
bool digitalRead(uint8_t pin, bool *value);
|
||||
uint8_t readPin(uint8_t pin); // Legacy - use digitalRead
|
||||
bool readPin(const uint8_t pin, bool *value);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ledDriverInit(uint8_t pin, uint8_t freq, bool log): This function initializes LED
|
||||
// driving on a pin. It must be called if you want to use the pwm or blink
|
||||
// functions on that pin.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin connected to an LED. Should be 0-15.
|
||||
// - freq: Sets LED clock frequency divider.
|
||||
// - log: selects either linear or logarithmic mode on the LED drivers
|
||||
// - log defaults to 0, linear mode
|
||||
// - currently log sets both bank A and B to the same mode
|
||||
// Note: this function automatically decides to use the internal 2MHz osc.
|
||||
// -----------------------------------------------------------------------------
|
||||
void ledDriverInit(uint8_t pin, uint8_t freq = 1, bool log = false);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// analogWrite(uint8_t pin, uint8_t iOn): This function can be used to control the intensity
|
||||
// of an output pin connected to an LED.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin connecte to an LED.Should be 0-15.
|
||||
// - iOn: should be a 0-255 value setting the intensity of the LED
|
||||
// - 0 is completely off, 255 is 100% on.
|
||||
//
|
||||
// Note: ledDriverInit should be called on the pin before calling this.
|
||||
// -----------------------------------------------------------------------------
|
||||
void analogWrite(uint8_t pin, uint8_t iOn);
|
||||
void pwm(uint8_t pin, uint8_t iOn); // Legacy - use analogWrite
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// setupBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t offIntensity, uint8_t tRise, uint8_t
|
||||
// tFall): blink performs both the blink and breath LED driver functions.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: the SX1509 pin (0-15) you want to set blinking/breathing.
|
||||
// - tOn: the amount of time the pin is HIGH
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// - tOff: the amount of time the pin is at offIntensity
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// - offIntensity: How dim the LED is during the off period.
|
||||
// - This value should be between 0 and 7. 0 is completely off.
|
||||
// - onIntensity: How bright the LED will be when completely on.
|
||||
// - This value can be between 0 (0%) and 255 (100%).
|
||||
// - tRise: This sets the time the LED takes to fade in.
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// - This value is used with tFall to make the LED breath.
|
||||
// - tFall: This sets the time the LED takes to fade out.
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// Notes:
|
||||
// - The breathable pins are 4, 5, 6, 7, 12, 13, 14, 15 only. If tRise and
|
||||
// tFall are set on 0-3 or 8-11 those pins will still only blink.
|
||||
// - ledDriverInit should be called on the pin to be blinked before this.
|
||||
// -----------------------------------------------------------------------------
|
||||
void setupBlink(uint8_t pin, uint8_t tOn, uint8_t toff, uint8_t onIntensity = 255, uint8_t offIntensity = 0, uint8_t tRise = 0, uint8_t tFall = 0, bool log = false);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity, uint8_t offIntensity);
|
||||
// Set a pin to blink output for estimated on/off millisecond durations.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: the SX1509 pin (0-15) you want to set blinking
|
||||
// - tOn: estimated number of milliseconds the pin is LOW (LED sinking current will be on)
|
||||
// - tOff: estimated number of milliseconds the pin is HIGH (LED sinking current will be off)
|
||||
// - onIntensity: 0-255 value determining LED on brightness
|
||||
// - offIntensity: 0-255 value determining LED off brightness
|
||||
// Notes:
|
||||
// - The breathable pins are 4, 5, 6, 7, 12, 13, 14, 15 only. If tRise and
|
||||
// tFall are set on 0-3 or 8-11 those pins will still only blink.
|
||||
// - ledDriverInit should be called on the pin to be blinked before this.
|
||||
// -----------------------------------------------------------------------------
|
||||
void blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity = 255, uint8_t offIntensity = 0);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, uint8_t onInt, uint8_t offInt, bool log);
|
||||
// Set a pin to breathe output for estimated on/off millisecond durations, with
|
||||
// estimated rise and fall durations.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: the SX1509 pin (0-15) you want to set blinking
|
||||
// - tOn: estimated number of milliseconds the pin is LOW (LED sinking current will be on)
|
||||
// - tOff: estimated number of milliseconds the pin is HIGH (LED sinking current will be off)
|
||||
// - rise: estimated number of milliseconds the pin rises from LOW to HIGH
|
||||
// - falll: estimated number of milliseconds the pin falls from HIGH to LOW
|
||||
// - onIntensity: 0-255 value determining LED on brightness
|
||||
// - offIntensity: 0-255 value determining LED off brightness
|
||||
// Notes:
|
||||
// - The breathable pins are 4, 5, 6, 7, 12, 13, 14, 15 only. If tRise and
|
||||
// tFall are set on 0-3 or 8-11 those pins will still only blink.
|
||||
// - ledDriverInit should be called on the pin to be blinked before this,
|
||||
// Or call pinMode(<pin>, ANALOG_OUTPUT);
|
||||
// -----------------------------------------------------------------------------
|
||||
void breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, uint8_t onInt = 255, uint8_t offInt = 0, bool log = LINEAR);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// keypad(uint8_t rows, uint8_t columns, uint8_t sleepTime, uint8_t scanTime, uint8_t debounceTime)
|
||||
// Initializes the keypad function on the SX1509. Millisecond durations for sleep,
|
||||
// scan, and debounce can be set.
|
||||
//
|
||||
// Inputs:
|
||||
// - rows: The number of rows in the button matrix.
|
||||
// - This value must be between 1 and 7. 0 will turn it off.
|
||||
// - eg: 1 = 2 rows, 2 = 3 rows, 7 = 8 rows, etc.
|
||||
// - columns: The number of columns in the button matrix
|
||||
// - This value should be between 0 and 7.
|
||||
// - 0 = 1 column, 7 = 8 columns, etc.
|
||||
// - sleepTime: Sets the auto-sleep time of the keypad engine.
|
||||
// Should be a millisecond duration between 0 (OFF) and 8000 (8 seconds).
|
||||
// Possible values are 0, 128, 256, 512, 1000, 2000, 4000, 8000
|
||||
// - scanTime: Sets the scan time per row. Must be set above debounce.
|
||||
// Should be a millisecond duration between 1 and 128.
|
||||
// Possible values are 1, 2, 4, 8, 16, 32, 64, 128.
|
||||
// - debounceTime: Sets the debounc time per button. Must be set below scan.
|
||||
// Should be a millisecond duration between 0 and 64.
|
||||
// Possible values are 0 (0.5), 1, 2, 4, 8, 16, 32, 64.
|
||||
// -----------------------------------------------------------------------------
|
||||
void keypad(uint8_t rows, uint8_t columns, uint16_t sleepTime = 0, uint8_t scanTime = 1, uint8_t debounceTime = 0);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// readKeypad(): This function returns a 16-bit value containing the status of
|
||||
// keypad engine.
|
||||
//
|
||||
// Output:
|
||||
// A 16-bit value is returned. The lower 8 bits represent the up-to 8 rows,
|
||||
// while the MSB represents the up-to 8 columns. Bit-values of 1 indicate a
|
||||
// button in that row or column is being pressed. As such, at least two
|
||||
// bits should be set.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint16_t readKeypad();
|
||||
uint16_t readKeyData(); // Legacy: use readKeypad();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// getRow(): This function returns the first active row from the return value of
|
||||
// readKeypad().
|
||||
//
|
||||
// Input:
|
||||
// - keyData: Should be the uint16_t value returned from readKeypad().
|
||||
// Output:
|
||||
// A 16-bit value is returned. The lower 8 bits represent the up-to 8 rows,
|
||||
// while the MSB represents the up-to 8 columns. Bit-values of 1 indicate a
|
||||
// button in that row or column is being pressed. As such, at least two
|
||||
// bits should be set.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t getRow(uint16_t keyData);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// getCol(): This function returns the first active column from the return value of
|
||||
// readKeypad().
|
||||
//
|
||||
// Input:
|
||||
// - keyData: Should be the uint16_t value returned from readKeypad().
|
||||
// Output:
|
||||
// A 16-bit value is returned. The lower 8 bits represent the up-to 8 rows,
|
||||
// while the MSB represents the up-to 8 columns. Bit-values of 1 indicate a
|
||||
// button in that row or column is being pressed. As such, at least two
|
||||
// bits should be set.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t getCol(uint16_t keyData);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// sync(void): this function resets the PWM/Blink/Fade counters, syncing any
|
||||
// blinking LEDs. Bit 2 of REG_MISC is set, which alters the functionality
|
||||
// of the nReset pin. The nReset pin is toggled low->high, which should
|
||||
// reset all LED counters. Bit 2 of REG_MISC is again cleared, returning
|
||||
// nReset pin to POR functionality
|
||||
// -----------------------------------------------------------------------------
|
||||
void sync(void);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debounceConfig(uint8_t configValue): This method configures the debounce time of
|
||||
// every input.
|
||||
//
|
||||
// Input:
|
||||
// - configValue: A 3-bit value configuring the debounce time.
|
||||
// 000: 0.5ms * 2MHz/fOSC
|
||||
// 001: 1ms * 2MHz/fOSC
|
||||
// 010: 2ms * 2MHz/fOSC
|
||||
// 011: 4ms * 2MHz/fOSC
|
||||
// 100: 8ms * 2MHz/fOSC
|
||||
// 101: 16ms * 2MHz/fOSC
|
||||
// 110: 32ms * 2MHz/fOSC
|
||||
// 111: 64ms * 2MHz/fOSC
|
||||
//
|
||||
// Note: fOSC is set with the configClock function. It defaults to 2MHz.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debounceConfig(uint8_t configVaule);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debounceTime(uint8_t configValue): This method configures the debounce time of
|
||||
// every input to an estimated millisecond time duration.
|
||||
//
|
||||
// Input:
|
||||
// - time: A millisecond duration estimating the debounce time. Actual
|
||||
// debounce time will depend on fOSC. Assuming it's 2MHz, debounce will
|
||||
// be set to the 0.5, 1, 2, 4, 8, 16, 32, or 64 ms (whatever's closest)
|
||||
//
|
||||
// Note: fOSC is set with the configClock function. It defaults to 2MHz.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debounceTime(uint8_t time);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debouncePin(uint8_t pin): This method enables debounce on SX1509 input pin.
|
||||
//
|
||||
// Input:
|
||||
// - pin: The SX1509 pin to be debounced. Should be between 0 and 15.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debouncePin(uint8_t pin);
|
||||
void debounceEnable(uint8_t pin); // Legacy, use debouncePin
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debounceKeypad(uint8_t pin): This method enables debounce on all pins connected
|
||||
// to a row/column keypad matrix.
|
||||
//
|
||||
// Input:
|
||||
// - time: Millisecond time estimate for debounce (see debounceTime()).
|
||||
// - numRows: The number of rows in the keypad matrix.
|
||||
// - numCols: The number of columns in the keypad matrix.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debounceKeypad(uint8_t time, uint8_t numRows, uint8_t numCols);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// enableInterrupt(uint8_t pin, uint8_t riseFall): This function sets up an interrupt
|
||||
// on a pin. Interrupts can occur on all SX1509 pins, and can be generated
|
||||
// on rising, falling, or both.
|
||||
//
|
||||
// Inputs:
|
||||
// -pin: SX1509 input pin that will generate an input. Should be 0-15.
|
||||
// -riseFall: Configures if you want an interrupt generated on rise fall or
|
||||
// both. For this param, send the pin-change values previously defined
|
||||
// by Arduino:
|
||||
// #define CHANGE 1 <-Both
|
||||
// #define FALLING 2 <- Falling
|
||||
// #define RISING 3 <- Rising
|
||||
//
|
||||
// Note: This function does not set up a pin as an input, or configure its
|
||||
// pull-up/down resistors! Do that before (or after).
|
||||
// -----------------------------------------------------------------------------
|
||||
void enableInterrupt(uint8_t pin, uint8_t riseFall);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// interruptSource(void): Returns an uint16_t representing which pin caused
|
||||
// an interrupt.
|
||||
//
|
||||
// Output: 16-bit value, with a single bit set representing the pin(s) that
|
||||
// generated an interrupt. E.g. a return value of 0x0104 would mean pins 8
|
||||
// and 3 (bits 8 and 3) have generated an interrupt.
|
||||
// Input:
|
||||
// - clear: boolean commanding whether the interrupt should be cleared
|
||||
// after reading or not.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint16_t interruptSource(bool clear = true);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// checkInterrupt(void): Checks if a single pin generated an interrupt.
|
||||
//
|
||||
// Output: Boolean value. True if the requested pin has triggered an interrupt/
|
||||
// Input:
|
||||
// - pin: Pin to be checked for generating an input.
|
||||
// -----------------------------------------------------------------------------
|
||||
bool checkInterrupt(uint8_t pin);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// configClock(uint8_t oscSource, uint8_t oscPinFunction, uint8_t oscFreqOut, uint8_t oscDivider)
|
||||
// This function configures the oscillator source/speed
|
||||
// and the clock, which is used to drive LEDs and time debounces.
|
||||
//
|
||||
// Inputs:
|
||||
// - oscSource: Choose either internal 2MHz oscillator or an external signal
|
||||
// applied to the OSCIO pin.
|
||||
// - INTERNAL_CLOCK and EXTERNAL_CLOCK are defined in the header file.
|
||||
// Use those.
|
||||
// - This value defaults to internal.
|
||||
// - oscDivider: Sets the clock divider in REG_MISC.
|
||||
// - ClkX = fOSC / (2^(RegMisc[6:4] -1))
|
||||
// - This value defaults to 1.
|
||||
// - oscPinFunction: Allows you to set OSCIO as an input or output.
|
||||
// - You can use Arduino's INPUT, OUTPUT defines for this value
|
||||
// - This value defaults to input
|
||||
// - oscFreqOut: If oscio is configured as an output, this will set the output
|
||||
// frequency
|
||||
// - This should be a 4-bit value. 0=0%, 0xF=100%, else
|
||||
// fOSCOut = FOSC / (2^(RegClock[3:0]-1))
|
||||
// - This value defaults to 0.
|
||||
// -----------------------------------------------------------------------------
|
||||
void configClock(uint8_t oscSource = 2, uint8_t oscPinFunction = 0, uint8_t oscFreqOut = 0, uint8_t oscDivider = 1); // Legacy, use clock();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// clock(uint8_t oscSource, uint8_t oscDivider, uint8_t oscPinFunction, uint8_t oscFreqOut)
|
||||
// This function configures the oscillator source/speed
|
||||
// and the clock, which is used to drive LEDs and time debounces.
|
||||
// This is just configClock in a bit more sane order.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
void clock(uint8_t oscSource = 2, uint8_t oscDivider = 1, uint8_t oscPinFunction = 0, uint8_t oscFreqOut = 0);
|
||||
};
|
||||
|
||||
// Add backwards compatibility for the old class name: sx1509Class
|
||||
typedef SX1509 sx1509Class;
|
||||
|
||||
#endif // SX1509_library_H
|
||||
@@ -0,0 +1,163 @@
|
||||
/******************************************************************************
|
||||
sx1509_registers.h
|
||||
Register definitions for SX1509.
|
||||
Jim Lindblom @ SparkFun Electronics
|
||||
Original Creation Date: September 21, 2015
|
||||
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
|
||||
|
||||
Here you'll find the Arduino code used to interface with the SX1509 I2C
|
||||
16 I/O expander. There are functions to take advantage of everything the
|
||||
SX1509 provides - input/output setting, writing pins high/low, reading
|
||||
the input value of pins, LED driver utilities (blink, breath, pwm), and
|
||||
keypad engine utilites.
|
||||
|
||||
Development environment specifics:
|
||||
IDE: Arduino 1.6.5
|
||||
Hardware Platform: Arduino Uno
|
||||
SX1509 Breakout Version: v2.0
|
||||
|
||||
This code is beerware; if you see me (or any other SparkFun employee) at the
|
||||
local, and you've found our code helpful, please buy us a round!
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
******************************************************************************/
|
||||
|
||||
#define REG_INPUT_DISABLE_B 0x00 // RegInputDisableB Input buffer disable register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_INPUT_DISABLE_A 0x01 // RegInputDisableA Input buffer disable register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_LONG_SLEW_B 0x02 // RegLongSlewB Output buffer long slew register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_LONG_SLEW_A 0x03 // RegLongSlewA Output buffer long slew register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_LOW_DRIVE_B 0x04 // RegLowDriveB Output buffer low drive register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_LOW_DRIVE_A 0x05 // RegLowDriveA Output buffer low drive register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_PULL_UP_B 0x06 // RegPullUpB Pull_up register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_PULL_UP_A 0x07 // RegPullUpA Pull_up register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_PULL_DOWN_B 0x08 // RegPullDownB Pull_down register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_PULL_DOWN_A 0x09 // RegPullDownA Pull_down register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_OPEN_DRAIN_B 0x0A // RegOpenDrainB Open drain register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_OPEN_DRAIN_A 0x0B // RegOpenDrainA Open drain register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_POLARITY_B 0x0C // RegPolarityB Polarity register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_POLARITY_A 0x0D // RegPolarityA Polarity register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_DIR_B 0x0E // RegDirB Direction register _ I/O[15_8] (Bank B) 1111 1111
|
||||
#define REG_DIR_A 0x0F // RegDirA Direction register _ I/O[7_0] (Bank A) 1111 1111
|
||||
#define REG_DATA_B 0x10 // RegDataB Data register _ I/O[15_8] (Bank B) 1111 1111*
|
||||
#define REG_DATA_A 0x11 // RegDataA Data register _ I/O[7_0] (Bank A) 1111 1111*
|
||||
#define REG_INTERRUPT_MASK_B 0x12 // RegInterruptMaskB Interrupt mask register _ I/O[15_8] (Bank B) 1111 1111
|
||||
#define REG_INTERRUPT_MASK_A 0x13 // RegInterruptMaskA Interrupt mask register _ I/O[7_0] (Bank A) 1111 1111
|
||||
#define REG_SENSE_HIGH_B 0x14 // RegSenseHighB Sense register for I/O[15:12] 0000 0000
|
||||
#define REG_SENSE_LOW_B 0x15 // RegSenseLowB Sense register for I/O[11:8] 0000 0000
|
||||
#define REG_SENSE_HIGH_A 0x16 // RegSenseHighA Sense register for I/O[7:4] 0000 0000
|
||||
#define REG_SENSE_LOW_A 0x17 // RegSenseLowA Sense register for I/O[3:0] 0000 0000
|
||||
#define REG_INTERRUPT_SOURCE_B 0x18 // RegInterruptSourceB Interrupt source register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_INTERRUPT_SOURCE_A 0x19 // RegInterruptSourceA Interrupt source register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_EVENT_STATUS_B 0x1A // RegEventStatusB Event status register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_EVENT_STATUS_A 0x1B // RegEventStatusA Event status register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_LEVEL_SHIFTER_1 0x1C // RegLevelShifter1 Level shifter register 0000 0000
|
||||
#define REG_LEVEL_SHIFTER_2 0x1D // RegLevelShifter2 Level shifter register 0000 0000
|
||||
#define REG_CLOCK 0x1E // RegClock Clock management register 0000 0000
|
||||
#define REG_MISC 0x1F // RegMisc Miscellaneous device settings register 0000 0000
|
||||
#define REG_LED_DRIVER_ENABLE_B 0x20 // RegLEDDriverEnableB LED driver enable register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_LED_DRIVER_ENABLE_A 0x21 // RegLEDDriverEnableA LED driver enable register _ I/O[7_0] (Bank A) 0000 0000
|
||||
// Debounce and Keypad Engine
|
||||
#define REG_DEBOUNCE_CONFIG 0x22 // RegDebounceConfig Debounce configuration register 0000 0000
|
||||
#define REG_DEBOUNCE_ENABLE_B 0x23 // RegDebounceEnableB Debounce enable register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_DEBOUNCE_ENABLE_A 0x24 // RegDebounceEnableA Debounce enable register _ I/O[7_0] (Bank A) 0000 0000
|
||||
#define REG_KEY_CONFIG_1 0x25 // RegKeyConfig1 Key scan configuration register 0000 0000
|
||||
#define REG_KEY_CONFIG_2 0x26 // RegKeyConfig2 Key scan configuration register 0000 0000
|
||||
#define REG_KEY_DATA_1 0x27 // RegKeyData1 Key value (column) 1111 1111
|
||||
#define REG_KEY_DATA_2 0x28 // RegKeyData2 Key value (row) 1111 1111
|
||||
// LED Driver (PWM, blinking, breathing)
|
||||
#define REG_T_ON_0 0x29 // RegTOn0 ON time register for I/O[0] 0000 0000
|
||||
#define REG_I_ON_0 0x2A // RegIOn0 ON intensity register for I/O[0] 1111 1111
|
||||
#define REG_OFF_0 0x2B // RegOff0 OFF time/intensity register for I/O[0] 0000 0000
|
||||
#define REG_T_ON_1 0x2C // RegTOn1 ON time register for I/O[1] 0000 0000
|
||||
#define REG_I_ON_1 0x2D // RegIOn1 ON intensity register for I/O[1] 1111 1111
|
||||
#define REG_OFF_1 0x2E // RegOff1 OFF time/intensity register for I/O[1] 0000 0000
|
||||
#define REG_T_ON_2 0x2F // RegTOn2 ON time register for I/O[2] 0000 0000
|
||||
#define REG_I_ON_2 0x30 // RegIOn2 ON intensity register for I/O[2] 1111 1111
|
||||
#define REG_OFF_2 0x31 // RegOff2 OFF time/intensity register for I/O[2] 0000 0000
|
||||
#define REG_T_ON_3 0x32 // RegTOn3 ON time register for I/O[3] 0000 0000
|
||||
#define REG_I_ON_3 0x33 // RegIOn3 ON intensity register for I/O[3] 1111 1111
|
||||
#define REG_OFF_3 0x34 // RegOff3 OFF time/intensity register for I/O[3] 0000 0000
|
||||
#define REG_T_ON_4 0x35 // RegTOn4 ON time register for I/O[4] 0000 0000
|
||||
#define REG_I_ON_4 0x36 // RegIOn4 ON intensity register for I/O[4] 1111 1111
|
||||
#define REG_OFF_4 0x37 // RegOff4 OFF time/intensity register for I/O[4] 0000 0000
|
||||
#define REG_T_RISE_4 0x38 // RegTRise4 Fade in register for I/O[4] 0000 0000
|
||||
#define REG_T_FALL_4 0x39 // RegTFall4 Fade out register for I/O[4] 0000 0000
|
||||
#define REG_T_ON_5 0x3A // RegTOn5 ON time register for I/O[5] 0000 0000
|
||||
#define REG_I_ON_5 0x3B // RegIOn5 ON intensity register for I/O[5] 1111 1111
|
||||
#define REG_OFF_5 0x3C // RegOff5 OFF time/intensity register for I/O[5] 0000 0000
|
||||
#define REG_T_RISE_5 0x3D // RegTRise5 Fade in register for I/O[5] 0000 0000
|
||||
#define REG_T_FALL_5 0x3E // RegTFall5 Fade out register for I/O[5] 0000 0000
|
||||
#define REG_T_ON_6 0x3F // RegTOn6 ON time register for I/O[6] 0000 0000
|
||||
#define REG_I_ON_6 0x40 // RegIOn6 ON intensity register for I/O[6] 1111 1111
|
||||
#define REG_OFF_6 0x41 // RegOff6 OFF time/intensity register for I/O[6] 0000 0000
|
||||
#define REG_T_RISE_6 0x42 // RegTRise6 Fade in register for I/O[6] 0000 0000
|
||||
#define REG_T_FALL_6 0x43 // RegTFall6 Fade out register for I/O[6] 0000 0000
|
||||
#define REG_T_ON_7 0x44 // RegTOn7 ON time register for I/O[7] 0000 0000
|
||||
#define REG_I_ON_7 0x45 // RegIOn7 ON intensity register for I/O[7] 1111 1111
|
||||
#define REG_OFF_7 0x46 // RegOff7 OFF time/intensity register for I/O[7] 0000 0000
|
||||
#define REG_T_RISE_7 0x47 // RegTRise7 Fade in register for I/O[7] 0000 0000
|
||||
#define REG_T_FALL_7 0x48 // RegTFall7 Fade out register for I/O[7] 0000 0000
|
||||
#define REG_T_ON_8 0x49 // RegTOn8 ON time register for I/O[8] 0000 0000
|
||||
#define REG_I_ON_8 0x4A // RegIOn8 ON intensity register for I/O[8] 1111 1111
|
||||
#define REG_OFF_8 0x4B // RegOff8 OFF time/intensity register for I/O[8] 0000 0000
|
||||
#define REG_T_ON_9 0x4C // RegTOn9 ON time register for I/O[9] 0000 0000
|
||||
#define REG_I_ON_9 0x4D // RegIOn9 ON intensity register for I/O[9] 1111 1111
|
||||
#define REG_OFF_9 0x4E // RegOff9 OFF time/intensity register for I/O[9] 0000 0000
|
||||
#define REG_T_ON_10 0x4F // RegTOn10 ON time register for I/O[10] 0000 0000
|
||||
#define REG_I_ON_10 0x50 // RegIOn10 ON intensity register for I/O[10] 1111 1111
|
||||
#define REG_OFF_10 0x51 // RegOff10 OFF time/intensity register for I/O[10] 0000 0000
|
||||
#define REG_T_ON_11 0x52 // RegTOn11 ON time register for I/O[11] 0000 0000
|
||||
#define REG_I_ON_11 0x53 // RegIOn11 ON intensity register for I/O[11] 1111 1111
|
||||
#define REG_OFF_11 0x54 // RegOff11 OFF time/intensity register for I/O[11] 0000 0000
|
||||
#define REG_T_ON_12 0x55 // RegTOn12 ON time register for I/O[12] 0000 0000
|
||||
#define REG_I_ON_12 0x56 // RegIOn12 ON intensity register for I/O[12] 1111 1111
|
||||
#define REG_OFF_12 0x57 // RegOff12 OFF time/intensity register for I/O[12] 0000 0000
|
||||
#define REG_T_RISE_12 0x58 // RegTRise12 Fade in register for I/O[12] 0000 0000
|
||||
#define REG_T_FALL_12 0x59 // RegTFall12 Fade out register for I/O[12] 0000 0000
|
||||
#define REG_T_ON_13 0x5A // RegTOn13 ON time register for I/O[13] 0000 0000
|
||||
#define REG_I_ON_13 0x5B // RegIOn13 ON intensity register for I/O[13] 1111 1111
|
||||
#define REG_OFF_13 0x5C // RegOff13 OFF time/intensity register for I/O[13] 0000 0000
|
||||
#define REG_T_RISE_13 0x5D // RegTRise13 Fade in register for I/O[13] 0000 0000
|
||||
#define REG_T_FALL_13 0x5E // RegTFall13 Fade out register for I/O[13] 0000 0000
|
||||
#define REG_T_ON_14 0x5F // RegTOn14 ON time register for I/O[14] 0000 0000
|
||||
#define REG_I_ON_14 0x60 // RegIOn14 ON intensity register for I/O[14] 1111 1111
|
||||
#define REG_OFF_14 0x61 // RegOff14 OFF time/intensity register for I/O[14] 0000 0000
|
||||
#define REG_T_RISE_14 0x62 // RegTRise14 Fade in register for I/O[14] 0000 0000
|
||||
#define REG_T_FALL_14 0x63 // RegTFall14 Fade out register for I/O[14] 0000 0000
|
||||
#define REG_T_ON_15 0x64 // RegTOn15 ON time register for I/O[15] 0000 0000
|
||||
#define REG_I_ON_15 0x65 // RegIOn15 ON intensity register for I/O[15] 1111 1111
|
||||
#define REG_OFF_15 0x66 // RegOff15 OFF time/intensity register for I/O[15] 0000 0000
|
||||
#define REG_T_RISE_15 0x67 // RegTRise15 Fade in register for I/O[15] 0000 0000
|
||||
#define REG_T_FALL_15 0x68 // RegTFall15 Fade out register for I/O[15] 0000 0000
|
||||
// Miscellaneous
|
||||
#define REG_HIGH_INPUT_B 0x69 // RegHighInputB High input enable register _ I/O[15_8] (Bank B) 0000 0000
|
||||
#define REG_HIGH_INPUT_A 0x6A // RegHighInputA High input enable register _ I/O[7_0] (Bank A) 0000 0000
|
||||
// Software Reset
|
||||
#define REG_RESET 0x7D // RegReset Software reset register 0000 0000
|
||||
#define REG_TEST_1 0x7E // RegTest1 Test register 0000 0000
|
||||
#define REG_TEST_2 0x7F // RegTest2 Test register 0000 0000
|
||||
|
||||
byte REG_I_ON[16] = {REG_I_ON_0, REG_I_ON_1, REG_I_ON_2, REG_I_ON_3,
|
||||
REG_I_ON_4, REG_I_ON_5, REG_I_ON_6, REG_I_ON_7,
|
||||
REG_I_ON_8, REG_I_ON_9, REG_I_ON_10, REG_I_ON_11,
|
||||
REG_I_ON_12, REG_I_ON_13, REG_I_ON_14, REG_I_ON_15};
|
||||
|
||||
byte REG_T_ON[16] = {REG_T_ON_0, REG_T_ON_1, REG_T_ON_2, REG_T_ON_3,
|
||||
REG_T_ON_4, REG_T_ON_5, REG_T_ON_6, REG_T_ON_7,
|
||||
REG_T_ON_8, REG_T_ON_9, REG_T_ON_10, REG_T_ON_11,
|
||||
REG_T_ON_12, REG_T_ON_13, REG_T_ON_14, REG_T_ON_15};
|
||||
|
||||
byte REG_OFF[16] = {REG_OFF_0, REG_OFF_1, REG_OFF_2, REG_OFF_3,
|
||||
REG_OFF_4, REG_OFF_5, REG_OFF_6, REG_OFF_7,
|
||||
REG_OFF_8, REG_OFF_9, REG_OFF_10, REG_OFF_11,
|
||||
REG_OFF_12, REG_OFF_13, REG_OFF_14, REG_OFF_15};
|
||||
|
||||
byte REG_T_RISE[16] = {0xFF, 0xFF, 0xFF, 0xFF,
|
||||
REG_T_RISE_4, REG_T_RISE_5, REG_T_RISE_6, REG_T_RISE_7,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
REG_T_RISE_12, REG_T_RISE_13, REG_T_RISE_14, REG_T_RISE_15};
|
||||
|
||||
byte REG_T_FALL[16] = {0xFF, 0xFF, 0xFF, 0xFF,
|
||||
REG_T_FALL_4, REG_T_FALL_5, REG_T_FALL_6, REG_T_FALL_7,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
REG_T_FALL_12, REG_T_FALL_13, REG_T_FALL_14, REG_T_FALL_15};
|
||||
Reference in New Issue
Block a user