Overview
Solenoids are a little like cats: if your project has one solenoid, you'll probably stick with just one, and in such cases our single MOSFET driver will work well. But if you have more than one solenoid, it's going to be anywhere from 2 to 24. Why? Maybe people just love their purring clicky-clacking. And driving a lot of solenoids is kind of a pain: they all need drive transistors and flyback diodes and then a common power source. That's why we designed the Adafruit I2C to 8 Channel Solenoid Driver featuring an MCP23017 GPIO expander to control eight solenoids at a time easily and solder-free.
This board has an I2C to GPIO expander - so you can use it even if you don't have a lot of pins on your microcontroller. Power the solenoids with a DC power supply in the center terminal blocks, you can use 3V to 24V DC maximum. Then wire up each solenoid to the remaining terminal blocks. The positive side will tie to the power supply you provided, and then the negative side will connect to ground when activated. Each solenoid has its own pass transistor AO3406 N-Channel MOSFET rated for 30Vdc, 3.6A peak, and 70mΩ RdsOn. A flyback diode protects your circuit from the inductive kick-back, and a red LED will light up to let you know that the transistor is on.
Since the MCP23017 has 16 total IO pins, we also bring out the B port, which you can use for other general purpose I/O, such as LED drivers, or button inputs. There are also three address pins you can jumper closed so up to 8 boards can be daisy-chained together for a total of 64 solenoids.
The Adafruit I2C to 8 Channel Solenoid Driver can be powered/driven with 3V or 5V power and logic so it's usable by everything from an Arduino-compatible Metro 328 to the latest Raspberry Pi. And the SparkFun Qwiic compatible STEMMA QT JST SH connectors ease the process of connecting the Solenoid Driver to your project. The board allows you to easily share an I2C bus with other STEMMA QT, Qwiic, Grove, or other compatible sensors. QT Cable is not included, but we have a variety in the shop.
Page last edited June 04, 2025
Text editor powered by tinymce.
Pinouts
The default I2C address is 0x20.
Power Pins
- Vcc - This is the power pin. To power the board, give it the same power as the logic level of your microcontroller - i.e. for a 5V micro like Arduino, use 5V, or for a 3V micro like a Feather, use 3V.
- V+/+ - The DC power input terminal block for the solenoids is located in the center of the terminal block row on the top edge of the board. You can use 3V to 24V DC maximum to power the solenoids.
- GND - This is common ground for power and logic.
- GND pads - The ground pads (highlighted in white on the board's silkscreen) are available as discrete ground connections for the GPIO.
I2C Logic Pins
- SCL - I2C clock pin, connect to your microcontroller's I2C clock line. This pin can use 3-5V logic, and there's a 10K pullup on this pin.
- SDA - I2C data pin, connect to your microcontroller's I2C data line. This pin can use 3-5V logic, and there's a 10K pullup on this pin.
- STEMMA QT - These connectors allow you to connect to dev boards with STEMMA QT (qwiic) connectors or to other things with various associated accessories
Solenoid Terminal Block Outputs
Along the top edge of the board are two sets of 8 terminal blocks. These are the solenoid outputs from the N-Channel MOSFETs connected to the MCP23017.
- The outputs labeled + on the front of board and V+ on the back, are connected to the DC power supply input terminal block and connect to the positive input on your solenoid.
- The numbered outputs, labeled 0-7 on the front of the board and A0-A7 on the back, will connect to the negative input on your solenoid and are routed to the A port pins on the MCP23017 (A0-A7).
Additional MCP23017 GPIO Pins
Along the bottom edge of the board are 8 additional GPIO from the MCP23017 B port. These pins are labeled B0-B7 and correspond to those same output pins on the MCP23017. You can use these pins as general purpose I/O for LEDs, button inputs, etc.
MCP23017 Port B Interrupt Pin
- INT - This is the interrupt pin (INTB) for port B on the MCP23017. You can use it to keep track of inputs connected to the port B GPIO pins at the bottom edge of the breakout.
LEDs
- Red LEDs - Directly below the terminal blocks are 8 red LEDs. These LEDs act as indicators for the 8 solenoid outputs. When a signal is sent to any of these outputs, the corresponding red LED will turn on.
- Power LED - On the left side of the board, above the STEMMA QT port, is the power LED. It is a green LED.
- Power LED Jumper - This jumper is located on the back of the board, on the right. Cut the trace on this jumper to cut power to the green power LED.
I2C Address Pins
On the back of the board are three address jumpers, labeled A0, A1 and A2. These jumpers allow you to chain up to 8 of these boards on the same pair of I2C clock and data pins. To do so, you solder the jumpers "closed" by connecting the two pads.
On the front of the board are three address pins, labeled A0, A1 and A2. Just like the jumpers, these pins allow you to change the I2C address to connect multiple boards by connecting them to Vcc.
The default I2C address is 0x20. The other address options can be calculated by “adding” the A0/A1/A2 to the base of 0x20.
A0 sets the lowest bit with a value of 1, A1 sets the next bit with a value of 2 and A2 sets the next bit with a value of 4. The final address is 0x20 + A2 + A1 + A0 which would be 0x27.
So for example if A2 is soldered closed and A0 is soldered closed, the address is 0x20 + 4 + 1 = 0x25.
If only A0 is soldered closed, the address is 0x20 + 1 = 0x21
If only A1 is soldered closed, the address is 0x20 + 2 = 0x22
If only A2 is soldered closed, the address is 0x20 + 4 = 0x24
The table below shows all possible addresses, and whether the pin(s) should be high (closed) or low (open).
Page last edited June 04, 2025
Text editor powered by tinymce.
CircuitPython and Python
It's easy to use the 8 Channel Solenoid Driver with Python or CircuitPython, and the Adafruit CircuitPython MCP23017 module. This module allows you to easily write Python code that adds up to 16 inputs or outputs over I2C.
You can use this driver with any CircuitPython microcontroller board or with a computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.
You'll need a solenoid motor, external DC power supply and a DC jack to terminal block adapter to follow this example.
CircuitPython Microcontroller Wiring
First wire up the breakout to your board exactly as follows. The following is the breakout wired to a Feather RP2040 and two solenoid motors:
-
Board 3.3V to breakout Vcc (red wire)
-
Board GND to breakout GND (black wire)
-
Board SCL to breakout SCL (yellow wire)
- Board SDA to breakout SDA (blue wire)
- Motor 1 positive to breakout + (red wire)
- Motor 1 negative to breakout A0 (black wire)
- Motor 2 positive to breakout + (red wire)
- Motor 2 negative to breakout A4 (black wire)
- DC power supply GND to breakout terminal block GND (black wire)
- DC power supply positive to breakout terminal block V+ (red wire)
Python Computer Wiring
Since there are dozens of Linux computers/boards you can use, we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported.
Here's the Raspberry Pi wired to the breakout with two solenoid motors:
-
Pi 3.3V to breakout Vcc (red wire)
-
Pi GND to breakout GND (black wire)
-
Pi SCL to breakout SCL (yellow wire)
- Pi SDA to breakout SDA (blue wire)
- Motor 1 positive to breakout + (red wire)
- Motor 1 negative to breakout A0 (black wire)
- Motor 2 positive to breakout + (red wire)
- Motor 2 negative to breakout A4 (black wire)
- DC power supply GND to breakout terminal block GND (black wire)
- DC power supply positive to breakout terminal block V+ (red wire)
Python Installation of MCP230xx Library
You'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python. This may also require enabling I2C on your platform and verifying you are running Python 3. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!
Once that's done, from your command line run the following command:
pip3 install adafruit-circuitpython-mcp230xx
If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
CircuitPython Usage
To use with CircuitPython, you need to first install the Adafruit_CircuitPython_MCP230xx library, and its dependencies, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following folders:
- adafruit_bus_device/
- adafruit_mcp230xx/
Python Usage
Once you have the library pip3 installed on your computer, copy or download the following example to your computer, and run the following, replacing code.py with whatever you named the file:
python3 code.py
Example Code
If running CircuitPython: Once everything is saved to the CIRCUITPY drive, connect to the serial console to see the data printed out!
If running Python: The console output will appear wherever you are running Python.
# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import board
from adafruit_mcp230xx.mcp23017 import MCP23017
i2c = board.STEMMA_I2C()
mcp = MCP23017(i2c)
noid_1 = mcp.get_pin(0)
noid_2 = mcp.get_pin(4)
noid_1.switch_to_output(value=False)
noid_2.switch_to_output(value=False)
while True:
noid_1.value = True
print(f"Solenoid 1: {noid_1.value}, Solenoid 2: {noid_2.value}")
time.sleep(0.2)
noid_1.value = False
print(f"Solenoid 1: {noid_1.value}, Solenoid 2: {noid_2.value}")
time.sleep(0.2)
noid_2.value = True
print(f"Solenoid 1: {noid_1.value}, Solenoid 2: {noid_2.value}")
time.sleep(0.2)
noid_2.value = False
print(f"Solenoid 1: {noid_1.value}, Solenoid 2: {noid_2.value}")
time.sleep(1)
noid_1.value = True
noid_2.value = True
print(f"Solenoid 1: {noid_1.value}, Solenoid 2: {noid_2.value}")
time.sleep(1)
noid_1.value = False
noid_2.value = False
print(f"Solenoid 1: {noid_1.value}, Solenoid 2: {noid_2.value}")
time.sleep(2)
First, the MCP23017 is instantiated over I2C. Then, in the loop, the solenoid connected to pin A0 on the breakout is toggled, followed by the solenoid connected to pin A4. Both motors are then turned on and turned off together. You'll see your motors move and the corresponding LEDs on the breakout turn on and off.
Page last edited June 04, 2025
Text editor powered by tinymce.
Arduino
Using the 8 Channel Solenoid Driver with Arduino involves wiring up the breakout to your Arduino-compatible microcontroller, installing the Adafruit MCP23017 library and running the provided example code.
You'll need a solenoid motor, external DC power supply and a DC jack to terminal block adapter to follow this example.
Wiring
Wire as shown for a 5V board like an Uno. If you are using a 3V board, like an Adafruit Feather, wire the board's 3V pin to the breakout Vcc.
Here is an Adafruit Metro wired up to the breakout with two solenoid motors:
-
Board 5V to breakout Vcc (red wire)
-
Board GND to breakout GND (black wire)
-
Board SCL to breakout SCL (yellow wire)
- Board SDA to breakout SDA (blue wire)
- Motor 1 positive to breakout + (red wire)
- Motor 1 negative to breakout A0 (black wire)
- Motor 2 positive to breakout + (red wire)
- Motor 2 negative to breakout A4 (black wire)
- DC power supply GND to breakout terminal block GND (black wire)
- DC power supply positive to breakout terminal block V+ (red wire)
Library Installation
You can install the Adafruit_MCP23017 library for Arduino using the Library Manager in the Arduino IDE.
Click the Manage Libraries ... menu item, search for Adafruit MCP23017, and select the select the Adafruit MCP23017 Arduino Library library:
If asked about dependencies, click "Install all".
If the "Dependencies" window does not come up, then you already have the dependencies installed.
// SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <Adafruit_MCP23X17.h>
#define NOID_1 0 // MCP23XXX pin LED is attached to
#define NOID_2 4 // MCP23XXX pin LED is attached to
Adafruit_MCP23X17 mcp;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("8 Channel Solenoid Driver Demo");
if (!mcp.begin_I2C()) {
Serial.println("Couldn't find MCP23017..");
while (1);
}
mcp.pinMode(NOID_1, OUTPUT);
mcp.pinMode(NOID_2, OUTPUT);
Serial.println("Found MCP23017, looping...");
}
void loop() {
Serial.println("Solenoid 1!");
mcp.digitalWrite(NOID_1, HIGH);
delay(500);
mcp.digitalWrite(NOID_1, LOW);
delay(500);
Serial.println("Solenoid 2!");
mcp.digitalWrite(NOID_2, HIGH);
delay(500);
mcp.digitalWrite(NOID_2, LOW);
delay(500);
Serial.println("Together!");
mcp.digitalWrite(NOID_1, HIGH);
mcp.digitalWrite(NOID_2, HIGH);
delay(1000);
mcp.digitalWrite(NOID_1, LOW);
mcp.digitalWrite(NOID_2, LOW);
delay(2000);
Serial.println("Repeat!");
Serial.println();
delay(500);
}
Upload the sketch to your board and open up the Serial Monitor (Tools -> Serial Monitor) at 115200 baud. You'll see the breakout recognized over I2C. Then, in the loop, the solenoid connected to pin A0 on the breakout is toggled, followed by the solenoid connected to pin A4. Both motors are then turned on and turned off together. You'll see your motors move and the corresponding LEDs on the breakout turn on and off.
Page last edited June 04, 2025
Text editor powered by tinymce.
Downloads
Page last edited June 04, 2025
Text editor powered by tinymce.