A simple Arduino library for controlling any length of chained 595 style serial to parallel shift registers over the built in SPI bus.
SpiShiftRegisterChain
enables you to manage a chain of 595-style shift registers. Utilizing the hardware SPI bus, this library allows you to control large numbers of shift registers connected in series with high performance, making it ideal for projects requiring a high number of digital outputs.
SpiShiftRegisterChain
objectslibraries
directory (usually located at Documents/Arduino/libraries
).SpiShiftRegisterChain
appears in the list.To begin using the SpiShiftRegisterChain
library after installing it, include it in your sketch and create an instance of SpiShiftRegisterChain
with the appropriate parameters. This object will be used to manage the chain:
#include <SPI.h>
#include <SpiShiftRegisterChain.h>
// Define latch pin and number of bytes for shift register chain
const int latchPin = 10;
const int dataLengthBytes = 4; // Example: 4 bytes for 32 output bits (4 * 8)
SpiShiftRegisterChain shiftRegister(latchPin, dataLengthBytes);
void setup() {
SPI.begin();
}
The entire shift register chain is treated as one large shift register with bits numbered from 0
to n-1
for a register chain with n
total output bits. Each bit is addressed by its zero indexed number no matter which physical register it lies on.
When setting the number of bytes it does not matter what your physical configuration is, only how many outputs it has. For example, 3 8-bit registers would be handled the same as 2 12-bit registers since both have 24 bits or 3 bytes.
Before using the shift register you must call SPI.begin()
or the SPI bus will not be initialized for the registers. This is typically done in setup()
, as above, but can be done anywhere as required.
Setting Individual Bits On/Off:
The library keeps an internal representation of the data which you manipulate before writing it out to the hardware. By default, data is written immediately when you call a data function such as setBitOn()
. If you want to batch changes, set the second parameter of the data function to false
. Then, later, call writeData()
manually when you're ready to apply the changes to the hardware. This allows you to change any number of bits at exactly the same time.
shiftRegister.setBitOn(3); // Turns on bit 3 and writes the data to the hardware
shiftRegister.setBitOff(4, false); // Turns off bit 4 internally but does not write out to the hardware
shiftRegister.setBitOn(8, false); // Turns on bit 8 internally but does not write out to the hardware
shiftRegister.toggleBit(6, false); // Toggles bit 6 internally but does not write out to the hardware
shiftRegister.writeData(); // Now, manually apply the internal changes to the hardware, in this case to bits 4, 8, and 6
Also note that any internal changes will be written on the next write even if it not from a call to writeData()
. So the following are equivalent:
//example 1: call writeData()
shiftRegister.setBitOn(8, false);
shiftRegister.toggleBit(6, false);
shiftRegister.writeData();
//example 2: implicit write
shiftRegister.setBitOn(8, false);
shiftRegister.toggleBit(6);
Toggling a Bit:
Toggling will change a bit's state from false to true or true to false as required. The toggle function works the same way as the on/ off functions, automatically writing data unless false
is specified as the second parameter.
shiftRegister.toggleBit(3); // Toggles the state of the 4th bit and writes the data
Writing Data to All Shift Registers:
Since writing happens by default, use writeData()
if you've opted to delay writing data for any changes by setting the write parameter to false
.
shiftRegister.writeData(); // Manually applies any batched internal changes
Here’s a full example demonstrating how to set up the SpiShiftRegisterChain
library and control individual bits:
#include <SPI.h>
#include <SpiShiftRegisterChain.h>
const int latchPin = 10;
const int dataLengthBytes = 4;
SpiShiftRegisterChain shiftRegister(latchPin, dataLengthBytes);
void setup() {
SPI.begin();
shiftRegister.setBitOn(0); // Turn on the 1st bit and write data
shiftRegister.setBitOff(1, false); // Turn off the 2nd bit without writing
shiftRegister.writeData(); // Apply all changes at once
delay(1000);
shiftRegister.toggleBit(0); // Toggle the 1st bit and write data
delay(1000);
}
void loop() {
// Your main code here
}
To use SpiShiftRegisterChain
, connect your Arduino's SPI and control pins to the 595 shift registers as follows:
latchPin
from the Arduino (defined in your code) to the Latch pin on the first shift register (usually labeled ST_CP or RCLK). You may set latchPin
to any Arduino pin. You may also create multiple instances of SpiShiftRegisterChain
with different latch pins to control independent chains.For each additional shift register in the chain:
SpiShiftRegisterChain(unsigned int latchPin, unsigned int dataLengthBytes, unsigned long maxClockSpeed = 4000000);
latchPin
: The digital pin used to tell the shift register new data is coming.dataLengthBytes
: The number of bytes (8-bit groups) in the shift register chain.maxClockSpeed
: Optional. Sets the maximum SPI clock speed (default is 4 MHz).~SpiShiftRegisterChain()
This project is licensed under the Unlicense - see the license file for details.
Contributions are welcome! Please fork this repository and submit a pull request with your improvements. For major changes, please open an issue first to discuss what you would like to change.