Skip to content

Instantly share code, notes, and snippets.

@ksimmulator
Created October 30, 2012 18:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ksimmulator/3982166 to your computer and use it in GitHub Desktop.
Save ksimmulator/3982166 to your computer and use it in GitHub Desktop.
Space Board code for controlling RGB LED Lights
///////////////////////////////////////////////////////////////
// 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