Skip to content

Instantly share code, notes, and snippets.

@Alexx999
Last active March 19, 2018 01:14
Show Gist options
  • Save Alexx999/0148de706bac4ea1f58773e0466f3327 to your computer and use it in GitHub Desktop.
Save Alexx999/0148de706bac4ea1f58773e0466f3327 to your computer and use it in GitHub Desktop.
Star Lamp
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIXELS 20
#define PIN 6
#define IN_0 3
#define IN_1 4
#define STATE_RAINBOW 0
#define STATE_HYBRID 1
#define STATE_WHITE 2
#define STATE_CYCLE 3
#define TRANSITION_DELAY 15
#define RAINBOW_DELAY 20
#define WHITE_BRIGHTNESS 200
#define HYBRID_BRIGHTNESS 120
#define HYBRID_RAINBOW_FIRST 0
#define HYBRID_RAINBOW_LAST 11
#define CYCLE_MAX 1000000
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXELS, PIN, NEO_GRB + NEO_KHZ800);
uint8_t current_state = -1;
uint8_t rainbow_state = 0;
uint32_t cycle_state = 0;
uint8_t hybrid_state = 0;
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
uint8_t readState(){
uint8_t state = 0;
if(digitalRead(IN_0) == HIGH){
state |= 1;
}
if(digitalRead(IN_1) == HIGH){
state |= 2;
}
return state;
}
bool stateCheck(){
uint8_t last_state = current_state;
current_state = readState();
return last_state != current_state;
}
void setup() {
pinMode(IN_0, INPUT_PULLUP);
pinMode(IN_1, INPUT_PULLUP);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
initRandom();
rainbow_state = random(256);
hybrid_state = random(256);
cycle_state = random(CYCLE_MAX);
stateCheck();
switchState();
}
void initRandom(){
long a = analogRead(3) & 255;
delay(10);
long b = analogRead(3) & 255;
delay(10);
long c = analogRead(3) & 255;
delay(10);
long d = analogRead(3) & 255;
long seed = a | (b << 8) | (c << 16) | (d << 24);
randomSeed(seed);
}
void switchState(){
switch(current_state){
case STATE_RAINBOW:{
switchToRainbow();
return;
}
case STATE_HYBRID:{
switchToHybrid();
return;
}
case STATE_WHITE:{
showColor(strip.Color(WHITE_BRIGHTNESS, WHITE_BRIGHTNESS, WHITE_BRIGHTNESS), TRANSITION_DELAY);
return;
}
case STATE_CYCLE:{
switchToCycle();
return;
}
}
}
void switchToRainbow(){
for(uint16_t i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, getRainbowColor(i));
strip.show();
delay(TRANSITION_DELAY);
}
}
void switchToHybrid(){
for(uint16_t i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, getHybridColor(i));
strip.show();
delay(TRANSITION_DELAY);
}
}
void switchToCycle(){
for(uint16_t i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, PreciseWheel(cycle_state));
strip.show();
delay(TRANSITION_DELAY);
}
}
void doStep(){
if(stateCheck()){
switchState();
return;
}
switch(current_state){
case STATE_WHITE:{
delay(200);
return;
}
case STATE_RAINBOW:{
rainbowCycleStep();
delay(RAINBOW_DELAY);
return;
}
case STATE_HYBRID:{
hybridCycleStep();
delay(RAINBOW_DELAY);
return;
}
case STATE_CYCLE:{
colorCycleStep();
return;
}
}
}
void loop() {
doStep();
}
// Fill the dots one after the other with a color
void showColor(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbowCycleStep() {
for(uint16_t i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, getRainbowColor(i));
}
strip.show();
rainbow_state++;
}
void hybridCycleStep() {
for(uint16_t i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, getHybridColor(i));
}
strip.show();
hybrid_state++;
}
void colorCycleStep() {
uint32_t color = PreciseWheel(cycle_state);
for(uint16_t i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, color);
}
strip.show();
cycle_state++;
if(cycle_state == CYCLE_MAX){
cycle_state = 0;
}
}
uint32_t getRainbowColor(uint16_t i){
return Wheel(((i * 256 / strip.numPixels()) + rainbow_state) & 255);
}
uint32_t getHybridColor(uint16_t i){
if(i >= HYBRID_RAINBOW_FIRST && i <= HYBRID_RAINBOW_LAST){
return Wheel(((i * 256 / (HYBRID_RAINBOW_LAST - HYBRID_RAINBOW_FIRST + 1)) + hybrid_state) & 255);
}
else{
return strip.Color(HYBRID_BRIGHTNESS, HYBRID_BRIGHTNESS, HYBRID_BRIGHTNESS);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
uint32_t PreciseWheel(uint32_t pos){
float H = pos / (float)CYCLE_MAX;
uint8_t var_r = 0;
uint8_t var_g = 0;
uint8_t var_b = 0;
float var_h = H * 6;
//if ( var_h >= 6 || var_h < 0 ) var_h = 0; //H must be < 1
int var_i = int( var_h ); //Or ... var_i = floor( var_h )
uint8_t var_2 = ( 1 - 1 * ( var_h - var_i ) ) * 255;
uint8_t var_3 = ( 1 - 1 * ( 1 - ( var_h - var_i ) ) ) * 255;
if ( var_i == 0 ) { var_r = 255 ; var_g = var_3 ; var_b = 0 ; }
else if ( var_i == 1 ) { var_r = var_2 ; var_g = 255 ; var_b = 0 ; }
else if ( var_i == 2 ) { var_r = 0 ; var_g = 255 ; var_b = var_3; }
else if ( var_i == 3 ) { var_r = 0 ; var_g = var_2 ; var_b = 255 ; }
else if ( var_i == 4 ) { var_r = var_3 ; var_g = 0 ; var_b = 255 ; }
else { var_r = 255 ; var_g = 0 ; var_b = var_2; }
return strip.Color(var_r, var_g, var_b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment