Skip to content

Instantly share code, notes, and snippets.

@Lunchbox4K
Last active January 27, 2016 17:09
Show Gist options
  • Save Lunchbox4K/4f0c006150b85e7e7a20 to your computer and use it in GitHub Desktop.
Save Lunchbox4K/4f0c006150b85e7e7a20 to your computer and use it in GitHub Desktop.
Arduino Button Press ShiftBrite
/**
* @struct ColorRGB
* @desc Structure for holding RGB color intensities.
*/
#define CLOCK_PIN 13 // CI
#define ENABLE_PIN 10 // EI
#define LATCH_PIN 9 // LI
#define DATA_PIN 11 // DI
#define LED_BTN_PIN 2
#define SB_POWER_MODE 0x01
#define SB_COLOR_MODE 0x00
#define SB_CLR_MAX 256
#define SB_DEF_POW_R 0
#define SB_DEG_POW_G 0
#define SB_DEG_POW_B 0
/**
* @struct ColorRGB
* @desc Structure for holding RGB color intensities.
*/
struct ColorRGB{
ColorRGB(short r=0, short b=0, short g=0) : red(r), blue(g), green(b) {}
/*! Generated a random color.*/
static ColorRGB rand(){
ColorRGB x;
x.red = random(0,SB_CLR_MAX);
x.blue = random(0,SB_CLR_MAX);
x.green = random(0,SB_CLR_MAX);
return x;
}
short red; //short = 16bit
short blue;
short green;
};
/**
* @class ShiftBrite
* @desc Wrapper class for a ShiftBrite.
*/
class ShiftBrite{
public:
/*! Constructor */
ShiftBrite(const ColorRGB& clr, const ColorRGB& power)
{
m_color = clr; m_power = power; m_next= NULL;
sendPowerCommand(); sendColorCommand();
if (!m_initialized) initializeShiftBrite();
}
/*! Destructor, remove any ShiftBrites connected to this one. */
~ShiftBrite(){delete m_next;}
void setColor(ColorRGB color){m_color = color; sendColorCommand();}
void setPower(ColorRGB power){m_power = power; sendPowerCommand();}
const ColorRGB& getColor(){return m_color;}
const ColorRGB& getPower(){return m_power;}
/*! Initializes the pins for the ShiftBrite */
static void initializeShiftBrite(){
//
pinMode(DATA_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0);
digitalWrite(LATCH_PIN, LOW);
digitalWrite(ENABLE_PIN, LOW);
m_initialized = true;
}
private:
/*----------------------
Private Helper Methods
---------------------- */
/*! Sends the power command */
void sendPowerCommand(){ _sendPowerCommand(); latchData(); }
/*! Helper method for sendPowerCommand() to help use multiple ShiftBrites. */
void _sendPowerCommand(){
if (m_next != NULL) m_next->sendPowerCommand();
sendPackets(SB_POWER_MODE); }
/*! Sends the color command */
void sendColorCommand(){ _sendColorCommand(); latchData(); }
/*! */
void _sendColorCommand(){
if (m_next != NULL) m_next->sendColorCommand();
sendPackets(SB_COLOR_MODE);
}
/*! Helper method for sending a command to the ShiftBrite. */
void sendPackets(byte command){
//Point type to either m_color or m_power based on the command.
ColorRGB* type;
(command == SB_COLOR_MODE) ? (type = &m_color) : (type = &m_power);
//Send packet
SPDR = command << 6 | (type->blue)>>4;
while(!(SPSR & (1<<SPIF)));
SPDR = (type->blue)<<4 | (type->red)>>6;
while(!(SPSR & (1<<SPIF)));
SPDR = (type->red) << 2 | (type->green)>>8;
while(!(SPSR & (1<<SPIF)));
SPDR = (type->green);
while(!(SPSR & (1<<SPIF)));
}
/*! Helper method for latching data. */
void latchData(){
delayMicroseconds(15);
digitalWrite(LATCH_PIN,HIGH); // latch data into registers
delayMicroseconds(15);
digitalWrite(LATCH_PIN,LOW);
}
/*----------------------
ShiftBrite Members
---------------------- */
ColorRGB m_color; /*! */
ColorRGB m_power; /*! Decided to also use my RGB structure for power control. */
ShiftBrite* m_next; /*! Points to next shift brite */
static bool m_initialized; /*! Flag that helps first constructor call, call initialize */
};
bool ShiftBrite::m_initialized = false;
//Colors
ColorRGB ClrWhite ( SB_CLR_MAX, SB_CLR_MAX, SB_CLR_MAX );
ColorRGB ClrRed ( SB_CLR_MAX, 0, 0 );
ColorRGB ClrGreen ( 0, SB_CLR_MAX, 0 );
ColorRGB ClrBlue ( 0, 0, SB_CLR_MAX );
ColorRGB ClrYellow ( SB_CLR_MAX, SB_CLR_MAX, 0);
ColorRGB ClrOrange ( SB_CLR_MAX, SB_CLR_MAX/2, 0 );
ColorRGB ClrPurple ( SB_CLR_MAX, 0, SB_CLR_MAX );
void initializeShiftBrite();
/*-----------------------------------
* Arduino Sketch
*
----------------------------------*/
ColorRGB colors[4] = { ClrWhite, ClrYellow, ClrOrange, ClrPurple };
ColorRGB dark = ColorRGB(0,0,0);
bool btnState = HIGH;
bool prevBtnState = HIGH;
long lastDebounceTime = 0;
long debounceDelay = 50;
int lightIndex = 0;
void setup() {
pinMode(LED_BTN_PIN, INPUT);
Serial.begin(9600);
randomSeed(analogRead(0));
ShiftBrite::initializeShiftBrite(); //Manually call initializer, also called on first instance of ShiftBrite.
ShiftBrite light(colors[lightIndex], dark);
}
void loop() {
int reading = digitalRead(LED_BTN_PIN);
if (reading != prevBtnState) lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay)
{
if (reading != btnState)
{
btnState = reading;
if (btnState == LOW)
{
++lightIndex;
if (lightIndex >= 4) lightIndex = 0;
ShiftBrite light(colors[lightIndex], dark);
}
}
}
prevBtnState = reading;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment