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:
2025-05-13 19:07:14 +02:00
parent 6435550e29
commit 379b4887c3
47 changed files with 26343 additions and 2850 deletions
@@ -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));
}
}
@@ -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
}