Instantly share code, notes, and snippets.
Last active
January 27, 2016 17:09
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Lunchbox4K/4f0c006150b85e7e7a20 to your computer and use it in GitHub Desktop.
Arduino Button Press ShiftBrite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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