WLED/wled00/led.cpp

263 lines
6.7 KiB
C++
Raw Normal View History

2020-04-10 12:30:08 +02:00
#include "wled.h"
/*
* LED methods
*/
2020-04-10 12:30:08 +02:00
2019-12-03 14:15:12 +01:00
void setValuesFromMainSeg()
{
WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId());
colorFromUint32(seg.colors[0]);
colorFromUint32(seg.colors[1], true);
effectCurrent = seg.mode;
effectSpeed = seg.speed;
effectIntensity = seg.intensity;
effectPalette = seg.palette;
}
void resetTimebase()
{
strip.timebase = 0 - millis();
}
void toggleOnOff()
{
if (bri == 0)
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
}
2018-11-24 11:52:23 +01:00
void setAllLeds() {
2020-02-09 19:10:29 +01:00
if (!realtimeMode || !arlsForceMaxBri)
2017-02-01 19:25:36 +01:00
{
double d = briT*briMultiplier;
int val = d/100;
if (val > 255) val = 255;
2019-05-22 00:23:09 +02:00
strip.setBrightness(val);
2017-02-01 19:25:36 +01:00
}
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY)
{
colorRGBtoRGBW(colT);
colorRGBtoRGBW(colSecT);
}
strip.setColor(0, colT[0], colT[1], colT[2], colT[3]);
strip.setColor(1, colSecT[0], colSecT[1], colSecT[2], colSecT[3]);
}
2018-11-24 11:52:23 +01:00
2020-04-10 12:30:08 +02:00
void setLedsStandard(bool justColors)
{
for (byte i=0; i<4; i++)
{
colOld[i] = col[i];
colT[i] = col[i];
colSecOld[i] = colSec[i];
colSecT[i] = colSec[i];
}
2020-02-09 10:35:32 +01:00
if (justColors) return;
briOld = bri;
briT = bri;
setAllLeds();
}
2018-11-24 11:52:23 +01:00
bool colorChanged()
{
for (byte i=0; i<4; i++)
{
if (col[i] != colIT[i]) return true;
if (colSec[i] != colSecIT[i]) return true;
}
if (bri != briIT) return true;
return false;
}
2018-11-24 11:52:23 +01:00
void colorUpdated(int callMode)
{
2018-11-24 11:52:23 +01:00
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
2019-01-09 22:52:42 +01:00
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
2020-02-22 16:17:32 +01:00
if (callMode != NOTIFIER_CALL_MODE_INIT &&
callMode != NOTIFIER_CALL_MODE_DIRECT_CHANGE &&
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments
2019-12-02 12:41:35 +01:00
2018-11-24 11:52:23 +01:00
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
2020-02-24 17:25:40 +01:00
bool colChanged = colorChanged();
if (fxChanged || colChanged)
{
2020-02-24 17:25:40 +01:00
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
if (isPreset) {isPreset = false;}
else {currentPreset = -1;}
notify(callMode);
//set flag to update blynk and mqtt
if (callMode != NOTIFIER_CALL_MODE_PRESET_CYCLE) interfaceUpdateCallMode = callMode;
} else {
2020-02-22 16:17:32 +01:00
if (nightlightActive && !nightlightActiveOld &&
callMode != NOTIFIER_CALL_MODE_NOTIFICATION &&
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY)
{
2020-02-22 16:17:32 +01:00
notify(NOTIFIER_CALL_MODE_NIGHTLIGHT);
interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT;
}
}
2020-02-24 17:25:40 +01:00
if (!colChanged) return; //following code is for e.g. initiating transitions
2020-02-22 16:17:32 +01:00
if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && nightlightFade)
{
briNlT = bri;
nightlightDelayMs -= (millis() - nightlightStartTime);
nightlightStartTime = millis();
}
for (byte i=0; i<4; i++)
{
colIT[i] = col[i];
colSecIT[i] = colSec[i];
}
2020-02-09 10:35:32 +01:00
if (briT == 0)
{
2020-02-22 16:17:32 +01:00
setLedsStandard(true); //do not color transition if starting from off
if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning
2020-02-09 10:35:32 +01:00
}
briIT = bri;
if (bri > 0) briLast = bri;
if (fadeTransition)
{
//set correct delay if not using notification delay
2020-02-22 16:17:32 +01:00
if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay;
jsonTransitionOnce = false;
if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;}
if (transitionActive)
{
for (byte i=0; i<4; i++)
{
colOld[i] = colT[i];
colSecOld[i] = colSecT[i];
}
briOld = briT;
tperLast = 0;
}
strip.setTransitionMode(true);
transitionActive = true;
transitionStartTime = millis();
} else
{
setLedsStandard();
strip.trigger();
}
}
2018-11-24 11:52:23 +01:00
void updateInterfaces(uint8_t callMode)
{
2019-03-01 17:10:42 +01:00
#ifndef WLED_DISABLE_ALEXA
2020-02-22 16:17:32 +01:00
if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) {
2019-03-01 17:10:42 +01:00
espalexaDevice->setValue(bri);
espalexaDevice->setColor(col[0], col[1], col[2]);
}
#endif
2020-02-22 16:17:32 +01:00
if (callMode != NOTIFIER_CALL_MODE_BLYNK &&
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) updateBlynk();
2019-10-20 17:38:25 +02:00
doPublishMqtt = true;
lastInterfaceUpdate = millis();
}
2018-11-24 11:52:23 +01:00
void handleTransitions()
{
//handle still pending interface update
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > 2000)
{
updateInterfaces(interfaceUpdateCallMode);
interfaceUpdateCallMode = 0; //disable
}
2019-10-20 17:38:25 +02:00
if (doPublishMqtt) publishMqtt();
if (transitionActive && transitionDelayTemp > 0)
{
float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp;
if (tper >= 1.0)
{
strip.setTransitionMode(false);
transitionActive = false;
tperLast = 0;
setLedsStandard();
return;
}
2019-02-05 19:40:24 +01:00
if (tper - tperLast < 0.004) return;
tperLast = tper;
for (byte i=0; i<4; i++)
{
2019-02-05 19:40:24 +01:00
colT[i] = colOld[i]+((col[i] - colOld[i])*tper);
colSecT[i] = colSecOld[i]+((colSec[i] - colSecOld[i])*tper);
}
2019-02-05 19:40:24 +01:00
briT = briOld +((bri - briOld )*tper);
setAllLeds();
2016-11-27 16:45:54 +01:00
}
}
2018-11-24 11:52:23 +01:00
2016-11-27 16:45:54 +01:00
void handleNightlight()
{
if (nightlightActive)
{
if (!nightlightActiveOld) //init
2016-11-27 16:45:54 +01:00
{
nightlightStartTime = millis();
2016-11-27 16:45:54 +01:00
nightlightDelayMs = (int)(nightlightDelayMins*60000);
nightlightActiveOld = true;
briNlT = bri;
2020-02-24 17:27:59 +01:00
for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color
2016-11-27 16:45:54 +01:00
}
float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
if (nightlightFade)
{
bri = briNlT + ((nightlightTargetBri - briNlT)*nper);
2020-02-24 17:27:59 +01:00
if (nightlightColorFade) // color fading only is enabled with "NF=2"
{
2020-02-24 17:27:59 +01:00
for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color
}
2020-02-22 16:17:32 +01:00
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
}
2016-11-27 16:45:54 +01:00
if (nper >= 1)
{
nightlightActive = false;
if (!nightlightFade)
{
2018-02-20 22:29:48 +01:00
bri = nightlightTargetBri;
2020-02-22 16:17:32 +01:00
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
}
2018-07-29 14:03:02 +02:00
updateBlynk();
if (bri == 0) briLast = briNlT;
2016-11-27 16:45:54 +01:00
}
} else if (nightlightActiveOld) //early de-init
2016-11-27 16:45:54 +01:00
{
nightlightActiveOld = false;
2016-11-27 16:45:54 +01:00
}
//also handle preset cycle here
if (presetCyclingEnabled && (millis() - presetCycledTime > presetCycleTime))
{
applyPreset(presetCycCurr,presetApplyBri);
presetCycCurr++; if (presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin;
if (presetCycCurr > 25) presetCycCurr = 1;
2020-02-22 16:17:32 +01:00
colorUpdated(NOTIFIER_CALL_MODE_PRESET_CYCLE);
presetCycledTime = millis();
}
2016-11-27 16:45:54 +01:00
}