Monday, January 26, 2015

Shift Registers Have Class

Have been working on adapting my standard pin functions to work with a shift register.  First worked on a class for the shift registers.

First step was declaring the basics; bytes for my clock, latch, and data pins, and an int to declare the total number of pins used on the shift register.  Next big concern was tracking the state of each of the eight pins; as the state can only be off or on, this was done with a simple array of booleans. As I would like to incorporate 24 total LED's into the project, so I added two extra arrays to keep track of the two additional shift registers I will have daisy chained to the first.  Next created a constant, static array of bytes to represent each of the pins values (from B1 to B10000000, or 1 to 255 in decimal.)  We want it static because these values can be shared among all shift registers, and we want it constant because binary math should never change within the scope of this program.

As the array of pins matches up with the array of pin values (pin 0 is 1, pin 2 is 01 etc,) all we have to do to activate a pin is pass an int to the void ActivatePin, which sets the appropriate boolean to true.  To get a value for our ShiftOut function, all we have to do now is add up the values for each pin that is set to true - these are stored in an array of 3 bytes; one to hold the value for each shift register we intend to use.

All that remained was to add a few maintenance functions; ShiftClear() to clear the shift register values and ClearPins() to clear the boolean value of each of the pins.  Also added a RandomPin() function to allow it to output a random pin.
Header and cpp file to follow.




ShiftRegister.h
#ifndef LED_h
#define LED_h
#include <Arduino.h>
#include <WProgram.h>

/*
  ShiftRegister.h - Library for standard and RGB LED's
  Beau Bureau, 2014
  Released into the public domain.
*/

class ShiftRegister{
private:
// Gets the binary equivalent of a given pin
int ReturnPin(int);
// sets the clock and data pins
byte clockPin,latchPin,dataPin;
// sets the number of pins
int noPins;
// Stores the values of our shift registers
byte rArray[3];
// gives all the available numbers
static const byte Pins[8];
// Tells the system which pins have been turned on
bool firstPinsActive[8];
bool secondPinsActive[8];
bool thirdPinsActive[8];
// adds the values of the pins.
void CountPins();


public:
ShiftRegister();
// standard shift register constructor
ShiftRegister(byte,byte,byte, int);
// Public members for red, green and blue.
byte ClockPin() {return clockPin;}
byte LatchPin() {return latchPin;}
byte DataPin() {return dataPin;}
int NoPins() {return noPins;}
byte ShiftNum(int);
void ClearShift();
void ActivatePin(int);
void ClearPins();
byte RandomPin();

};


#endif



ShiftRegister.cpp
#include<ShiftRegister.h>
#include <Arduino.h>
#include <WProgram.h>
const byte ShiftRegister::Pins[]={B00000001,B00000010,B00000100,B00001000,B00010000,B00100000,B01000000,B10000000};


ShiftRegister::ShiftRegister() { 
ClearShift();
ClearPins();
}



ShiftRegister::ShiftRegister(byte c, byte l,byte d, int p) { 
clockPin=c;
latchPin=l;
dataPin=d;
noPins=p;
ClearShift();
ClearPins();
}




void ShiftRegister::CountPins() {
ClearShift();
for (int i=0; i<8;i++)
{
if (firstPinsActive[i]==1)
{
rArray[0]=rArray[0]+Pins[i];
}
if (secondPinsActive[i]==1)
{
rArray[1]=rArray[1]+Pins[i];
}

if (firstPinsActive[i]==2)
{
rArray[2]=rArray[2]+Pins[i];
}
}
}


void ShiftRegister::ClearShift() 
{
for (int i=0;i<3;i++)
{
rArray[i]=0;
}
}
void ShiftRegister::ClearPins() {
for (int i=0; i<8;i++)
{
firstPinsActive[i]=0;
secondPinsActive[i]=0;
thirdPinsActive[i]=0;
}
}

// returns the boolean-equivalent integer of the specified register (can be up to 3)
byte ShiftRegister::ShiftNum(int i)
{
if (i<3)
{
return rArray[i];
}
}

void ShiftRegister::ActivatePin(int input)
{
if (input>24)
{
return;
}
if (input>16)
{
input=input-16;
// this pin stops you from counting the same pin twice
if (thirdPinsActive[input-1]==0)
{
// Activate the pin
thirdPinsActive[input-1]=1;
}
}
if (input>8)
{
input=input-8;
if (secondPinsActive[input-1]==0)
{
secondPinsActive[input-1]=1;
}
}
if (input <=8)
{
if (firstPinsActive[input-1]==0)
{
Serial.print("activating pin ");
Serial.println(input);
     
firstPinsActive[input-1]=1;
}
}
CountPins();

}

byte ShiftRegister::RandomPin() {

  // return a random pin number
  
  int output=random(0,noPins-1);
return output;

}

No comments:

Post a Comment