Skip to content

Instantly share code, notes, and snippets.

@fredrike
Last active October 11, 2016 17:22
Show Gist options
  • Save fredrike/c423384cbd68ac4254840dda66c7c364 to your computer and use it in GitHub Desktop.
Save fredrike/c423384cbd68ac4254840dda66c7c364 to your computer and use it in GitHub Desktop.
#include <application.h>
#include "SunRiseLamp.h"
#include "neopixel/neopixel.h"
SunRiseLamp::SunRiseLamp(int totalTime, int pixelCount, int pixelPin, int pixelType) {
colorInterval = (totalTime * 1000) / 1500;
sunRiseTemp = 0;
brightness = 0;
neoPixelPtr = new Adafruit_NeoPixel(pixelCount, pixelPin, pixelType);
neoPixelPtr->begin();
neoPixelPtr->setBrightness(0);
neoPixelPtr->show();
}
void SunRiseLamp::begin() {
lastUpdate = millis();
}
bool SunRiseLamp::update() {
unsigned long currentMillis = millis();
if (currentMillis - lastUpdate > colorInterval) {
if (direction == 1 && sunRiseTemp < 3500) {
//make a smooth transition from 0 to 2255
if( brightness < 255 )
neoPixelPtr->setBrightness(brightness++);
} else if (direction == -1 && sunRiseTemp > 2000) {
//make a smooth transition from 2000k to 0
if(sunRiseTemp <= 2255 && brightness > 0)
neoPixelPtr->setBrightness(brightness--);
} else {
return (direction = 0);
}
lastUpdate = currentMillis;
sunRiseTemp += direction;
colorAll(kelvinToRGB(sunRiseTemp));
return true;
} else {
return false;
}
}
// Set the starting temp and direction of the sun
void SunRiseLamp::rise() {
sunRiseTemp = 2000;
direction = 1;
brightness = 0;
neoPixelPtr->setBrightness(brightness);
}
void SunRiseLamp::rise(int totalTime) {
if(totalTime >= 15)
colorInterval = (totalTime * 1000) / 1500;
rise();
}
// Set the starting temp and direction of the sun
void SunRiseLamp::set() {
sunRiseTemp = 3500;
direction = -1;
brightness = 255;
neoPixelPtr->setBrightness(brightness);
}
//Convert kelvien to RGB
uint32_t SunRiseLamp::kelvinToRGB(int kelvin) {
if(kelvin <= 2000)
return 0;
int temp = kelvin / 100;
int red = 255, green, blue = 0;
if( temp <= 66 ) {
green = 99.4708025861 * log(temp) - 161.1195681661;
if( temp > 19) {
blue = 138.5177312231 * log(temp-1) - 305.0447927307;
}
} else {
red = 329.698727446 * pow(temp - 60, -0.1332047592);
green = 288.1221695283 * pow(temp - 60, -0.0755148492);
blue = 255;
}
return ((uint32_t)clamp(red) << 16) | ((uint32_t)clamp(green) << 8) | clamp(blue);
}
int SunRiseLamp::clamp(int n) {
int x=n>255?255:n;
return x<0?0:x;
}
// Set all pixels in the strip to a solid color
void SunRiseLamp::colorAll(uint32_t c) {
for(uint16_t i = 0; i < neoPixelPtr->numPixels(); i++) {
neoPixelPtr->setPixelColor(i, c);
}
neoPixelPtr->show();
}
#ifndef SunRiseLamp_h
#define SunRiseLamp_h
#include "application.h"
#include "neopixel/neopixel.h"
#include "math.h"
class SunRiseLamp {
public:
SunRiseLamp(int totalTime, int pixelCount, int pixelPin, int pixelType);
void begin(); // total time for sunrise
bool update();
void rise();
void rise(int totalTime);
void set();
uint32_t kelvinToRGB(int kelvin);
int clamp(int x);
void colorAll(uint32_t c);
private:
Adafruit_NeoPixel* neoPixelPtr = NULL;
unsigned int colorInterval;
unsigned long lastUpdate;
int direction = 0;
int sunRiseTemp;
int brightness;
};
#endif
#include "SunRiseLamp.h"
#include "TimeAlarms/TimeAlarms.h"
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = 0;
//Sunrise function.
int sunrise(String);
//Sunset function.
int sunset(String) {};
SYSTEM_MODE(AUTOMATIC);
// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 12
#define PIXEL_PIN D6
#define PIXEL_TYPE WS2812B
#define SUN_RISE_LENGTH_IN_SEC 600
SunRiseLamp sunRiseLamp = SunRiseLamp(SUN_RISE_LENGTH_IN_SEC, PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
void setup()
{
RGB.control(true);
RGB.brightness(1);
RGB.control(false);
Particle.function("color", setColor);
Particle.function("sunrise", sunrise);
Particle.function("sunset", sunset);
Time.zone(2);
Time.setFormat(TIME_FORMAT_ISO8601_FULL);
Serial.begin(9600);
/*
// create the alarms
Alarm.alarmRepeat(21,43,0, MorningAlarm); // 8:30am every day
Alarm.alarmRepeat(21,45,10,EveningAlarm); // 5:45pm every day
Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm); // 8:30:30 every Saturday
Alarm.timerRepeat(15, Repeats); // timer for every 15 seconds
Alarm.timerOnce(10, OnceOnly); // called once after 10 seconds
*/
sunRiseLamp.begin();
}
void loop(){
sunRiseLamp.update();
if (millis() - lastSync > ONE_DAY_MILLIS) {
// Request time synchronization from the Particle Cloud
Particle.syncTime();
lastSync = millis();
}
}
int setColor(String command) {
char inputStr[64];
command.toCharArray(inputStr,64);
char *p = strtok(inputStr,",");
int red = atoi(p);
p = strtok(NULL,",");
int grn = atoi(p);
p = strtok(NULL,",");
int blu = atoi(p);
p = strtok(NULL,",");
sunRiseLamp.colorAll(Adafruit_NeoPixel::Color(red, grn, blu)); //(red,grn,blu);
return Adafruit_NeoPixel::Color(red, grn, blu);
}
int sunrise(String command) {
sunRiseLamp.rise(command.toInt());
}
/*
// functions to be called when an alarm triggers:
void MorningAlarm(){
Serial.println("Alarm: - turn lights off");
}
void EveningAlarm(){
Serial.println("Alarm: - turn lights on");
}
void WeeklyAlarm(){
Serial.println("Alarm: - its Monday Morning");
}
void ExplicitAlarm(){
Serial.println("Alarm: - this triggers only at the given date and time");
}
void Repeats(){
Serial.println("15 second timer");
}
void OnceOnly(){
Serial.println("This timer only triggers once");
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment