Commit 319edb49 authored by Sam Guyer's avatar Sam Guyer
Browse files

First version

parents
#include <FastLED.h>
// -- Motor --------------------------------
#define MOTOR_PIN 3
// -- LED strip ----------------------------
#define LED_PIN 7
// -- Number of LEDs in the strip
#define NUM_LEDS 6
float g_num_leds = (float) NUM_LEDS;
// -- LED elements
CRGB leds[NUM_LEDS];
#define MAX_BRIGHTNESS 80
// -- Spectrum for the timer
// Use 50 (yellow) to 97 (red)
#define START_HUE 70
#define END_HUE 95
#define POWERUP_TIME 5000
// -----------------------------------------------
// Button class
// -----------------------------------------------
class Button
{
public:
enum EventKind { NONE, CLICK, HOLD, RELEASE };
private:
enum State { UP, START, DOWN };
int m_pin;
uint32_t m_state;
uint32_t m_start_time;
uint32_t m_hold_time;
public:
Button(int pin)
: m_pin(pin),
m_state(UP),
m_start_time(0),
m_hold_time(0)
{}
void init()
{
pinMode(m_pin, INPUT);
}
EventKind getEvent(uint32_t current_time)
{
unsigned long elapsed_time = current_time - m_start_time;
// -- Read raw button
int button_raw = digitalRead(m_pin);
// --- Cap sense button
// long cs = CapSense.capacitiveSensor(1);
// if (cs > 20) button = HIGH;
// else button = LOW;
EventKind buttonEvent = NONE;
switch (m_state) {
// -- First detection of button down -- just record the time
case UP:
if (button_raw == HIGH) {
m_state = START;
m_start_time = current_time;
m_hold_time = 0;
}
break;
// -- Debouncing: if we detected a button push, check again after 50ms
// to make sure it is real
case START:
if (elapsed_time > 50) {
if (button_raw == HIGH)
m_state = DOWN;
else
m_state = UP;
}
break;
// -- Button was clicked
// Depending on how long it stays down, we either return CLICK or HOLD
case DOWN:
if (button_raw == HIGH) {
if (elapsed_time > 500) {
buttonEvent = HOLD;
m_hold_time = elapsed_time;
}
} else {
if (elapsed_time > 500) {
buttonEvent = RELEASE;
m_hold_time = elapsed_time;
} else {
buttonEvent = CLICK;
}
m_state = UP;
}
break;
}
return buttonEvent;
}
uint32_t getHoldTime(uint32_t current_time)
{
return m_hold_time;
}
};
// -- Button -------------------------------
#define BUTTON_PIN 4
Button button(BUTTON_PIN);
// -----------------------------------------------
// Set up
// -----------------------------------------------
void setup()
{
delay(500);
// -- Create the LED entries
FastLED.addLeds<WS2812, LED_PIN, RGB>(leds, NUM_LEDS);
FastLED.setBrightness(MAX_BRIGHTNESS);
// -- Set up the pins
pinMode(LED_PIN, OUTPUT);
pinMode(MOTOR_PIN, OUTPUT);
analogWrite(MOTOR_PIN, 255);
button.init();
}
// -----------------------------------------------
// Render
// -----------------------------------------------
void render(uint32_t tplus, double power)
{
double f_time = (double) tplus;
for (int i = 0; i < NUM_LEDS; i++) {
// -- Position maps LED index to range 0-1.0
double pos = ((double) i)/g_num_leds;
// -- Offset into the 2pi cycle
double offset = pos * 6.282;
// -- Want a full wave to be 1/2 second
// 500ms/x = 6.282 ==> x ~ 80
// Scale result to range 0-1.0
double speedup = 50.0 * power;
double adjusted_time = f_time/(120.0 - speedup);
double wave = (cos(adjusted_time + offset) + 1.0) / 2.0;
// -- Pick a hue in the given range
// Use a range closer to the END (red) when power is low
double range = ((double)(END_HUE - START_HUE)) * power;
double d_color = wave * range;
// -- When scale is low, keep colors in the low range
//double d_bias = 1.0 + (((double) scale)/255.0);
//d_color = d_color/d_bias;
uint8_t bright = (uint8_t) (power * 240.0) + 15;
uint8_t hue = END_HUE - ((uint8_t) d_color);
CHSV hsv((uint8_t) hue, 255, bright);
hsv2rgb_rainbow( hsv, leds[i]);
}
// -- Show the LEDS
FastLED.show();
}
// -----------------------------------------------
// Main loop
// -----------------------------------------------
unsigned long g_releaseTime = 0;
void loop()
{
// -- Read time
unsigned long currentTime = millis();
// -- See what's going on with the button
Button::EventKind event = button.getEvent(currentTime);
if (event == Button::HOLD) {
// -- Button is down: fire up the jet pack
uint32_t tplus = button.getHoldTime(currentTime);
// -- 5 seconds to fire it up
// This value ranges from 0-255 in the first 5 seconds, then
// remains at 255 for the remainder of the time
double power = ((double) tplus) / POWERUP_TIME;
if (power > 1.0) power = 1.0;
// -- Motor speed
uint8_t motor_speed = 255 - (uint8_t) (power * 255.0);
analogWrite(MOTOR_PIN, motor_speed);
// -- Go
render(tplus, power);
}
if (event == Button::RELEASE) {
g_releaseTime = currentTime;
}
if (g_releaseTime > 0) {
uint32_t downtime = currentTime - g_releaseTime;
if (downtime < 5000) {
double power = ((double) downtime) / POWERUP_TIME;
if (power > 1.0) power = 1.0;
power = 1.0 - power;
// -- Motor speed
uint8_t motor_speed = 255 - (uint8_t) (power * 255.0);
analogWrite(MOTOR_PIN, motor_speed);
// -- Power down
render(downtime, power);
} else {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
}
g_releaseTime = 0;
}
// -- Show the LEDS
FastLED.show();
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment