-
Tested outputting to lots of LEDs via shift registers
09/27/2022 at 19:29 • 2 commentsI wanted to figure out the best way to run many LEDs quickly without using loads of IO pins. Here I tested using shift registers. I tried two methods, shiftOut() and SPI. I ran a test setting 16bits and recorded the time. Results:
- shiftOut() = 204 μs
- SPI = 16 μs
Clearly SPI is much faster. Below are both methods.
SPI Schematic:
SPI test code:
#include <SPI.h> //int pll_d=11; //piedino data //int pll_c=13; //piedino clock int pll_l=10; //piedino latch #define DATAOUT 11//MOSI #define DATAIN 12//MISO #define SPICLOCK 13//SCK int timer = 0; uint16_t ledNumbers[17] = { 0b0000000000000000, 0b1000000000000000, 0b0100000000000000, 0b0010000000000000, 0b0001000000000000, 0b0000100000000000, 0b0000010000000000, 0b0000001000000000, 0b0000000100000000, 0b0000000010000000, 0b0000000001000000, 0b0000000000100000, 0b0000000000010000, 0b0000000000001000, 0b0000000000000100, 0b0000000000000010, 0b0000000000000001}; void setup () { pinMode(DATAOUT, OUTPUT); pinMode(DATAIN, INPUT); pinMode(SPICLOCK,OUTPUT); pinMode(pll_l, OUTPUT); SPI.begin(); Serial.begin(9600); SPI.setDataMode(SPI_MODE0); SPI.setBitOrder(LSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV2); timer = micros(); digitalWrite(pll_l,LOW); SPI.transfer(ledNumbers[0]); SPI.transfer(ledNumbers[0] >> 8); digitalWrite(pll_l,HIGH); timer = micros() - timer; Serial.println(timer); } void loop() { // put your main code here, to run repeatedly: for(int x = 0; x < 16; x++){ turnOn(ledNumbers[x + 1]); delay(500); } } void turnOn(uint16_t bitNum){ digitalWrite(pll_l,LOW); SPI.transfer(bitNum); SPI.transfer(bitNum >> 8); digitalWrite(pll_l,HIGH); }
shiftOut() Schematic:
shiftOut() Code:
int DS_pin = 11; int STCP_pin = 12; int SHCP_pin = 8; uint16_t ledOutput = 0; uint16_t ledNumbers[17] = { 0b0000000000000000, 0b1000000000000000, 0b0100000000000000, 0b0010000000000000, 0b0001000000000000, 0b0000100000000000, 0b0000010000000000, 0b0000001000000000, 0b0000000100000000, 0b0000000010000000, 0b0000000001000000, 0b0000000000100000, 0b0000000000010000, 0b0000000000001000, 0b0000000000000100, 0b0000000000000010, 0b0000000000000001}; void setup() { Serial.begin(115200); pinMode(DS_pin,OUTPUT); pinMode(STCP_pin,OUTPUT); pinMode(SHCP_pin,OUTPUT); turnOn(4); delay(500); turnOn(8); delay(500); turnOn(12); delay(500); turnOn(16); delay(500); turnOff(4); delay(500); turnOff(8); delay(500); turnOff(12); delay(500); turnOff(16); } void loop() { } void turnOn(int bitNum) { ledOutput |= ledNumbers[bitNum]; digitalWrite(SHCP_pin, LOW); shiftOut(DS_pin, STCP_pin, LSBFIRST, ledOutput); shiftOut(DS_pin, STCP_pin, LSBFIRST, ledOutput >> 8); digitalWrite(SHCP_pin, HIGH); } void turnOff(int bitNum) { ledOutput &= ~ledNumbers[bitNum]; digitalWrite(SHCP_pin, LOW); shiftOut(DS_pin, STCP_pin, LSBFIRST, ledOutput); shiftOut(DS_pin, STCP_pin, LSBFIRST, ledOutput >> 8); digitalWrite(SHCP_pin, HIGH); }