This week Bob is back and talk about how to control one and many relays with an Arduino. Also, an update on the live light project.
Downloads
Arduino pre-programmed with standard blink sketch controlling a lamp.
Notes: This 5V general purpose relay needs 450mA (page 3, line 8) to power the coil, which is at the limit of what an Arduino is spec’d at. This Uno will only work reliably if its powered with a power supply. A USB works most of the time, but is unreliable. Its not in the demo, but I did have my multimeter on this setup and it was drawing 440 to 445 mA. The Leonardo I have would NOT power this relay, even with an external power supply.
Wiki for Relay: http://en.wikipedia.org/wiki/Relay
Relay used: http://www.mouser.com/ProductDetail/TE-Connectivity-OEG/OJE-SH-105DM095/?qs=sGAEpiMZZMs8I5ltipPMAJsrp7dpEY83
Datasheet: http://www.mouser.com/ds/2/418/NG_DS_OJ_OJE_series_relay_data_sheet_E_0412-124865.pdf
In the Arduino IDE, this is under Examples/Basics/Blink
Sample Code
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Arduino pre-programmed with Shiftregister code controlling a lamp and using a LM317 to deliver 5V.
Notes: Standard shift register code pre-loaded on Arduino. The demo has a LM317 because an Arduino could not power this board, with 300 ohm resistor in the R1 position and 3-300 ohm resistors in series for a total of 900 ohm in the R2 position. Two .1 uF capacitors are used to smooth the supply. This setup also uses the 5V VIN pin on the Arduino. This can be dangerous since supplying an Arduino like this is an unregulated supply and NOT recommended, however, shows how to power an entire circuit When tested, before connecting anything, the LM317 was delivering 5.02V according to the multimeter (not in demo).
The relay board will show the red LED when the relay is OFF. However, when unpowered, the circuit is live.
Relay board: SainSmart 8 channel relay board
Shift Register used: http://www.ti.com/lit/ds/symlink/sn74hc595.pdf
LM317 datasheet: http://www.ti.com/lit/ds/symlink/lm317.pdf
Graphic showing setup: http://4.bp.blogspot.com/-7EY0uW0OE2g/TcDxgE7hzAI/AAAAAAAAAKo/NHRMUA7h_vc/s1600/lm317.gif
Arduino Spec page – See 5V comment in the Power section:
http://arduino.cc/en/Main/arduinoBoardUno
Sample Code:
/**************************************************************
Name ShiftRegister_nleds_1
Author Bob Powell
texanfromiowa@gmail.com
Copyright (C) 2012-2013, Parallelus Automation, Inc.
Date Apr 2, 2013
Modified Apr 2, 2013
Version 1.0.0
Arduino 1.0.4
Notes Example for using "n" number of 74HC595 Shift Registers and LEDs.
Various test functions included for fun. Functions are written
for maximum flexibility, so everything is a variable.
This means that the code that calls the function, sets the
values of the variables which allows for the same function
to have an infinite number of variations.
This program is heavily commented to explain a number
of concepts. PLEASE READ!!!
In this version of the software, I switched to the Shifter (link below)
library for maximum flexibility in both the number of LEDs
and the number of shift registers. There is a little more
logic involved, but the added functionality is more than
worth it. It does seem to have been written with a 74HC595
in mind, so you may need to modify the code if other register
types are used.
Essentially, there are two steps to turn on and off leds.
First, use the LED[] array to set a given led on or off.
Second, use the writeBytes() function to send the array to
the shift registers. If you want the array reversed,
then use the writeBytesRev() function.
At a number of points in the code, you will see variations
of this: 1<<i This is bit shifting. If you want a full
explanation, go here: http://en.wikipedia.org/wiki/Logical_shift
The bit shifting is used because of the inherent problems
with floating point numbers. The preferred method for
calculating an exponent would be, for example, to use:
pow(2,3) which would equal 8 (the number 2, cubed (2^3))
Unfortunately, the function returns a float which may not
be exactly 8 (ie. 7.998761234). Using C casting to force an
integer would set this to a 7, which is unacceptable.
Rather than write code to fix this, bit shifting was used, which
ALWAYS gives you an integer, which is what we want anyway.
Legal Stuff:
============
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
at your option, any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Personal note:
==============
If you do something interesting with this code, expand it, or just
have a question, please email me at the address above.
I hope you find this example helpful. Enjoy.
Bob
****************************************************************/
// Switched to the Shifter library. This allows for "n" number
// shift registers to be used without significant changes to the
// code. For help in adding libraries to the Arduino IDE, go here:
// http://www.arduino.cc/en/Hacking/Libraries
// This library was obtained from: http://bildr.org/2011/08/74hc595-breakout-arduino/
//
// The short version of installing a library it to, first, download the library
// (link above). They usually download as a zip file, so unzip the file which
// will usually create a directory of the libraries contents. Third, put this
// directory into the "libraries" directory of your Arduino IDE (Integrated
// Design Enviroment) software. In a typical Windows installation, the Arduino
// IDE executable file is located at: c:\Program Files\Arduino\Arduino.exe
// There is a directory called: c:\Program Files\Arduino\libraries
// The Shifter\ directory will go into this libraries directory.
// For a Mac, this directory is typically located at:
// /Applications/Arduino.app/Contents/Resources/Java/libraries
// If you have trouble, see the link above for complete instruction from Arduino
// You will need to restart the Arduino IDE for it to realize that this
// library is present. Once you have installed the library and restarted the
// IDE, this line tells the compilier to include it:
#include <Shifter.h>
// THESE VARIABLES CHANGE.
// Set the number of leds your using and the number of shift registers used.
// The Shifter library assumes one register = 8 bits. With this in mind,
// NUM_LED can never be greater that NUM_REG x 8 bits.
const int NUM_LED = 16; // number of leds
const int NUM_REG = 2; // number of shift registers
// Set variables - Global variables, except for the Arduino
// pins, are CAPITALIZED. This makes identification of local and
// global variables easy to understand. The compilier is case sensitive
// so it understands capitalized and lower case letters.
// These variables are too make things a little easier for humans to read.
// The "const" sets the variable so it cannot be changed
// later in the program (ie. make them constants). The standard
// constants "true" and "false" function just as well as these.
const bool OFF = 0;
const bool ON = 1;
// In this example, this chip is used: http://www.ti.com/lit/ds/symlink/sn74hc595.pdf
// (Since I worked for TI for almost a decade, I'm fond of their products. Plus, the
// quality can't be beat.)
// The names below match those in the datasheet, but can change from one datasheet to
// another depending on the manufacturer. The function of each pin remain the same.
// Pin connected to RCLK, pin 12, of ALL the 74HC595s
// ===
const int latchPin = 10;
// Pin connected to SRCLK, pin 11, of ALL the 74HC595s
// ===
const int clockPin = 11;
// Pin connected to SER, pin 14, of the FIRST 74HC595s
// =====
// All of the serial data will be going to this SER (data in)
// pin to all the register(s) you have connected.
const int dataPin = 12;
/* The rest of the 74HC595 pins and setup:
To daisy chain registers, pin 9, data out, of the first register connects
to pin 14, data in, of the second register, then pin 9, data out of the second
register connects to pin 14, data in, of the third register, etc. etc. This
code will support more registers than can be physically connected without
circuit modifications. Data in for all the registers is the dataPin
variable set above.
Also, you must tie ALL the latch and clock pin for ALL registers
together. When the Arduino sets the latchPin and clockPin variables
(created above) HIGH or LOW, it must set ALL latch and clock pins
HIGH and LOW TOGETHER!!! If this is not done, the chain of registers
will not work.
For each register used, don't forget to connect ALL registers as
show here:
Connect SRCLR (master reset), pin 10, to 5V. In this example,
the chip will not be reset and must always be set HIGH for the chip
to function. Setting this pin LOW resets the register.
Connect OE (output enable), pin 13, to GRD (LOW).
In this example, we are not using the 74HC595 for any
data input, so we never switch this pin from HIGH
to LOW, to switch if from inputing data to outputing
data, repestively.
One more, somewhat obvious detail, connect pin 15, Qa, to your first
led, pin 1, Qb, to the second led, pin 2, Qc, to your third led, and
so on. The 8th led will be connected to pin 7, Qh.
Again, see the datasheet for details.
*/
// Set up the shifter object used to send data to the registers.
Shifter shifter(dataPin, latchPin, clockPin, NUM_REG);
// Set up the array of leds that is used throughout the program
bool LED[NUM_LED];
/**************************************************************
Function: setup
Purpose: set up Arduino
Args: none
Returns: nothing
Notes: This function is required by the Arduino
***************************************************************/
void setup() {
// Set up the output pins.
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// Set up the shifter output
shifter.clear();
shifter.write();
// turn off all the LEDS, just in case
allOff();
writeBytes();
// This is needed for the randomLeds() function below,
// along with any other code that uses a random number
// and removed if random numbers are not used.
// Quoted from http://arduino.cc/en/Reference/random -
// if analog input pin 0 is unconnected, random analog
// noise will cause the call to randomSeed() to generate
// different seed numbers each time the sketch runs.
// randomSeed() will then shuffle the random function.
//
// In other words, set this to any analog pin that is
// not used.
randomSeed(analogRead(0));
} // End of Arduino Setup
/**************************************************************
Function: loop
Purpose: loop funtion for Arduino
Args: none
Returns: nothing
Notes: This function is required by the Arduino, and the
Arduino will loop through this function indefinately.
***************************************************************/
void loop() {
/***** See detailed descriptions for each funcion below *****/
//
// Most of these functions follow the same basic principle.
// A duration is selected for how long each led should be on,
// a repeat count is selected, and how many leds are to be on
// at once is selected.
// For example, flashAll(500, 3) tells the function to turn on
// all leds for 1/2 a second, then off 1/2 a second. The do this
// 3 times.
// The chase function is similiar. Below chase(100, 2, 3, false)
// is used. In this case, we tell the chase function to keep each
// led on for .1 seconds, have the chase sequence have 2 leds on at
// a time, to repeat the sequence 3 times, and selects the reverse
// option, in this case false. Using true would just have the
// effect go in reverse.
// Again:
/***** See detailed descriptions for each funcion below *****/
// Set a standard delay between each effect
int loopDelay = 2000;
// Flash all leds, to let us know its on
flashAll(500, 3);
delay(loopDelay);
// Meter effect
for(int i = 0; i < 6; i++){
int randomnum = random(NUM_LED);
meter(50, randomnum, false);
}
delay(loopDelay);
// Meter effect in reverse
for(int i = 0; i < 6; i++){
int randomnum = random(NUM_LED);
meter(50, randomnum, true);
}
delay(loopDelay);
// The Knight Rider effect
knightRider(50, 5, 3);
delay(loopDelay);
// Busted effect
busted(50, 10, 3);
delay(loopDelay);
// Flash odd only, then even only leds
flashOdd(250, 2);
flashEven(250, 2);
delay(loopDelay);
// Marque effect
marque(150, 10);
delay(loopDelay);
// criss-cross effect
crissCross(100, 5);
delay(loopDelay);
// Randomly turn on and off leds
// Reminds me of Christmas lights...
randomLeds(250,50);
delay(loopDelay);
// Chase effect
chase(100, 3, 3, false);
delay(loopDelay);
// Chase effect in reverse
// Note that the only differnce is the "true"
chase(100, 3, 3, true);
delay(loopDelay);
// Flash again
flashAll(500, 2);
delay(2000);
// Count up from a number to another -- in binary!!
countUp(0, 100, 50, false);
delay(loopDelay);
// count up again, but in reverse
countUp(0, 64, 100, true);
delay(loopDelay);
// count down from a number to another
countDown(128, 0, 50, true);
delay(loopDelay);
// Flash one last time
flashAll(1000, 1);
// One last longer delay, then the loop will start again indefinately
delay(loopDelay);
delay(loopDelay);
} // End of Arduino Loop
/**************************************************************
Function: flashAll
Purpose: Flashes all leds
Args: int duration - how long an led is on
int count - how many times to flash
Returns: nothing
Notes:
***************************************************************/
void flashAll(int duration, int count)
{
for(int i = 0; i < count; i++)
{
allOn();
writeBytes();
delay(duration);
allOff();
writeBytes();
delay(duration);
}
}
/**************************************************************
Function: flashOdd
Purpose: Flashes odd leds
Args: int duration - how long an led is on
int count - how many times to flash
Returns: nothing
Notes:
***************************************************************/
void flashOdd(int duration, int count)
{
allOff();
for(int i = 0; i < count; i++)
{
oddOn();
writeBytes();
delay(duration);
allOff();
writeBytes();
delay(duration);
}
}
/**************************************************************
Function: flashEven
Purpose: Flashes even leds
Args: int duration - how long an led is on
int count - how many times to flash
Returns: nothing
Notes:
***************************************************************/
void flashEven(int duration, int count)
{
allOff();
for(int i = 0; i < count; i++)
{
evenOn();
writeBytes();
delay(duration);
allOff();
writeBytes();
delay(duration);
}
}
/**************************************************************
Function: busted
Purpose: You just got pulled over
Args: int duration - how long an led is on
int count - how many times to repeat
int sidecount - how many times to flash each side
Returns: nothing
Notes:
***************************************************************/
void busted(int duration, int count, int sidecount)
{
int half = ceil(NUM_LED/2);
for(int i = 0; i < count; i++)
{
for(int j = 0; j < sidecount; j++)
{
for(int k = 0; k < half; k++)
LED[k] = ON;
writeBytes();
delay(duration);
allOff();
writeBytes();
delay(duration);
}
delay(duration);
for(int j = 0; j < sidecount; j++)
{
for(int k = NUM_LED - 1; k >= half; k--)
LED[k] = ON;
writeBytes();
delay(duration);
allOff();
writeBytes();
delay(duration);
}
delay(duration);
}
}
/**************************************************************
Function: crissCross
Purpose: Criss-Cross effect
Args: int duration - how long an led is on
int count - how many times to cycle through effect
Returns: nothing
Notes:
***************************************************************/
void crissCross(int duration, int count)
{
// Clear the array and turns off any leds still on
allOff();
writeBytes();
// Create variables
int firstled;
int lastled;
for(int i = 0; i < count; i++)
{
for(int j = 0; j < NUM_LED; j++)
{
// if its the start of a loop through the leds,
// reset the variables to their starting position.
if(j == 0){
firstled = 0;
lastled = NUM_LED -1;
}
LED[firstled] = ON;
LED[lastled] = ON;
writeBytes();
// Skip the delay if the center leds are crossing
// or if the leds have reached the ends.
// This code was changed to be human readable and
// is not the most effecient.
if(lastled == (firstled +1)){}
// do nothing - skip delay
else if (lastled == 0){}
// do nothing - skip delay
else
delay(duration);
// Turn off the last leds we just turned on
LED[firstled] = OFF;
LED[lastled] = OFF;
// increment variables
firstled++;
lastled--;
}
}
// turn the last leds off
delay(duration);
allOff();
writeBytes();
}
/**************************************************************
Function: randomLeds
Purpose: Randomly turn on and off leds
Args: int duration - time between random number generations
int count - number of cycles through the loop
Returns: nothing
Notes:
***************************************************************/
void randomLeds(int duration, int count)
{
// Clear the array and turns off any leds still on
allOff();
writeBytes();
// Create variables
int randomnum;
for(int i = 0; i < count; i++)
{
randomnum = random(NUM_LED);
if(LED[randomnum] == ON)
{
LED[randomnum] = OFF;
writeBytes();
}
else
{
LED[randomnum] = ON;
writeBytes();
}
delay(duration);
}
// Randomly turn off any remaining leds
while(sumArray(LED) > 0)
{
randomnum = random(NUM_LED);
LED[randomnum] = OFF;
writeBytes();
delay(duration);
}
// turn the last leds off
allOff();
writeBytes();
}
/**************************************************************
Function: marque
Purpose: Marque effect
Args: int duration - how long an led is on
int count - how many times to cycle through effect
Returns: nothing
Notes: This funtion is flashing the odd leds, then
flashing even leds to create the marque effect.
**************************************************************/
void marque(int duration, int count)
{
// Clear the array and turns off any leds still on
allOff();
writeBytes();
for(int i = 0; i < count; i++)
{
oddOn();
writeBytes();
//writeBits(ODDLEDS);
delay(duration);
allOff();
evenOn();
writeBytes();
// writeBits(EVENLEDS);
delay(duration);
allOff();
}
// Turn off when finished
allOff();
writeBytes();
}
/**************************************************************
Function: chase
Purpose: Chase effect
Args: int duration - how long an led is on
int count - how many times to cycle through effect
int numleds - how many leds are on at a time
bool reverse - true or false - a value of true
- reverses the normal direction
Returns: nothing
Notes:
**************************************************************/
void chase(int duration, int count, int numleds, bool reverse)
{
// Clear the array and turns off any leds still on
allOff();
writeBytes();
duration = duration / numleds;
int trailingleds = numleds - 1;
int ledcounter = NUM_LED + trailingleds;
for(int i = 0; i < count; i++)
{
for(int j = 0; j < ledcounter; j++)
{
LED[j] = ON;
if (reverse == true)
writeBytesRev();
else
writeBytes();
delay(duration);
LED[j + 1] = ON;
LED[j - trailingleds] = OFF;
}
}
// turn off the last led
allOff();
writeBytes();
}
/**************************************************************
Function: meter
Purpose: Meter effect
Args: int duration - how long an led is on
int num - how many times to cycle through effect
bool reverse - true or false - a value of true
- reverses the normal direction
Returns: nothing
Notes:
**************************************************************/
void meter(int duration, int num, bool reverse)
{
// Clear the array and turns off any leds still on
allOff();
writeBytes();
// if the number is greater than the number of leds, then return
if(num > NUM_LED)
return;
// turn on the leds
for(int i = 0; i < num; i++)
{
LED[i] = ON;
if (reverse == true)
writeBytesRev();
else
writeBytes();
delay(duration);
}
// turn off the leds
for(int i = num; i > 0; i--)
{
LED[i] = OFF;
if (reverse == true)
writeBytesRev();
else
writeBytes();
delay(duration);
}
// turn off the last led
allOff();
writeBytes();
}
/**************************************************************
Function: knightRider
Purpose: "Knight Rider" effect from the TV show
Args: int duration - how long an led is on
int count - how many times to cycle through effect
int numleds - how many leds are on at a time
Returns: nothing
Notes: This is not a perfect implementaion of the effect.
A perfect effect would include a dimming of the
trainling leds (using PWM). Its still cool!
**************************************************************/
void knightRider(int duration, int count, int numleds)
{
// Clear the array and turns off any leds still on
allOff();
writeBytes();
duration = duration / numleds;
int trailingleds = numleds - 1;
int ledcounter = NUM_LED + trailingleds;
for(int i = 0; i < count; i++)
{
// cycle through one direction
for(int j = 0; j < ledcounter -1 ; j++)
{
LED[j] = ON;
writeBytes();
delay(duration);
LED[j + 1] = ON;
LED[j - trailingleds] = OFF;
writeBytes();
// Skip the extra delay() commands as the
// trailing leds catch up.
if(j < NUM_LED)
delay(duration);
}
// cycle back in the oppisite direction
for(int j = ledcounter; j > -trailingleds; j--)
{
LED[j] = ON;
writeBytes();
// Skip the initial delay() commands as the
// trailing leds start back.
if(j < NUM_LED -1)
delay(duration);
LED[j - 1] = ON;
LED[j + trailingleds] = OFF;
writeBytes();
delay(duration);
}
}
// Turn the last led off
allOff();
writeBytes();
}
/**************************************************************
Function: countUp
Purpose: Count up, in binary, from one number to another
Args: int duration - how long an led is on
int startNum - starting number
int endNum - ending number
bool reverse - true or false - a value of true
- reverses the normal direction
Returns: nothing
Notes:
**************************************************************/
void countUp(int startNum, int endNum, int duration, bool reverse)
{
// Clear the array and turns off any leds still on
allOff();
if((endNum <= startNum) || (endNum < 0))
return;
for (int numberToDisplay = startNum; numberToDisplay <= endNum; numberToDisplay++) {
setArray(numberToDisplay);
if(reverse == true){
writeBytesRev();
}
else{
writeBytes();
}
delay(duration);
}
allOff();
writeBytes();
}
/**************************************************************
Function: countDown
Purpose: Count down, in binary, from one number to another
Args: int duration - how long an led is on
int startNum - starting number
int endNum - ending number
bool reverse - true or false - a value of true
- reverses the normal direction
Returns: nothing
Notes:
**************************************************************/
void countDown(int startNum, int endNum, int duration, bool reverse)
{
// Clear the array and turns off any leds still on
allOff();
if(endNum >= startNum)
return;
for (int numberToDisplay = startNum; numberToDisplay > endNum; numberToDisplay--) {
setArray(numberToDisplay);
if(reverse == true)
writeBytesRev();
else
writeBytes();
delay(duration);
}
// turn off the last led
allOff();
writeBytes();
}
/**************************************************************
Function: sumArray
Purpose: Take a binary representation of the array of ON and OFF
positions, and generates an integer.
Args: int array[]
Returns: integer of the total
Notes: See comments on bit shifting at the beginning
of this file.
**************************************************************/
int sumArray(bool array[])
{
int total = 0;
for (int i = 0; i < NUM_LED; i++)
{
if (array[i] == ON)
total = total + (1<<i);
}
return(total);
}
/**************************************************************
Function: setArray
Purpose: Sets the primary array to the binary of the number
given.
Args: int num - number to put into array
Returns: nothing
Notes: See comments on bit shifting at the beginning
of this file. Since this is an integer, it must be
between -32,768 and 32,767, HOWEVER, it should
always be a positive number (0 to 32,767).
**************************************************************/
void setArray(int num)
{
// Clear the array
allOff();
int i = 0;
bool value;
while (num > 0)
{
value = num & 1;
if(value == true)
LED[i] = ON;
else
LED[i] = OFF;
num >>= 1;
i++;
}
}
/**************************************************************
Function: evenOn
Purpose: Turns ON even leds
Args: none
Returns: none
Notes:
**************************************************************/
void evenOn()
{
for (int i = 1; i < NUM_LED; i += 2)
{
LED[i] = ON;
}
}
/**************************************************************
Function: oddOn
Purpose: Turns ON even leds
Args: none
Returns: none
Notes:
**************************************************************/
void oddOn()
{
for (int i = 0; i < NUM_LED; i += 2)
{
LED[i] = ON;
}
}
/**************************************************************
Function: allOn
Purpose: Turns ON all leds
Args: none
Returns: none
Notes:
**************************************************************/
void allOn()
{
for (int i = 0; i < NUM_LED; i++)
{
LED[i] = ON;
}
}
/**************************************************************
Function: allOff
Purpose: Turns OFF all leds
Args: none
Returns: none
Notes:
**************************************************************/
void allOff()
{
for (int i = 0; i < NUM_LED; i++)
{
LED[i] = OFF;
}
}
/**************************************************************
Function: writeBits
Purpose: Write the array with Most Significant Bit first (MSFBFIRST)
Args: none
Returns: nothing
Notes: This function is a wrapper function for outBytes()
***************************************************************/
void writeBytes()
{
outBytes(MSBFIRST);
}
/**************************************************************
Function: writeBytesRev
Purpose: Write the array with Least Significant Bit first (MSFBFIRST)
Args: none
Returns: nothing
Notes: This function is a wrapper function for outBytes()
***************************************************************/
void writeBytesRev()
{
outBytes(LSBFIRST);
}
/**************************************************************
Function: outBytes
Purpose: Send array data to shift register
Args: int dir - First or Least significant bit first
Returns: nothing
Notes: This is where data is actually sent out, but is not
intended to be used directly. writeBytes() and
writeBytesRev() should be used instead.
***************************************************************/
void outBytes(int dir)
{
// set latch pin low so data can be sent
digitalWrite(latchPin, LOW);
// Clears previous data
shifter.clear();
// Set each pin according to what LED[] currently has.
// most significant bit first
if(dir == MSBFIRST)
{
for(int i = 0; i < sizeof(LED);i++)
{
if(LED[i] == ON)
shifter.setPin(i, HIGH);
else
shifter.setPin(i, LOW);
}
}
// least significant bit first - reverses what is in LED[]
else if(dir == LSBFIRST)
{
int j = 0;
for(int i = sizeof(LED) - 1; i > -1;i--)
{
if(LED[i] == ON){
shifter.setPin(j, HIGH);
}
else{
shifter.setPin(j, LOW);
}
j++;
}
}
// Write the data to the registers
shifter.write();
// set the latch high to turn on the output
digitalWrite(latchPin, HIGH);
}
// End of program