Instantly share code, notes, and snippets.

Embed
What would you like to do?
Moon Light software. This is for my father's birthday present: a light up moon, read more on my blog https://benjaminja.com/2018/06/12/the-moon-project
#include "control.h"
#include <Arduino.h>
#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>
#include <interpolate.h>
#include <color.h>
#define NEO_LED_PIN 3
#define NUM_NEO 1
#define BTN_LED_PIN 5
#define MOON_TIME 1000
#define MOON_SET_TIME 5000
#define LED_TIME 250
#define LED_FLASH_TIME 1000
#define EE_R 0
#define EE_G 1
#define EE_B 2
Interpolate<uint8_t> led(SMOOTH);
Interpolate<Color> color(SMOOTH);
Adafruit_NeoPixel neopixels(NUM_NEO, NEO_LED_PIN);
control::Mode mode;
Color setColor;
void set_moon(bool value) {
static bool lastValue(!value);
if(value != lastValue) {
if(color.isDone()) {
color.setValue(value ? setColor : Color(0, 0, 0), MOON_TIME);
} else {
color.setValue(value ? setColor : Color(0, 0, 0), color.getTimeLeft() / (1 - color.getDelta()));
}
}
lastValue = value;
}
void set_neo(uint32_t color) {
for(uint8_t i=0; i < NUM_NEO; i++) {
neopixels.setPixelColor(i, color);
}
}
void control::begin() {
EEPROM.begin();
setColor.r = EEPROM.read(EE_R);
setColor.g = EEPROM.read(EE_G);
setColor.b = EEPROM.read(EE_B);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
pinMode(BTN_LED_PIN, OUTPUT);
neopixels.begin();
set_neo(neopixels.Color(0, 0, 0));
neopixels.show();
led.setValue(0, 0);
color.setValue(Color(0, 0, 0), 0);
setMode(POWER);
}
bool ledOn;
bool moonOn;
void control::update() {
static uint32_t lastTime(millis());
uint32_t currentTime = millis();
if(!led.isDone() || led.justFinished()) {
analogWrite(BTN_LED_PIN, led.getValue());
}
if(!color.isDone() || color.justFinished()) {
set_neo(color.getValue().to32());
neopixels.show();
}
if(mode == BRIGHTNESS) {
if(color.isDone()) {
color.setValue(moonOn ? Color(0, 0, 0) : Color(255, 255, 255), MOON_SET_TIME);
moonOn = !moonOn;
}
if(led.isDone()) {
led.setValue(ledOn ? 0 : 255, LED_FLASH_TIME);
ledOn = !ledOn;
}
}
led.step(currentTime - lastTime);
color.step(currentTime - lastTime);
lastTime = currentTime;
}
void control::setMode(control::Mode m) {
if(mode == BRIGHTNESS && m == POWER) {
setColor = color.getValue();
EEPROM.update(EE_R, setColor.r);
EEPROM.update(EE_G, setColor.g);
EEPROM.update(EE_B, setColor.b);
color.setInterpolation(SMOOTH);
set_moon(true);
color.setValue(setColor, 0);
led.setValue(255, LED_TIME);
} else if(mode == POWER && m == BRIGHTNESS) {
moonOn = true;
color.setInterpolation(LINEAR);
color.setValue(Color(255, 255, 255), MOON_SET_TIME);
ledOn = true;
led.setValue(255, LED_FLASH_TIME);
}
digitalWrite(LED_BUILTIN, m == BRIGHTNESS);
mode = m;
}
uint32_t lastTime = 0;
void control::push() {
lastTime = millis();
switch(mode) {
case POWER:
led.setValue(255, LED_TIME);
set_moon(true);
break;
case BRIGHTNESS:
setMode(POWER);
break;
}
}
void control::release() {
uint32_t t = millis();
switch(mode) {
case POWER:
if(t - lastTime < 500) {
setMode(BRIGHTNESS);
} else {
set_moon(false);
led.setValue(0, LED_TIME);
}
break;
case BRIGHTNESS:
break;
}
}
#ifndef CONRTOL_H
#define CONRTOL_H
namespace control {
enum Mode {POWER,BRIGHTNESS};
void begin();
void setMode(Mode mode);
void update();
void push();
void release();
}
#endif
#include <Arduino.h>
#include "control.h"
#define BTN_PIN 8
bool buttonUp;
void setup() {
Serial.begin(9600);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
control::begin();
if(!digitalRead(BTN_PIN)) {
buttonUp = false;
control::push();
} else {
buttonUp = true;
}
}
void loop() {
if(digitalRead(BTN_PIN) != buttonUp) {
buttonUp = !buttonUp;
if(buttonUp) {
control::release();
} else {
control::push();
}
}
control::update();
delay(16);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment