Skip to content

Instantly share code, notes, and snippets.

@Luc3as
Created December 4, 2020 07:20
Show Gist options
  • Save Luc3as/2e654d422e22572bf0ff4a24cf50f648 to your computer and use it in GitHub Desktop.
Save Luc3as/2e654d422e22572bf0ff4a24cf50f648 to your computer and use it in GitHub Desktop.
Sunrise Effect for WS2812b and ESPHome
light:
- platform: neopixelbus
name: Ranné svetlo
type: GRB
pin: GPIO3
num_leds: 90
effects:
- addressable_lambda:
name: "Sunrise"
update_interval: 5ms
lambda: |-
static int sunsize = 50; //percentage of the strip that is the "sun"
static int aurorasize = 80;
static int aurora = (aurorasize * it.size()) /100 ; // 80
static int sun = (sunsize * it.size()) / 100;
static int numLeds = it.size();
static int fadeStep = 0;
static int currentAurora = 0;
static int currentMiddle = 0;
static int oldMiddle = -1;
static int oldAurora = 0;
static int currentSun = 0;
static int oldSun = -1;
static int numOfCycles = 1024;
static int cycleNumber = 0;
static int delayTime = 50 ;
// To reset static when stopping and starting the effect
// again you can use the initial_run variables
if (initial_run) {
ESP_LOGD("main", "First run, resetting effect");
fadeStep = 0;
currentAurora = 0;
currentMiddle = 0;
oldMiddle = -1;
oldAurora = 0;
currentSun = 0;
oldSun = -1;
cycleNumber = 150;
it.all() = ESPColor(0,0,0);
}
// Draw ambient
// Target blue color 0 , 102, 146
if(cycleNumber >= 0 && cycleNumber < 150) { // Initial ambient from black to blue
fadeStep++;
int greenValue = map(fadeStep, 0, 150, 0, 40);
int blueValue = map(fadeStep, 0, 150, 0, 75);
it.all() = ESPColor(0,greenValue,blueValue,0);
delay(delayTime*10);
}
if (cycleNumber == 150 ) {
fadeStep = 0;
}
// Red target 90,47 ,0
if(cycleNumber >= 150 && cycleNumber < 400) { // from blue to redish yellow
fadeStep++;
int redValue = map(fadeStep, 0, 250, 0, 70);
int greenValue = map(fadeStep, 0, 250, 0, 37);
int blueValue = map(fadeStep, 0, 250, 0, 0);
it.all() = ESPColor(redValue,greenValue,blueValue,0);
delay(delayTime*10);
}
if (cycleNumber == 400 ) {
fadeStep = 0;
}
// Aurora target 255,119,46
if(cycleNumber > 400 && cycleNumber < 1024 && currentAurora <= numLeds) { // Draw aurora
fadeStep++;
currentAurora = map(cycleNumber-400, 0, 100, 0, numLeds);
if(currentAurora % 2 != 0) {
currentAurora--;
}
//ESP_LOGD("main", "Aurora :(%d)", currentAurora);
int auroraStart = (numLeds/2)-(currentAurora/2);
int newAuroraLeft = auroraStart-1;
int newAuroraRight = auroraStart+currentAurora;
if(newAuroraLeft >= 0 && newAuroraRight <= numLeds) {
int redValue = map(fadeStep, 0, 100, 70, constrain( 255 - currentAurora * 1.2, 0, 255));
int greenValue = map(fadeStep, 0, 100, 37, constrain( 119 - currentAurora * 1.2, 0, 255));
int blueValue = map(fadeStep, 0, 100, 0, 46);
//redValue = constrain(redValue - currentAurora * 2, 0, 255);
//greenValue = constrain(greenValue - currentAurora *2 , 0 ,255);
it[newAuroraRight] = ESPColor(redValue, greenValue,0,0);
it[newAuroraLeft] = ESPColor(redValue, greenValue,0,0);
}
//it.range(auroraStart, auroraStart+currentAurora) = ESPColor( 252, 108,45,0);
oldAurora = currentAurora;
if (currentAurora >= 6 ) { // Start rising the sun
// Draw sun
currentSun = map(cycleNumber-401, 0, 100, 0, sun);
if(currentSun % 2 != 0)
{
currentSun--;
}
//ESP_LOGD("main", "sun:(%d)", currentSun);
if(currentSun != oldSun) {
int sunStart = (numLeds/2)-(currentSun/2);
int newSunLeft = sunStart-1;
int newSunRight = sunStart+currentSun;
if(newSunLeft >= 0 && newSunRight <= numLeds ) {
int sunRedValue = map(fadeStep, 0, 100, 255, 255);
int sunGreenValue = map(fadeStep, 0, 100, 119, constrain( 189 - (currentSun-8) * 2, 0, 255));
int sunBlueValue = map(fadeStep, 0, 100, 0, 0);
//ESP_LOGD("main", "sun:(%d)", sunRedValue);
it[newSunLeft] = ESPColor(sunRedValue, sunGreenValue,0,0);
it[newSunRight] = ESPColor(sunRedValue, sunGreenValue,0,0);
//it.range(sunStart, sunStart+currentSun) = ESPColor( 255, 187,0,0);
}
}
if (fadeStep == 98) {
oldSun = currentSun;
}
}
if(currentSun >= 3 ){
// Draw white middle
currentMiddle = map(cycleNumber-420, 0, 100, 0, sun/2);
if(currentMiddle % 2 != 0)
{
currentMiddle--;
}
//ESP_LOGD("main", "middle:(%d)", currentMiddle);
if(currentMiddle != oldMiddle) {
int sunStart = (numLeds/2)-(currentMiddle/2);
int newSunLeft = sunStart-1;
int newSunRight = sunStart+currentMiddle;
if(newSunLeft >= 0 && newSunRight <= numLeds ) {
int sunRedValue = map(fadeStep, 0, 100, 255, 250);
int sunGreenValue = map(fadeStep, 0, 100, 189, constrain( 223 - (currentMiddle-3) * 2, 0, 255));
int sunBlueValue = map(fadeStep, 0, 100, 0, constrain( 117 - (currentMiddle-3) * 2, 0, 255));
//ESP_LOGD("main", "sun:(%d)", sunRedValue);
it[newSunLeft] = ESPColor(sunRedValue, sunGreenValue,sunBlueValue,0);
it[newSunRight] = ESPColor(sunRedValue, sunGreenValue,sunBlueValue,0);
//it.range(sunStart, sunStart+currentSun) = ESPColor( 255, 187,0,0);
}
}
if (fadeStep == 98) {
oldMiddle = currentMiddle;
}
}
delay(delayTime);
}
if( cycleNumber <= 400) {
cycleNumber++;
ESP_LOGD("main", "Sunrise cycle (%d) / (%d)", cycleNumber,numOfCycles);
}
if(cycleNumber < numOfCycles && cycleNumber >= 399 && fadeStep >= 100 ) {
cycleNumber++;
cycleNumber++;
fadeStep = 0;
ESP_LOGD("main", "Sunrise cycle (%d) / (%d)", cycleNumber,numOfCycles);
}
if (currentAurora >= numLeds && cycleNumber < numOfCycles ) { // End of sunrise, start to brighten all
cycleNumber++;
delay(500);
if (cycleNumber >= 750 ) {
for (int i = 0; i < it.size() ; i++) {
ESPColor actualColor = it[i].get();
//ESP_LOGD("main", "Color :(%d)", actual.r);
actualColor.r = constrain( actualColor.r + cycleNumber / 200, 0, 254);
actualColor.g = constrain( actualColor.g + cycleNumber / 200, 0, 254);
actualColor.b = constrain( actualColor.b + cycleNumber / 200, 0, 254);
it[i] = ESPColor(actualColor);
//ESP_LOGD("main", "Color(%d):(%d,%d,%d)", i,actualColor.r,actualColor.g,actualColor.b);
if (actualColor.r >=254 && actualColor.g >=254 && actualColor.b >=254 ) { // everything is white, stop
cycleNumber = 1024;
ESP_LOGD("main", "Sunrise has rised ");
}
}
}
ESP_LOGD("main", "Sunrise cycle (%d) / (%d)", cycleNumber,numOfCycles);
}
@riclun80
Copy link

Hi, this lambda code is brilliant, but I don't understand anything about it.
When I run it, and it starts ramping up LEDs (around Sunrise cycle 400) it first ramp up the brightness of the LED for fiveish seconds but then jumps back to dimed and does the same over and over for 3 times (two sunrise cycles are counted every time) until it stays bright and the next LED take over doing the same.
I only have 12 LED's and hooked up one more module so I used 24, tried to change some in the code (but don't know how it works) everything was without success.

Do you have any tips on what I can change in the code to make LED ramp up slowly and only once?

Thanks!
Richard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment