Now I’m getting to grips with my Arduino I need to figure how to expand the 15 onboard PWM pins so that I can control more than 5 LEDs. I’m looking at being to assign LEDs for things like:
- 1 for the sun/moon
- 2 or 3 for ambient atmospheric sky lighting
- 3 for the shop windows on the left
- 3 for the shop windows on the right
- 1 for the window at the back
- Maybe an additional 1 for some magic spell explosions in one of the shops
I’ll double up one of the sky LEDs as a lightning effect and I’ll probably code things so that when then shops close, the shop window lights dim and flicker to suggest some evening candle light.
This list alone gives me in excess of 10 LEDs that will need connecting to the Arduino so I’m going to have to use the shift registers to expand things a little.
I won’t go into a huge amount of details on how to do this as there’s some great tutorials online already. I recommend this one from Element14:
I’m also using an Arduino library to handle most of the communication with the shift registers. There’s a few to choose from but I’ve gone with ShiftPWM by Elco Jacobs – https://github.com/elcojacobs/ShiftPWM
I got my breadboard wired up as the video above explains (and also used the diagram at https://www.pjrc.com/teensy/td_libs_ShiftPWM.html for help) and I opened up the example non-blocking code that came with the library. This was great at giving me a chance to explore what could be done. I won’t be using these examples exactly as they are but I’ll use them as a reference point.
Before I go any further I’ll just summarise how I wired my LEDs into things. On my breadboard I’m using 2 shift registers (I’ll probably use more in my finished design but that’s enough for now). Each shift register has 8 output pins (15, 1, 2, 3, 4, 5, 6, and 7). This is how I have them wired up:
Shift register / pin # | LED leg |
SR1 pin 15 | LED1 R |
SR1 pin 1 | LED1 G |
SR1 pin 2 | LED1 B |
SR1 pin 3 | LED2 R |
SR1 pin 4 | LED2 G |
SR1 pin 5 | LED2 B |
SR1 pin 6 | LED3 R |
SR1 pin 7 | LED3 G |
SR2 pin 15 | LED3 B |
SR2 pin 1 | LED4 R |
SR2 pin 2 | LED4 G |
SR2 pin 3 | LED4 B |
SR2 pin 4 | LED5 R |
SR2 pin 5 | LED5 G |
SR2 pin 6 | LED5 B |
SR2 pin 7 | No connection |
You should note that the library supports SPI (Serial Peripheral Interface) for passing data to the registers. This means that with the Arduino I’ve picked I can actually run all of my shift registers from just 1 PWM pin.
// Clock and data pins are pins from the hardware SPI, you cannot choose them yourself.
// Data pin is MOSI (Uno and earlier: 11, Leonardo: ICSP 4, Mega: 51, Teensy 2.0: 2, Teensy 2.0++: 22)
// Clock pin is SCK (Uno and earlier: 13, Leonardo: ICSP 3, Mega: 52, Teensy 2.0: 1, Teensy 2.0++: 21)
const int ShiftPWM_latchPin=8;
There’s instructions for this in the code but essentially you can connect your data pin to pin to pin 51 on the Arduino, the clock pin to pin 52 on the Arduino and then I can use PWM pin 8 as my latch pin.
I played about with the example code and used the serial monitor under “Tools > Serial Monitor” to change the mode of the program. One thing I did notice was that for things to fully work I had to include the SPI library in the example too.
#include <SPI.h>
#include <ShiftPWM.h>
I tweaked the variable that defines the number of shift registers you’ve got connected (remember you can daisy chain them) so that the code knows how many LEDs you’ve got connected.
// Set some core properties
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
unsigned int numRegisters = 2;
unsigned int numOutputs = numRegisters * 8;
unsigned int numRGBLeds = numRegisters * 8 / 3;
That’s it – I was up and running and ready to start coding!
Next up
Next we’ll get into the fun stuff. I’m going to start by figuring out how to structure things for a simple day/night cycle. I’ll look at adding loads of configurable options for things like timing, time-spans and colours and I’ll add in a third stage into the cycle so I can have a nice late-afternoon sunset as well as night and day.