Created
October 30, 2012 18:42
-
-
Save ksimmulator/3982166 to your computer and use it in GitHub Desktop.
Space Board code for controlling RGB LED Lights
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
/////////////////////////////////////////////////////////////// | |
// Space Board code for controlling RGB LED Lights | |
// on a skateboard via acceleration, motion, and orientation | |
// | |
// created by Keith Simmons | |
// http://ksimmulator.com | |
// | |
// demo video: http://www.youtube.com/watch?v=3NSgN4Y2Wfs | |
// | |
// 20121031: fixed some bugs by adding constrain(x,a,b) calls | |
// made all orientation logic one if/then/else statement | |
// | |
// Accelerometer stuff taken from this amazing blog post: | |
// https://chionophilous.wordpress.com/2011/06/20/getting-started-with-accelerometers-and-micro-controllers-arduino-adxl335/ | |
// | |
// RGB LED Libraries via adafruit: | |
// https://github.com/adafruit/LPD8806 | |
/////////////////////////////////////////////////////////////// | |
#include "LPD8806.h" | |
#include "SPI.h" | |
// these constants describe the pins. They won't change: | |
const int xpin = A0; // x-axis of the accelerometer | |
const int ypin = A1; // y-axis | |
const int zpin = A2; // z-axis (only on 3-axis models) | |
int sampleDelay = 1; //number of milliseconds between readings | |
// Number of RGB LEDs in strand: | |
int nLEDs = 32; | |
// Chose 2 pins for output; can be any valid output pins: | |
//int dataPin = 2; | |
//int clockPin = 3; | |
// First parameter is the number of LEDs in the strand. The LED strips | |
// are 32 LEDs per meter but you can extend or cut the strip. Next two | |
// parameters are SPI data and clock pins: | |
//LPD8806 strip = LPD8806(32, dataPin, clockPin); | |
// You can optionally use hardware SPI for faster writes, just leave out | |
// the data and clock pin parameters. But this does limit use to very | |
// specific pins on the Arduino. For "classic" Arduinos (Uno, Duemilanove, | |
// etc.), data = pin 11, clock = pin 13. For Arduino Mega, data = pin 51, | |
// clock = pin 52. For 32u4 Breakout Board+ and Teensy, data = pin B2, | |
// clock = pin B1. For Leonardo, this can ONLY be done on the ICSP pins. | |
LPD8806 strip = LPD8806(nLEDs); | |
void setup() | |
{ | |
// initialize the serial communications: | |
Serial.begin(9600); | |
//Make sure the analog-to-digital converter takes its reference voltage from | |
// the AREF pin | |
analogReference(EXTERNAL); | |
pinMode(xpin, INPUT); | |
pinMode(ypin, INPUT); | |
pinMode(zpin, INPUT); | |
// Start up the LED strip | |
strip.begin(); | |
// Update the strip, to start they are all 'off' | |
strip.show(); | |
} | |
void loop() | |
{ | |
int x = analogRead(xpin); | |
//add a small delay between pin readings. I read that you should | |
//do this but haven't tested the importance | |
delay(1); | |
int y = analogRead(ypin); | |
//add a small delay between pin readings. I read that you should | |
//do this but haven't tested the importance | |
delay(1); | |
int z = analogRead(zpin); | |
//zero_G is the reading we expect from the sensor when it detects | |
//no acceleration. Subtract this value from the sensor reading to | |
//get a shifted sensor reading. | |
float zero_G = 503.0; | |
//scale is the number of units we expect the sensor reading to | |
//change when the acceleration along an axis changes by 1G. | |
//Divide the shifted sensor reading by scale to get acceleration in Gs. | |
float scale = 615.0-zero_G; | |
float scaledX = ((float)x - zero_G)/scale; | |
float scaledY = ((float)y - zero_G)/scale; | |
float scaledZ = ((float)z - zero_G)/scale; | |
Serial.print(scaledX); | |
Serial.print("\t"); | |
Serial.print(scaledY); | |
Serial.print("\t"); | |
Serial.print(scaledZ); | |
Serial.print("\n"); | |
// delay before next reading: | |
delay(sampleDelay); | |
// Rainbow mode? | |
if ( abs(scaledY) > 0.9) { | |
// last param to color wipe function is wait in ms | |
rainbowCycle(0); // make it go through the cycle fairly fast | |
} else if ( scaledZ < -0.5) { // IS THE SKATEBOARD FACING GROUND ? | |
// last param to color wipe function is wait in ms | |
colorWipe(strip.Color( constrain(127.0 * abs(scaledX)/3.0,0,127), constrain(127.0 * abs(scaledX)/3.0,0,127), 127), 0); // Blue + white | |
} else { // POWER SAVER | |
//rainbowCycle(0); // make it go through the cycle fairly fast | |
colorWipe(strip.Color( 31, 0, 0), 0); // Red | |
//colorChase(strip.Color( 127, 0, 0), 0); // Red | |
//colorChase(strip.Color( 0, 127, 0), 0); // Green | |
//colorChase(strip.Color( 0, 0, 127), 0); // Blue | |
} | |
} | |
void loopCalibrate() | |
{ | |
Serial.print( analogRead(xpin)); | |
Serial.print("\t"); | |
//add a small delay between pin readings. I read that you should | |
//do this but haven't tested the importance | |
delay(1); | |
Serial.print( analogRead(ypin)); | |
Serial.print("\t"); | |
//add a small delay between pin readings. I read that you should | |
//do this but haven't tested the importance | |
delay(1); | |
Serial.print( analogRead(zpin)); | |
Serial.print("\n"); // delay before next reading: | |
delay(sampleDelay); | |
} | |
void rainbow(uint8_t wait) { | |
int i, j; | |
for (j=0; j < 384; j++) { // 3 cycles of all 384 colors in the wheel | |
for (i=0; i < strip.numPixels(); i++) { | |
strip.setPixelColor(i, Wheel( (i + j) % 384)); | |
} | |
strip.show(); // write all the pixels out | |
delay(wait); | |
} | |
} | |
// Slightly different, this one makes the rainbow wheel equally distributed | |
// along the chain | |
void rainbowCycle(uint8_t wait) { | |
uint16_t i, j; | |
for (j=0; j < 384 * 5; j++) { // 5 cycles of all 384 colors in the wheel | |
for (i=0; i < strip.numPixels(); i++) { | |
// tricky math! we use each pixel as a fraction of the full 384-color wheel | |
// (thats the i / strip.numPixels() part) | |
// Then add in j which makes the colors go around per pixel | |
// the % 384 is to make the wheel cycle around | |
strip.setPixelColor(i, Wheel( ((i * 384 / strip.numPixels()) + j) % 384) ); | |
} | |
strip.show(); // write all the pixels out | |
delay(wait); | |
} | |
} | |
// Fill the dots progressively along the strip. | |
void colorWipe(uint32_t c, uint8_t wait) { | |
int i; | |
for (i=0; i < strip.numPixels(); i++) { | |
strip.setPixelColor(i, c); | |
strip.show(); | |
delay(wait); | |
} | |
} | |
// Chase one dot down the full strip. | |
void colorChase(uint32_t c, uint8_t wait) { | |
int i; | |
// Start by turning all pixels off: | |
for(i=0; i<strip.numPixels(); i++) strip.setPixelColor(i, 0); | |
// Then display one pixel at a time: | |
for(i=0; i<strip.numPixels(); i++) { | |
strip.setPixelColor(i, c); // Set new pixel 'on' | |
strip.show(); // Refresh LED states | |
strip.setPixelColor(i, 0); // Erase pixel, but don't refresh! | |
delay(wait); | |
} | |
strip.show(); // Refresh to turn off last pixel | |
} | |
/* Helper functions */ | |
//Input a value 0 to 384 to get a color value. | |
//The colours are a transition r - g -b - back to r | |
uint32_t Wheel(uint16_t WheelPos) | |
{ | |
byte r, g, b; | |
switch(WheelPos / 128) | |
{ | |
case 0: | |
r = 127 - WheelPos % 128; //Red down | |
g = WheelPos % 128; // Green up | |
b = 0; //blue off | |
break; | |
case 1: | |
g = 127 - WheelPos % 128; //green down | |
b = WheelPos % 128; //blue up | |
r = 0; //red off | |
break; | |
case 2: | |
b = 127 - WheelPos % 128; //blue down | |
r = WheelPos % 128; //red up | |
g = 0; //green off | |
break; | |
} | |
return(strip.Color(r,g,b)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment