/******************************************************************************
* Addressable LED Strip Light Saber Example
* By Joe Larson, the 3D Printing Professor
* http://3dpprofessor.com
*
* The light saber's blade is 50 individually addressable RGB LEDs on a strip.
*
* This example code is designed to help you create your own light saber blade
* patterns that can be quickly added to the 3DPProfessor's official light saber.
* Simply take the "yourBlade()" function, rename it something meaningful,
* and write your function. Then, submit your code to [email protected]
* and it may be included in a future video on the 3DPProfessor youtube
* channel.
******************************************************************************/
#include "FastLED.h"
/***************************************
* Hardware definitions *
***************************************/
#define NUM_LEDS 50
#define LED_DATA_PIN 3
#define POT_PIN A3
/***************************************/
CRGB leds[NUM_LEDS];
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("LED Strip Light Saber Example");
Serial.println("By Joe Larson the 3D Printing Professor");
Serial.println("http://3dpprofessor.com");
pinMode(POT_PIN, INPUT);
randomSeed(analogRead(A0));
FastLED.addLeds<WS2812B, LED_DATA_PIN, GRB>(leds, NUM_LEDS);
}
int curmode = 0;
const int numModes = 2;
void loop()
{
curmode = getMode();
switch (curmode)
{
case 1:
Serial.println("Generic Blade");
genericBlade();
break;
case 2:
Serial.println("Your Blade");
yourBlade();
break;
default:
Serial.println("Blade is starting in dead zone. Turn the pot a little");
delay(200);
}
}
void genericBlade()
{
// Here's a basic example you can build off of.
CRGB color = getSubColor();
// You can start with a transition to make the change less abrupt.
// In this case I'm just "extending" the blade.
Serial.println("Transition");
for (int i = 0; i < NUM_LEDS; i++)
{
leds[i] = color;
FastLED.show();
delay(20);
}
while (!isTimeToChange())
{
delay (1200);
color = getSubColor();
// At this point you can do any animations you want, and they'll loop
// until the pot is twisted to a new settings.
for (int pulse = 0; pulse < 12; pulse++)
{
int pulsefactor = 4 * pulse;
CRGB color = getSubColor() + CRGB(pulsefactor, pulsefactor, pulsefactor);
fill_solid(leds, NUM_LEDS, color);
FastLED.show();
delay(10);
}
for (int pulse = 12; pulse >=0; pulse--)
{
int pulsefactor = 4 * pulse;
CRGB color = getSubColor() + CRGB(pulsefactor, pulsefactor, pulsefactor);
fill_solid(leds, NUM_LEDS, color);
FastLED.show();
delay(20);
}
}
}
CRGB getSubColor()
{
return CHSV (getFineMode(255), 255, 255);
}
void yourBlade() {
// So what are you going to do?
}
bool isTimeToChange()
{
return getMode() != curmode;
}
/**************************************************/
/* getMode global calulation */
const float range = 1024.0 / numModes;
/**************************************************/
int getMode()
{
/*****************************************************************************
* Getmode changes the pot's 0-1024 input into one of numModes zone.
* But it's tricky (because of course it is). Zone 1 is the first 255, so that
* the pot data can be used to change through all the colors. Then the rest of
* the zones are divided evenly among the remaining range with a "dead zone"
* of 2 spaces between each, to overcome the "shake" that pots sometimes
* return when straddling two inputs. If it's in that dead zone, it just echos
* curmode value.
*****************************************************************************/
int val = analogRead(POT_PIN);
int zone = (val/range)+1;
if (val > 3 && val%(int)range < 2) // If it's close to the division edge, return "dead"
{
Serial.println("Returning curmode");
return curmode;
}
return zone;
}
int getFineMode(int numZones)
{
/*****************************************************************************
* Returns between 0 and numZones-1 based on the pot's position within the
* coarser "zone" returned in GetMode above.
*****************************************************************************/
int val = analogRead(POT_PIN);
int zone = val/range;
int fineVal = val - (range * zone);
return fineVal*((float)numZones/range);
}