Page 1 of 16
SX1509 I/O Expander Breakout Hookup Guide
Introduction
Is your Arduino running low on GPIO? Looking to control the brightness of
16 LEDs individually? Maybe blink or breathe a few autonomously? Want to
delegate scanning an 8x8 matrix of 64 buttons to another controller? These
are all tasks the for which the SX1509 16-IO Expander was made!
The SX1509 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. And, with a built-in keypad engine, it
can interface with up to 64 buttons set up in an 8x8 matrix.
An SX1509 controlling three LEDs, monitoring three buttons and a 12button keypad, and producing SPI signals to drive a Serial 7-Segment
Display.
It’s a really cool chip and a great tool for expanding the capability of your
Arduino or any other I2C-capable microcontroller.
Page 2 of 16
Covered In this Tutorial
This tutorial will serve to familiarize you with all things SX1509 and the
SparkFun Breakout. Then we’ll demonstrate how take advantage of all of
the I/O expander’s features using an Arduino-compatible microcontroller
and our SX1509 Arduino Library.
The tutorial is split into the following sections:
• SX1509 Breakout Board Overview – An overview of the features of
the SX1509 and the SparkFun breakout.
• Hardware Assembly – Tips and tricks for soldering headers or wires
to the SX1509 Breakout.
• Installing the SparkFun SX1509 Arduino Library – We’ve written an
Arduino library to abstract all of the ugly register bit-operations.
◦ Example: Digital In/Out and PWM – An example circuit and
Arduino sketch demonstrating some of the simpler I/O
expander features.
◦ Example: LED Driving – Examples demonstrating how to
autonomously blink and breathe LEDs.
◦ Example: Button Matrices – How to use the SX1509’s keypad
engine to monitor a 12-button keypad.
Suggested Reading
Before delving into this tutorial, there are a few concepts you should
already be somewhat familiar with. Check out these related tutorials:
• I2C Communication – The SX1509 is controlled over an I2C interface.
Learn all about this powerful 2-wire interface.
• Logic Levels – While most Arduino’s operate at 5V, the SX1509
works at 3.3V. The GPIO are, at least, 5V tolerant!
• Pulse-Width Modulation (PWM) – All of the SX1509’s output pins are
capable of producing a PWM signal. That means you can control the
brightness of LEDs!
Pulse-width Modulation
Logic Levels
An introduction to the concept of
pulse width modulation.
Learn the difference between 3.3 V
and 5 V devices.
Light-emitting Diodes (LEDs)
I2C
Learn the basics about LEDs as well
as some more advanced topics to
help you calculate requirements for
projects containing many LEDs.
An introduction to I2C, one of the
main embedded communications
protocols in use today.
Page 3 of 16
SX1509 Breakout Board Overview
There’s a lot going on on the SX1509 Breakout. GPIO and power buses are
broken out in every-which direction, and configurable jumpers cover most of
the rest of the board.
This section will cover all things SX1509 Breakout, so you can get the most
out of the board’s features.
I2C and Power Input Headers
These two headers at the top and bottom of the breakout board are 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.
These headers break out the following pins:
Pin
Label
Type
Description
INT
Output
Active low programmable interrupt
RST
Input
Active low reset (pulled high on-board)
GND
Power
Ground (0V)
3V3
Power
Main supply voltage (1.425-3.6V)
SDA
I2C
I2C serial data line
SCL
I2C
I2C serial clock line
OSC
Clock
In/Out
Optional clock input, or programmable clock
signal output
Page 4 of 16
The SDA and SCL pins each have 10kΩ resistors pulling them up to 3.3V.
These resistors can be disconnected by cutting the SJ1 jumpers.
RST – the SX1509’s active-low reset input – works just like an Arduino
reset pin. If the pin is pulled LOW, the SX1509 will power down. When RST
rises, the SX1509 will turn back on, but all of its settings will be cleared out.
The breakout board includes a 10kΩ resistor pulling RST HIGH, so you
ignore this pin if you don’t need the reset functionality.
INT is a very handy interrupt output, especially if you’re using any SX1509
pins as inputs. It can be configured to go LOW whenever a pin state
changes. The breakout board includes a 10kΩ resistor pulling INT HIGH.
Finally, OSC breaks out the SX1509’s OSCIO pin – the oscillator
input/output. This highly-configurable pin can be used as either the clock
input for the SX1509 (if you don’t want to use its internal 2MHz clock), a
clock output (producing an up to 2MHz square wave signal), or a simple
digital I/O.
Required and optional pins: The pairs of power and I2C pins are the
only ones required for interfacing with the SX1509. RST, INT, and
OSC are all optional, they can be left disconnected if you don't need
the feature they provide.
I/O and GND/VCC Breakouts
The real meat of the breakout board are the pairs of rows breaking out all
sixteen I/O pins plus the power rails.
The SX1509 breaks its 16 I/O into two banks – bank A and bank B. Each
bank can operate on a separate power supply, but by default they’re both
set to 3.3V. Bank A is powered by VCC1, and bank B is supplied by VCC2.
VCC1 and VCC2 can range between 1.2V and 3.6V, if you want to supply
them externally. Check out the “Jumpers” section for more information on
that.
Every I/O pin is capable of PWM and blink outputs, but only half of them
can be set to “breathe” (blink with smooth transitions from on to off). Also, if
you plan on using the SX1509 keypad driver, each I/O is relegated to either
a row or column interface.
LED Driver
Keypad
I/O
PWM
Blink
Breathe
Row
0
✓
✓
✓
1
✓
✓
✓
2
✓
✓
✓
3
✓
✓
✓
Column
Page 5 of 16
4
✓
✓
✓
✓
5
✓
✓
✓
✓
6
✓
✓
✓
✓
7
✓
✓
✓
✓
8
✓
✓
✓
9
✓
✓
✓
10
✓
✓
✓
11
✓
✓
✓
12
✓
✓
✓
✓
13
✓
✓
✓
✓
14
✓
✓
✓
✓
15
✓
✓
✓
✓
Ground (or Power) Rails
Running alongside the I/O breakouts are a pair of power rails. These rails
can be distinguished by the bars of white silkscreen running between
each pad.
By default, these rails are both set to ground – handy if you want to fan out
some active-low buttons, or current-sourced LEDs. Jumpers on the back
side allow you to switch the rails from GND to either VCC1 or VCC2. You’ll
need to cut the jumper between GND and the rail, then blob solder between
the rail and VCC.
This bus is completely optional. Just don’t solder male pins into both rows
of headers if you plan on using the breakout in a breadboard!
Address-Select Jumpers
Up to four SX1509’s can be connected to a single I2C bus, by configuring
them to different addresses. The SX1509 has two pins devoted to I2C
address selection: ADD0 and ADD1. Each of those pins are broken out to a
jumper on the bottom of the board.
Page 6 of 16
The board defaults each of those pins to GND, which sets the I2C address
to 0x3E. To set either jumper to “1” (HIGH), grab a hobby knife, cut the
trace connecting to “0”, and blob some solder between the center pad and
“1”.
The four configurable addresses are listed on the back of the board, but for
quick reference, they are:
ADD1
ADD0
I2C address
0
0
0x3E
0
1
0x3F
1
0
0x70
1
1
0x71
VCC1 and VCC2 Jumpers
SJ1 and SJ2 on the back-side of the board connect VCC2 and VCC1,
respectively, to the 3V3 voltage supply input. So, if you’re delivering 3.3V to
the board, each of the I/O banks will operate at 3.3V.
If you want to take advantage of the SX1509’s level-shifting capabilities by
powering these banks at something other than VCC, cut the jumpers and
plug any voltage between 1.2V and 3.6V into the VCC1 and/or VCC2 pins.
These supply buses are completely independent – so they can operate at
different voltages.
Hardware Assembly
You’ll need to solder something into the SX1509 Breakout to use it, whether
that something is male or female headers or wire is completely up to you
and your intended application. If you’ve never soldered before, check out
our PTH soldering tutorial.
One option we like, which keeps the board as breadboard-compatible as
can be, is soldering male headers on the I/O banks, and female headers on
either (or both) of the power/I2C headers.
Page 7 of 16
Then you can use male-to-male jumper wires to connect between your
microcontroller and the breakout, and breadboard the rest of the I/O.
Installing the SparkFun SX1509 Arduino
Library
Now that you’ve got the hardware all mostly figured out, it’s time to start
programming! To help make using the SX1509 as painless as possible,
we’ve written an Arduino library to help interface with it. Visit the SparkFun
SX1509 Arduino Library GitHub repository, or click the button below to
download the latest version of the library.
D O W N LO AD T H E S X1 5 0 9 A R D UI N O L I B RA R Y !
For help installing the library, check out our Installing an Arduino Library
tutorial. If you downloaded the library as a ZIP, you can use Arduino’s
Sketch > Include Library > Add .ZIP Library tool to automatically add it to
your Arduino sketchbook.
The SparkFun SX1509 Arduino library includes all sorts of examples, which
demonstrate specific features of the I/O expander. Navigate to File >
Examples > SparkFun SX1509 IO Expander to check them out.
Quickly, we’ll walk you through a few quick examples that show off the I/O
expander’s range of features.
Example: Digital In/Out and PWM
Page 8 of 16
As with almost any I/O expander, each of the SX1509’s GPIO can be
configured as simple digital inputs or outputs. So you can toggle LEDs on
or off, monitor for button presses, or even bit-bang more advanced digital
interfaces like SPI (probably nothing that’s timing-dependent though).
Here’s a quick example that shows how you can digitalWrite or
digitalRead using the SX1509. If you want to follow along, hook up a
circuit like below:
Match up 3.3V, GND, SDA, and SCL between your Arduino and the
SX1509 Breakout. Then connect an LED to I/O 15 – you can either
configure it to source or sink current. And connect an active-low button to
I/O 0.
Then throw this code onto your Arduino:
Page 9 of 16
#include // Include the I2C library (required)
#include // Include SX1509 library
SX1509 io; // Create an SX1509 object
// SX1509 pin definitions:
// Note: these aren't Arduino pins. They're the SX1509 I/O:
const int SX1509_LED_PIN = 15; // LED connected to 15 (source
ing current)
const int SX1509_BTN_PIN = 7; // Button connected to 0 (active
low)
bool ledState = false;
void setup()
{
pinMode(13, OUTPUT); // Use pin 13 LED as debug output
digitalWrite(13, LOW); // Start it as low
// Call io.begin() to initialize the I/O
// expander. It'll return 1 on success, 0 on fail.
if (!io.begin(0x3E))
{
// If we failed to communicate, turn the pin 13 LED on
digitalWrite(13, HIGH);
while (1)
; // And loop forever.
}
// Call io.pinMode(, ) to set any SX1509 pin as
// either an INPUT, OUTPUT, INPUT_PULLUP, or ANALOG_OUTPUT
io.pinMode(SX1509_LED_PIN, OUTPUT);
io.pinMode(SX1509_BTN_PIN, INPUT_PULLUP);
// Blink the LED a few times before we start:
for (int i=0; i