mirror of
https://github.com/wled/WLED.git
synced 2025-07-16 15:26:31 +00:00
Merge branch 'main' into usermod-battery-update2023
This commit is contained in:
commit
42c8a77755
@ -390,7 +390,8 @@ build_flags = ${common.build_flags} ${esp32s2.build_flags} #-D WLED_RELEASE_NAME
|
|||||||
lib_deps = ${esp32s2.lib_deps}
|
lib_deps = ${esp32s2.lib_deps}
|
||||||
|
|
||||||
[env:esp32c3]
|
[env:esp32c3]
|
||||||
platform = espressif32@5.1.1
|
platform = espressif32@5.1.1 ;; well-tested on -C3, good compatibility with WLED
|
||||||
|
; platform = espressif32@~5.2.0 ;; might help in case you experience bootloops due to corrupted flash filesystem
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||||
|
@ -92,12 +92,14 @@ class Animated_Staircase : public Usermod {
|
|||||||
static const char _bottomEchoCm[];
|
static const char _bottomEchoCm[];
|
||||||
|
|
||||||
void publishMqtt(bool bottom, const char* state) {
|
void publishMqtt(bool bottom, const char* state) {
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
if (WLED_MQTT_CONNECTED){
|
if (WLED_MQTT_CONNECTED){
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
sprintf_P(subuf, PSTR("%s/motion/%d"), mqttDeviceTopic, (int)bottom);
|
sprintf_P(subuf, PSTR("%s/motion/%d"), mqttDeviceTopic, (int)bottom);
|
||||||
mqtt->publish(subuf, 0, false, state);
|
mqtt->publish(subuf, 0, false, state);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSegments() {
|
void updateSegments() {
|
||||||
@ -345,6 +347,7 @@ class Animated_Staircase : public Usermod {
|
|||||||
|
|
||||||
uint16_t getId() { return USERMOD_ID_ANIMATED_STAIRCASE; }
|
uint16_t getId() { return USERMOD_ID_ANIMATED_STAIRCASE; }
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
/**
|
/**
|
||||||
* handling of MQTT message
|
* handling of MQTT message
|
||||||
* topic only contains stripped topic (part after /wled/MAC)
|
* topic only contains stripped topic (part after /wled/MAC)
|
||||||
@ -382,6 +385,7 @@ class Animated_Staircase : public Usermod {
|
|||||||
mqtt->subscribe(subuf, 0);
|
mqtt->subscribe(subuf, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void addToJsonState(JsonObject& root) {
|
void addToJsonState(JsonObject& root) {
|
||||||
JsonObject staircase = root[FPSTR(_name)];
|
JsonObject staircase = root[FPSTR(_name)];
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
// force the compiler to show a warning to confirm that this file is included
|
// force the compiler to show a warning to confirm that this file is included
|
||||||
#warning **** Included USERMOD_BH1750 ****
|
#warning **** Included USERMOD_BH1750 ****
|
||||||
|
|
||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
@ -156,6 +160,7 @@ public:
|
|||||||
{
|
{
|
||||||
lastLux = lux;
|
lastLux = lux;
|
||||||
lastSend = millis();
|
lastSend = millis();
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
if (WLED_MQTT_CONNECTED)
|
if (WLED_MQTT_CONNECTED)
|
||||||
{
|
{
|
||||||
if (!mqttInitialized)
|
if (!mqttInitialized)
|
||||||
@ -170,6 +175,7 @@ public:
|
|||||||
{
|
{
|
||||||
DEBUG_PRINTLN(F("Missing MQTT connection. Not publishing data"));
|
DEBUG_PRINTLN(F("Missing MQTT connection. Not publishing data"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
// force the compiler to show a warning to confirm that this file is included
|
// force the compiler to show a warning to confirm that this file is included
|
||||||
#warning **** Included USERMOD_BME280 version 2.0 ****
|
#warning **** Included USERMOD_BME280 version 2.0 ****
|
||||||
|
|
||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
@ -194,6 +194,7 @@ class UsermodBattery : public Usermod
|
|||||||
if (autoOffEnabled && (autoOffThreshold >= bat->getLevel()))
|
if (autoOffEnabled && (autoOffThreshold >= bat->getLevel()))
|
||||||
turnOff();
|
turnOff();
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
// SmartHome stuff
|
// SmartHome stuff
|
||||||
// still don't know much about MQTT and/or HA
|
// still don't know much about MQTT and/or HA
|
||||||
if (WLED_MQTT_CONNECTED) {
|
if (WLED_MQTT_CONNECTED) {
|
||||||
@ -201,6 +202,7 @@ class UsermodBattery : public Usermod
|
|||||||
snprintf_P(buf, 63, PSTR("%s/voltage"), mqttDeviceTopic);
|
snprintf_P(buf, 63, PSTR("%s/voltage"), mqttDeviceTopic);
|
||||||
mqtt->publish(buf, 0, false, String(voltage).c_str());
|
mqtt->publish(buf, 0, false, String(voltage).c_str());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <dht_nonblocking.h>
|
#include <dht_nonblocking.h>
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
||||||
|
@ -136,7 +136,7 @@ private:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_offPreset) {
|
if (m_offPreset) {
|
||||||
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(m_offPreset, NotifyUpdateMode);
|
applyPreset(m_offPreset, NotifyUpdateMode);
|
||||||
return;
|
return;
|
||||||
} else if (prevPlaylist) {
|
} else if (prevPlaylist) {
|
||||||
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, NotifyUpdateMode);
|
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, NotifyUpdateMode);
|
||||||
@ -159,6 +159,7 @@ private:
|
|||||||
|
|
||||||
void publishMqtt(const char* state)
|
void publishMqtt(const char* state)
|
||||||
{
|
{
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
if (WLED_MQTT_CONNECTED) {
|
if (WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
@ -166,11 +167,13 @@ private:
|
|||||||
strcat_P(subuf, PSTR("/motion"));
|
strcat_P(subuf, PSTR("/motion"));
|
||||||
mqtt->publish(subuf, 0, false, state);
|
mqtt->publish(subuf, 0, false, state);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
|
// Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
|
||||||
void publishHomeAssistantAutodiscovery()
|
void publishHomeAssistantAutodiscovery()
|
||||||
{
|
{
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
if (WLED_MQTT_CONNECTED) {
|
if (WLED_MQTT_CONNECTED) {
|
||||||
StaticJsonDocument<600> doc;
|
StaticJsonDocument<600> doc;
|
||||||
char uid[24], json_str[1024], buf[128];
|
char uid[24], json_str[1024], buf[128];
|
||||||
@ -200,6 +203,7 @@ private:
|
|||||||
|
|
||||||
mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain?
|
mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain?
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,6 +109,7 @@ public:
|
|||||||
{
|
{
|
||||||
lastLDRValue = currentLDRValue;
|
lastLDRValue = currentLDRValue;
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
if (WLED_MQTT_CONNECTED)
|
if (WLED_MQTT_CONNECTED)
|
||||||
{
|
{
|
||||||
char subuf[45];
|
char subuf[45];
|
||||||
@ -121,6 +122,7 @@ public:
|
|||||||
DEBUG_PRINTLN("Missing MQTT connection. Not publishing data");
|
DEBUG_PRINTLN("Missing MQTT connection. Not publishing data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getLastLDRValue()
|
uint16_t getLastLDRValue()
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// this is remixed from usermod_v2_SensorsToMqtt.h (sensors_to_mqtt usermod)
|
// this is remixed from usermod_v2_SensorsToMqtt.h (sensors_to_mqtt usermod)
|
||||||
|
@ -29,6 +29,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
bool degC = true;
|
bool degC = true;
|
||||||
// using parasite power on the sensor
|
// using parasite power on the sensor
|
||||||
bool parasite = false;
|
bool parasite = false;
|
||||||
|
int8_t parasitePin = -1;
|
||||||
// how often do we read from sensor?
|
// how often do we read from sensor?
|
||||||
unsigned long readingInterval = USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL;
|
unsigned long readingInterval = USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL;
|
||||||
// set last reading as "40 sec before boot", so first reading is taken after 20 sec
|
// set last reading as "40 sec before boot", so first reading is taken after 20 sec
|
||||||
@ -53,6 +54,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
static const char _enabled[];
|
static const char _enabled[];
|
||||||
static const char _readInterval[];
|
static const char _readInterval[];
|
||||||
static const char _parasite[];
|
static const char _parasite[];
|
||||||
|
static const char _parasitePin[];
|
||||||
|
|
||||||
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
|
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
|
||||||
float readDallas() {
|
float readDallas() {
|
||||||
@ -94,12 +96,14 @@ class UsermodTemperature : public Usermod {
|
|||||||
DEBUG_PRINTLN(F("Requesting temperature."));
|
DEBUG_PRINTLN(F("Requesting temperature."));
|
||||||
oneWire->reset();
|
oneWire->reset();
|
||||||
oneWire->skip(); // skip ROM
|
oneWire->skip(); // skip ROM
|
||||||
oneWire->write(0x44,parasite); // request new temperature reading (TODO: parasite would need special handling)
|
oneWire->write(0x44,parasite); // request new temperature reading
|
||||||
|
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, HIGH); // has to happen within 10us (open MOSFET)
|
||||||
lastTemperaturesRequest = millis();
|
lastTemperaturesRequest = millis();
|
||||||
waitingForConversion = true;
|
waitingForConversion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void readTemperature() {
|
void readTemperature() {
|
||||||
|
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
|
||||||
temperature = readDallas();
|
temperature = readDallas();
|
||||||
lastMeasurement = millis();
|
lastMeasurement = millis();
|
||||||
waitingForConversion = false;
|
waitingForConversion = false;
|
||||||
@ -134,6 +138,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
void publishHomeAssistantAutodiscovery() {
|
void publishHomeAssistantAutodiscovery() {
|
||||||
if (!WLED_MQTT_CONNECTED) return;
|
if (!WLED_MQTT_CONNECTED) return;
|
||||||
|
|
||||||
@ -155,6 +160,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
mqtt->publish(buf, 0, true, json_str, payload_size);
|
mqtt->publish(buf, 0, true, json_str, payload_size);
|
||||||
HApublished = true;
|
HApublished = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -173,6 +179,12 @@ class UsermodTemperature : public Usermod {
|
|||||||
delay(25); // try to find sensor
|
delay(25); // try to find sensor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (parasite && pinManager.allocatePin(parasitePin, true, PinOwner::UM_Temperature)) {
|
||||||
|
pinMode(parasitePin, OUTPUT);
|
||||||
|
digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
|
||||||
|
} else {
|
||||||
|
parasitePin = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (temperaturePin >= 0) {
|
if (temperaturePin >= 0) {
|
||||||
DEBUG_PRINTLN(F("Temperature pin allocation failed."));
|
DEBUG_PRINTLN(F("Temperature pin allocation failed."));
|
||||||
@ -212,6 +224,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
}
|
}
|
||||||
errorCount = 0;
|
errorCount = 0;
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
if (WLED_MQTT_CONNECTED) {
|
if (WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
strcpy(subuf, mqttDeviceTopic);
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
@ -227,6 +240,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
// publish something else to indicate status?
|
// publish something else to indicate status?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +250,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
*/
|
*/
|
||||||
//void connected() {}
|
//void connected() {}
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
/**
|
/**
|
||||||
* subscribe to MQTT topic if needed
|
* subscribe to MQTT topic if needed
|
||||||
*/
|
*/
|
||||||
@ -246,6 +261,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
publishHomeAssistantAutodiscovery();
|
publishHomeAssistantAutodiscovery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* API calls te enable data exchange between WLED modules
|
* API calls te enable data exchange between WLED modules
|
||||||
@ -315,6 +331,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
top["degC"] = degC; // usermodparam
|
top["degC"] = degC; // usermodparam
|
||||||
top[FPSTR(_readInterval)] = readingInterval / 1000;
|
top[FPSTR(_readInterval)] = readingInterval / 1000;
|
||||||
top[FPSTR(_parasite)] = parasite;
|
top[FPSTR(_parasite)] = parasite;
|
||||||
|
top[FPSTR(_parasitePin)] = parasitePin;
|
||||||
DEBUG_PRINTLN(F("Temperature config saved."));
|
DEBUG_PRINTLN(F("Temperature config saved."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,6 +357,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000;
|
readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000;
|
||||||
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
|
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
|
||||||
parasite = top[FPSTR(_parasite)] | parasite;
|
parasite = top[FPSTR(_parasite)] | parasite;
|
||||||
|
parasitePin = top[FPSTR(_parasitePin)] | parasitePin;
|
||||||
|
|
||||||
if (!initDone) {
|
if (!initDone) {
|
||||||
// first run: reading from cfg.json
|
// first run: reading from cfg.json
|
||||||
@ -354,12 +372,21 @@ class UsermodTemperature : public Usermod {
|
|||||||
delete oneWire;
|
delete oneWire;
|
||||||
pinManager.deallocatePin(temperaturePin, PinOwner::UM_Temperature);
|
pinManager.deallocatePin(temperaturePin, PinOwner::UM_Temperature);
|
||||||
temperaturePin = newTemperaturePin;
|
temperaturePin = newTemperaturePin;
|
||||||
|
pinManager.deallocatePin(parasitePin, PinOwner::UM_Temperature);
|
||||||
// initialise
|
// initialise
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||||
return !top[FPSTR(_parasite)].isNull();
|
return !top[FPSTR(_parasitePin)].isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendConfigData()
|
||||||
|
{
|
||||||
|
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
|
||||||
|
oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
|
||||||
|
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
|
||||||
|
oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getId()
|
uint16_t getId()
|
||||||
@ -373,3 +400,4 @@ const char UsermodTemperature::_name[] PROGMEM = "Temperature";
|
|||||||
const char UsermodTemperature::_enabled[] PROGMEM = "enabled";
|
const char UsermodTemperature::_enabled[] PROGMEM = "enabled";
|
||||||
const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s";
|
const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s";
|
||||||
const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr";
|
const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr";
|
||||||
|
const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin";
|
||||||
|
@ -101,6 +101,7 @@ void userLoop() {
|
|||||||
if (temptimer - lastMeasure > 60000)
|
if (temptimer - lastMeasure > 60000)
|
||||||
{
|
{
|
||||||
lastMeasure = temptimer;
|
lastMeasure = temptimer;
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
if (mqtt != nullptr)
|
if (mqtt != nullptr)
|
||||||
{
|
{
|
||||||
@ -116,6 +117,7 @@ void userLoop() {
|
|||||||
t += "/temperature";
|
t += "/temperature";
|
||||||
mqtt->publish(t.c_str(), 0, true, String(board_temperature).c_str());
|
mqtt->publish(t.c_str(), 0, true, String(board_temperature).c_str());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we time interval for redrawing passes.
|
// Check if we time interval for redrawing passes.
|
||||||
|
@ -103,6 +103,7 @@ void userLoop() {
|
|||||||
{
|
{
|
||||||
lastMeasure = tempTimer;
|
lastMeasure = tempTimer;
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
// Check if MQTT Connected, otherwise it will crash the 8266
|
// Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
if (mqtt != nullptr)
|
if (mqtt != nullptr)
|
||||||
{
|
{
|
||||||
@ -122,6 +123,7 @@ void userLoop() {
|
|||||||
h += "/humidity";
|
h += "/humidity";
|
||||||
mqtt->publish(h.c_str(), 0, true, String(board_humidity).c_str());
|
mqtt->publish(h.c_str(), 0, true, String(board_humidity).c_str());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we time interval for redrawing passes.
|
// Check if we time interval for redrawing passes.
|
||||||
|
@ -219,6 +219,7 @@ class BobLightUsermod : public Usermod {
|
|||||||
|
|
||||||
void enable(bool en) { enabled = en; }
|
void enable(bool en) { enabled = en; }
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
/**
|
/**
|
||||||
* handling of MQTT message
|
* handling of MQTT message
|
||||||
* topic only contains stripped topic (part after /wled/MAC)
|
* topic only contains stripped topic (part after /wled/MAC)
|
||||||
@ -249,6 +250,7 @@ class BobLightUsermod : public Usermod {
|
|||||||
// mqtt->subscribe(subuf, 0);
|
// mqtt->subscribe(subuf, 0);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void addToJsonInfo(JsonObject& root)
|
void addToJsonInfo(JsonObject& root)
|
||||||
{
|
{
|
||||||
|
@ -66,12 +66,14 @@ class MultiRelay : public Usermod {
|
|||||||
static const char _HAautodiscovery[];
|
static const char _HAautodiscovery[];
|
||||||
|
|
||||||
void publishMqtt(int relay) {
|
void publishMqtt(int relay) {
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
if (WLED_MQTT_CONNECTED){
|
if (WLED_MQTT_CONNECTED){
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
sprintf_P(subuf, PSTR("%s/relay/%d"), mqttDeviceTopic, relay);
|
sprintf_P(subuf, PSTR("%s/relay/%d"), mqttDeviceTopic, relay);
|
||||||
mqtt->publish(subuf, 0, false, _relay[relay].state ? "on" : "off");
|
mqtt->publish(subuf, 0, false, _relay[relay].state ? "on" : "off");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,7 +184,7 @@ class MultiRelay : public Usermod {
|
|||||||
*/
|
*/
|
||||||
MultiRelay() {
|
MultiRelay() {
|
||||||
const int8_t defPins[] = {MULTI_RELAY_PINS};
|
const int8_t defPins[] = {MULTI_RELAY_PINS};
|
||||||
for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
for (size_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||||
_relay[i].pin = i<sizeof(defPins) ? defPins[i] : -1;
|
_relay[i].pin = i<sizeof(defPins) ? defPins[i] : -1;
|
||||||
_relay[i].delay = 0;
|
_relay[i].delay = 0;
|
||||||
_relay[i].mode = false;
|
_relay[i].mode = false;
|
||||||
@ -232,6 +234,7 @@ class MultiRelay : public Usermod {
|
|||||||
|
|
||||||
//Functions called by WLED
|
//Functions called by WLED
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
/**
|
/**
|
||||||
* handling of MQTT message
|
* handling of MQTT message
|
||||||
* topic only contains stripped topic (part after /wled/MAC)
|
* topic only contains stripped topic (part after /wled/MAC)
|
||||||
@ -313,6 +316,7 @@ class MultiRelay : public Usermod {
|
|||||||
mqtt->publish(buf, 0, true, json_str, payload_size);
|
mqtt->publish(buf, 0, true, json_str, payload_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "SHT85.h"
|
#include "SHT85.h"
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifndef WLED_ENABLE_MQTT
|
||||||
|
#error "This user mod requires MQTT to be enabled."
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
373
wled00/FX.cpp
373
wled00/FX.cpp
@ -378,7 +378,7 @@ uint16_t scan(bool dual)
|
|||||||
uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9);
|
uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9);
|
||||||
uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16;
|
uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16;
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
|
||||||
int led_offset = ledIndex - (SEGLEN - size);
|
int led_offset = ledIndex - (SEGLEN - size);
|
||||||
led_offset = abs(led_offset);
|
led_offset = abs(led_offset);
|
||||||
@ -404,7 +404,7 @@ uint16_t scan(bool dual)
|
|||||||
uint16_t mode_scan(void) {
|
uint16_t mode_scan(void) {
|
||||||
return scan(false);
|
return scan(false);
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots;!,!,!;!";
|
static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots,,,,,Overlay;!,!,!;!";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -413,7 +413,7 @@ static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots;!,!,!;!";
|
|||||||
uint16_t mode_dual_scan(void) {
|
uint16_t mode_dual_scan(void) {
|
||||||
return scan(true);
|
return scan(true);
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_DUAL_SCAN[] PROGMEM = "Scan Dual@!,# of dots;!,!,!;!";
|
static const char _data_FX_MODE_DUAL_SCAN[] PROGMEM = "Scan Dual@!,# of dots,,,,,Overlay;!,!,!;!";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -530,6 +530,7 @@ uint16_t running_base(bool saw, bool dual=false) {
|
|||||||
}
|
}
|
||||||
SEGMENT.setPixelColor(i, ca);
|
SEGMENT.setPixelColor(i, ca);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,7 +568,6 @@ static const char _data_FX_MODE_SAW[] PROGMEM = "Saw@!,Width;!,!;!";
|
|||||||
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
||||||
*/
|
*/
|
||||||
uint16_t mode_twinkle(void) {
|
uint16_t mode_twinkle(void) {
|
||||||
//SEGMENT.fill(SEGCOLOR(1));
|
|
||||||
SEGMENT.fade_out(224);
|
SEGMENT.fade_out(224);
|
||||||
|
|
||||||
uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5;
|
uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5;
|
||||||
@ -659,7 +659,7 @@ static const char _data_FX_MODE_DISSOLVE_RANDOM[] PROGMEM = "Dissolve Rnd@Repeat
|
|||||||
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
||||||
*/
|
*/
|
||||||
uint16_t mode_sparkle(void) {
|
uint16_t mode_sparkle(void) {
|
||||||
for(int i = 0; i < SEGLEN; i++) {
|
if (!SEGMENT.check2) for(int i = 0; i < SEGLEN; i++) {
|
||||||
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
|
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
|
||||||
}
|
}
|
||||||
uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2;
|
uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2;
|
||||||
@ -673,7 +673,7 @@ uint16_t mode_sparkle(void) {
|
|||||||
SEGMENT.setPixelColor(SEGENV.aux0, SEGCOLOR(0));
|
SEGMENT.setPixelColor(SEGENV.aux0, SEGCOLOR(0));
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!;!,!;!;;m12=0";
|
static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!,,,,,,Overlay;!,!;!;;m12=0";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -681,7 +681,7 @@ static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!;!,!;!;;m12=0";
|
|||||||
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
||||||
*/
|
*/
|
||||||
uint16_t mode_flash_sparkle(void) {
|
uint16_t mode_flash_sparkle(void) {
|
||||||
for(uint16_t i = 0; i < SEGLEN; i++) {
|
if (!SEGMENT.check2) for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||||
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,7 +694,7 @@ uint16_t mode_flash_sparkle(void) {
|
|||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!;Bg,Fx;!;;m12=0";
|
static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!,,,,,Overlay;Bg,Fx;!;;m12=0";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -702,7 +702,7 @@ static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!;Bg,F
|
|||||||
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
||||||
*/
|
*/
|
||||||
uint16_t mode_hyper_sparkle(void) {
|
uint16_t mode_hyper_sparkle(void) {
|
||||||
for (int i = 0; i < SEGLEN; i++) {
|
if (!SEGMENT.check2) for (int i = 0; i < SEGLEN; i++) {
|
||||||
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,7 +717,7 @@ uint16_t mode_hyper_sparkle(void) {
|
|||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_HYPER_SPARKLE[] PROGMEM = "Sparkle+@!,!;Bg,Fx;!;;m12=0";
|
static const char _data_FX_MODE_HYPER_SPARKLE[] PROGMEM = "Sparkle+@!,!,,,,,Overlay;Bg,Fx;!;;m12=0";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1366,12 +1366,11 @@ uint16_t police_base(uint32_t color1, uint32_t color2)
|
|||||||
//Police Lights with custom colors
|
//Police Lights with custom colors
|
||||||
uint16_t mode_two_dots()
|
uint16_t mode_two_dots()
|
||||||
{
|
{
|
||||||
SEGMENT.fill(SEGCOLOR(2));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(2));
|
||||||
uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1);
|
uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1);
|
||||||
|
|
||||||
return police_base(SEGCOLOR(0), color2);
|
return police_base(SEGCOLOR(0), color2);
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_TWO_DOTS[] PROGMEM = "Two Dots@!,Dot size;1,2,Bg;!";
|
static const char _data_FX_MODE_TWO_DOTS[] PROGMEM = "Two Dots@!,Dot size,,,,,Overlay;1,2,Bg;!";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1549,7 +1548,7 @@ uint16_t mode_icu(void) {
|
|||||||
uint16_t dest = SEGENV.step & 0xFFFF;
|
uint16_t dest = SEGENV.step & 0xFFFF;
|
||||||
uint8_t space = (SEGMENT.intensity >> 3) +2;
|
uint8_t space = (SEGMENT.intensity >> 3) +2;
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
|
||||||
byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255);
|
byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255);
|
||||||
uint32_t col = SEGMENT.color_from_palette(pindex, false, false, 0);
|
uint32_t col = SEGMENT.color_from_palette(pindex, false, false, 0);
|
||||||
@ -1580,7 +1579,7 @@ uint16_t mode_icu(void) {
|
|||||||
|
|
||||||
return SPEED_FORMULA_L;
|
return SPEED_FORMULA_L;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!;!,!;!";
|
static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!,,,,,Overlay;!,!;!";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1823,7 +1822,7 @@ uint16_t mode_lightning(void)
|
|||||||
SEGENV.aux0 = 200; //200ms delay after leader
|
SEGENV.aux0 = 200; //200ms delay after leader
|
||||||
}
|
}
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
|
||||||
if (SEGENV.aux1 > 3 && !(SEGENV.aux1 & 0x01)) { //flash on even number >2
|
if (SEGENV.aux1 > 3 && !(SEGENV.aux1 & 0x01)) { //flash on even number >2
|
||||||
for (int i = ledstart; i < ledstart + ledlen; i++)
|
for (int i = ledstart; i < ledstart + ledlen; i++)
|
||||||
@ -1848,7 +1847,7 @@ uint16_t mode_lightning(void)
|
|||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_LIGHTNING[] PROGMEM = "Lightning@!,!;!,!;!";
|
static const char _data_FX_MODE_LIGHTNING[] PROGMEM = "Lightning@!,!,,,,,Overlay;!,!;!";
|
||||||
|
|
||||||
|
|
||||||
// Pride2015
|
// Pride2015
|
||||||
@ -1892,6 +1891,7 @@ uint16_t mode_pride_2015(void)
|
|||||||
}
|
}
|
||||||
SEGENV.step = sPseudotime;
|
SEGENV.step = sPseudotime;
|
||||||
SEGENV.aux0 = sHue16;
|
SEGENV.aux0 = sHue16;
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;";
|
static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;";
|
||||||
@ -1929,9 +1929,10 @@ uint16_t mode_palette()
|
|||||||
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
|
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
|
||||||
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, noWrap, 255));
|
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, noWrap, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!";
|
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!;;c3=0,o2=0";
|
||||||
|
|
||||||
|
|
||||||
// WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active
|
// WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active
|
||||||
@ -2069,6 +2070,7 @@ uint16_t mode_colorwaves()
|
|||||||
}
|
}
|
||||||
SEGENV.step = sPseudotime;
|
SEGENV.step = sPseudotime;
|
||||||
SEGENV.aux0 = sHue16;
|
SEGENV.aux0 = sHue16;
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!";
|
static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!";
|
||||||
@ -2085,6 +2087,7 @@ uint16_t mode_bpm()
|
|||||||
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
|
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
|
||||||
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(stp + (i * 2), false, PALETTE_SOLID_WRAP, 0, beat - stp + (i * 10)));
|
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(stp + (i * 2), false, PALETTE_SOLID_WRAP, 0, beat - stp + (i * 10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_BPM[] PROGMEM = "Bpm@!;!;!;;sx=64";
|
static const char _data_FX_MODE_BPM[] PROGMEM = "Bpm@!;!;!;;sx=64";
|
||||||
@ -2267,6 +2270,7 @@ uint16_t mode_lake() {
|
|||||||
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
|
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
|
||||||
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, 0, lum));
|
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, 0, lum));
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!";
|
static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!";
|
||||||
@ -2396,7 +2400,7 @@ typedef struct Ripple {
|
|||||||
#else
|
#else
|
||||||
#define MAX_RIPPLES 100
|
#define MAX_RIPPLES 100
|
||||||
#endif
|
#endif
|
||||||
uint16_t ripple_base(bool rainbow)
|
uint16_t ripple_base()
|
||||||
{
|
{
|
||||||
uint16_t maxRipples = min(1 + (SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266
|
uint16_t maxRipples = min(1 + (SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266
|
||||||
uint16_t dataSize = sizeof(ripple) * maxRipples;
|
uint16_t dataSize = sizeof(ripple) * maxRipples;
|
||||||
@ -2405,80 +2409,74 @@ uint16_t ripple_base(bool rainbow)
|
|||||||
|
|
||||||
Ripple* ripples = reinterpret_cast<Ripple*>(SEGENV.data);
|
Ripple* ripples = reinterpret_cast<Ripple*>(SEGENV.data);
|
||||||
|
|
||||||
// ranbow background or chosen background, all very dim.
|
|
||||||
if (rainbow) {
|
|
||||||
if (SEGENV.call ==0) {
|
|
||||||
SEGENV.aux0 = random8();
|
|
||||||
SEGENV.aux1 = random8();
|
|
||||||
}
|
|
||||||
if (SEGENV.aux0 == SEGENV.aux1) {
|
|
||||||
SEGENV.aux1 = random8();
|
|
||||||
}
|
|
||||||
else if (SEGENV.aux1 > SEGENV.aux0) {
|
|
||||||
SEGENV.aux0++;
|
|
||||||
} else {
|
|
||||||
SEGENV.aux0--;
|
|
||||||
}
|
|
||||||
SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux0),BLACK,235));
|
|
||||||
} else {
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw wave
|
//draw wave
|
||||||
for (int i = 0; i < maxRipples; i++)
|
for (int i = 0; i < maxRipples; i++) {
|
||||||
{
|
|
||||||
uint16_t ripplestate = ripples[i].state;
|
uint16_t ripplestate = ripples[i].state;
|
||||||
if (ripplestate)
|
if (ripplestate) {
|
||||||
{
|
|
||||||
uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation
|
uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation
|
||||||
uint16_t rippleorigin = ripples[i].pos;
|
uint16_t rippleorigin = ripples[i].pos;
|
||||||
uint32_t col = SEGMENT.color_from_palette(ripples[i].color, false, false, 255);
|
uint32_t col = SEGMENT.color_from_palette(ripples[i].color, false, false, 255);
|
||||||
uint16_t propagation = ((ripplestate/rippledecay -1) * SEGMENT.speed);
|
uint16_t propagation = ((ripplestate/rippledecay - 1) * (SEGMENT.speed + 1));
|
||||||
int16_t propI = propagation >> 8;
|
int16_t propI = propagation >> 8;
|
||||||
uint8_t propF = propagation & 0xFF;
|
uint8_t propF = propagation & 0xFF;
|
||||||
int16_t left = rippleorigin - propI -1;
|
|
||||||
uint8_t amp = (ripplestate < 17) ? triwave8((ripplestate-1)*8) : map(ripplestate,17,255,255,2);
|
uint8_t amp = (ripplestate < 17) ? triwave8((ripplestate-1)*8) : map(ripplestate,17,255,255,2);
|
||||||
|
|
||||||
for (int16_t v = left; v < left +4; v++)
|
#ifndef WLED_DISABLE_2D
|
||||||
|
if (SEGMENT.is2D()) {
|
||||||
|
uint16_t cx = rippleorigin >> 8;
|
||||||
|
uint16_t cy = rippleorigin & 0xFF;
|
||||||
|
uint8_t mag = scale8(cubicwave8((propF>>2)), amp);
|
||||||
|
if (propI > 0) SEGMENT.draw_circle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag));
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
int16_t left = rippleorigin - propI -1;
|
||||||
|
for (int16_t v = left; v < left +4; v++) {
|
||||||
uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp);
|
uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp);
|
||||||
if (v < SEGLEN && v >= 0)
|
|
||||||
{
|
|
||||||
SEGMENT.setPixelColor(v, color_blend(SEGMENT.getPixelColor(v), col, mag)); // TODO
|
SEGMENT.setPixelColor(v, color_blend(SEGMENT.getPixelColor(v), col, mag)); // TODO
|
||||||
}
|
|
||||||
int16_t w = left + propI*2 + 3 -(v-left);
|
int16_t w = left + propI*2 + 3 -(v-left);
|
||||||
if (w < SEGLEN && w >= 0)
|
|
||||||
{
|
|
||||||
SEGMENT.setPixelColor(w, color_blend(SEGMENT.getPixelColor(w), col, mag)); // TODO
|
SEGMENT.setPixelColor(w, color_blend(SEGMENT.getPixelColor(w), col, mag)); // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ripplestate += rippledecay;
|
ripplestate += rippledecay;
|
||||||
ripples[i].state = (ripplestate > 254) ? 0 : ripplestate;
|
ripples[i].state = (ripplestate > 254) ? 0 : ripplestate;
|
||||||
} else //randomly create new wave
|
} else {//randomly create new wave
|
||||||
{
|
if (random16(IBN + 10000) <= SEGMENT.intensity) {
|
||||||
if (random16(IBN + 10000) <= SEGMENT.intensity)
|
|
||||||
{
|
|
||||||
ripples[i].state = 1;
|
ripples[i].state = 1;
|
||||||
ripples[i].pos = random16(SEGLEN);
|
ripples[i].pos = SEGMENT.is2D() ? ((random8(SEGENV.virtualWidth())<<8) | (random8(SEGENV.virtualHeight()))) : random16(SEGLEN);
|
||||||
ripples[i].color = random8(); //color
|
ripples[i].color = random8(); //color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
#undef MAX_RIPPLES
|
#undef MAX_RIPPLES
|
||||||
|
|
||||||
|
|
||||||
uint16_t mode_ripple(void) {
|
uint16_t mode_ripple(void) {
|
||||||
return ripple_base(false);
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
return ripple_base();
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #;,!;!";
|
static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #,,,,,Overlay;,!;!;12";
|
||||||
|
|
||||||
|
|
||||||
uint16_t mode_ripple_rainbow(void) {
|
uint16_t mode_ripple_rainbow(void) {
|
||||||
return ripple_base(true);
|
if (SEGENV.call ==0) {
|
||||||
|
SEGENV.aux0 = random8();
|
||||||
|
SEGENV.aux1 = random8();
|
||||||
|
}
|
||||||
|
if (SEGENV.aux0 == SEGENV.aux1) {
|
||||||
|
SEGENV.aux1 = random8();
|
||||||
|
} else if (SEGENV.aux1 > SEGENV.aux0) {
|
||||||
|
SEGENV.aux0++;
|
||||||
|
} else {
|
||||||
|
SEGENV.aux0--;
|
||||||
|
}
|
||||||
|
SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux0),BLACK,235));
|
||||||
|
return ripple_base();
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wave #;;!";
|
static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wave #;;!;12";
|
||||||
|
|
||||||
|
|
||||||
// TwinkleFOX by Mark Kriegsman: https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
|
// TwinkleFOX by Mark Kriegsman: https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
|
||||||
@ -2634,7 +2632,7 @@ uint16_t mode_halloween_eyes()
|
|||||||
uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE;
|
uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE;
|
||||||
if (eyeLength >= maxWidth) return mode_static(); //bail if segment too short
|
if (eyeLength >= maxWidth) return mode_static(); //bail if segment too short
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(1)); //fill background
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); //fill background
|
||||||
|
|
||||||
uint8_t state = SEGENV.aux1 >> 8;
|
uint8_t state = SEGENV.aux1 >> 8;
|
||||||
uint16_t stateTime = SEGENV.call;
|
uint16_t stateTime = SEGENV.call;
|
||||||
@ -2684,7 +2682,7 @@ uint16_t mode_halloween_eyes()
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Duration,Eye fade time;!,!;!;12";
|
static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Duration,Eye fade time,,,,,Overlay;!,!;!;12";
|
||||||
|
|
||||||
|
|
||||||
//Speed slider sets amount of LEDs lit, intensity sets unlit
|
//Speed slider sets amount of LEDs lit, intensity sets unlit
|
||||||
@ -2737,7 +2735,7 @@ static const char _data_FX_MODE_TRI_STATIC_PATTERN[] PROGMEM = "Solid Pattern Tr
|
|||||||
|
|
||||||
uint16_t spots_base(uint16_t threshold)
|
uint16_t spots_base(uint16_t threshold)
|
||||||
{
|
{
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
|
||||||
uint16_t maxZones = SEGLEN >> 2;
|
uint16_t maxZones = SEGLEN >> 2;
|
||||||
uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8);
|
uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8);
|
||||||
@ -2767,7 +2765,7 @@ uint16_t mode_spots()
|
|||||||
{
|
{
|
||||||
return spots_base((255 - SEGMENT.speed) << 8);
|
return spots_base((255 - SEGMENT.speed) << 8);
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_SPOTS[] PROGMEM = "Spots@,Width;!,!;!";
|
static const char _data_FX_MODE_SPOTS[] PROGMEM = "Spots@,Width,,,,,Overlay;!,!;!";
|
||||||
|
|
||||||
|
|
||||||
//Intensity slider sets number of "lights", LEDs per light fade in and out
|
//Intensity slider sets number of "lights", LEDs per light fade in and out
|
||||||
@ -2778,7 +2776,7 @@ uint16_t mode_spots_fade()
|
|||||||
uint16_t tr = (t >> 1) + (t >> 2);
|
uint16_t tr = (t >> 1) + (t >> 2);
|
||||||
return spots_base(tr);
|
return spots_base(tr);
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Spread,Width;!,!;!";
|
static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Spread,Width,,,,,Overlay;!,!;!";
|
||||||
|
|
||||||
|
|
||||||
//each needs 12 bytes
|
//each needs 12 bytes
|
||||||
@ -2800,7 +2798,7 @@ uint16_t mode_bouncing_balls(void) {
|
|||||||
|
|
||||||
Ball* balls = reinterpret_cast<Ball*>(SEGENV.data);
|
Ball* balls = reinterpret_cast<Ball*>(SEGENV.data);
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1));
|
||||||
|
|
||||||
// virtualStrip idea by @ewowi (Ewoud Wijma)
|
// virtualStrip idea by @ewowi (Ewoud Wijma)
|
||||||
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelColor()
|
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelColor()
|
||||||
@ -2857,7 +2855,7 @@ uint16_t mode_bouncing_balls(void) {
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_BOUNCINGBALLS[] PROGMEM = "Bouncing Balls@Gravity,# of balls;!,!,!;!;1;m12=1"; //bar
|
static const char _data_FX_MODE_BOUNCINGBALLS[] PROGMEM = "Bouncing Balls@Gravity,# of balls,,,,,Overlay;!,!,!;!;1;m12=1"; //bar
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2915,19 +2913,35 @@ uint16_t mode_sinelon_rainbow(void) {
|
|||||||
static const char _data_FX_MODE_SINELON_RAINBOW[] PROGMEM = "Sinelon Rainbow@!,Trail;,,!;!";
|
static const char _data_FX_MODE_SINELON_RAINBOW[] PROGMEM = "Sinelon Rainbow@!,Trail;,,!;!";
|
||||||
|
|
||||||
|
|
||||||
//Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6
|
// utility function that will add random glitter to SEGMENT
|
||||||
|
void glitter_base(uint8_t intensity, uint32_t col = ULTRAWHITE) {
|
||||||
|
if (intensity > random8()) {
|
||||||
|
if (SEGMENT.is2D()) {
|
||||||
|
SEGMENT.setPixelColorXY(random16(SEGMENT.virtualWidth()),random16(SEGMENT.virtualHeight()), col);
|
||||||
|
} else {
|
||||||
|
SEGMENT.setPixelColor(random16(SEGLEN), col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Glitter with palette background, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6
|
||||||
uint16_t mode_glitter()
|
uint16_t mode_glitter()
|
||||||
{
|
{
|
||||||
mode_palette();
|
if (!SEGMENT.check2) mode_palette(); // use "* Color 1" palette for solid background (replacing "Solid glitter")
|
||||||
|
glitter_base(SEGMENT.intensity, SEGCOLOR(2) ? SEGCOLOR(2) : ULTRAWHITE);
|
||||||
if (SEGMENT.intensity > random8())
|
|
||||||
{
|
|
||||||
SEGMENT.setPixelColor(random16(SEGLEN), ULTRAWHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_GLITTER[] PROGMEM = "Glitter@!,!;;!;;m12=0"; //pixels
|
static const char _data_FX_MODE_GLITTER[] PROGMEM = "Glitter@!,!,,,,,Overlay;1,2,Glitter color;!;;pal=0,m12=0"; //pixels
|
||||||
|
|
||||||
|
|
||||||
|
//Solid colour background with glitter
|
||||||
|
uint16_t mode_solid_glitter()
|
||||||
|
{
|
||||||
|
SEGMENT.fill(SEGCOLOR(0));
|
||||||
|
glitter_base(SEGMENT.intensity, SEGCOLOR(2) ? SEGCOLOR(2) : ULTRAWHITE);
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
static const char _data_FX_MODE_SOLID_GLITTER[] PROGMEM = "Solid Glitter@,!;Bg,,Glitter color;;;m12=0";
|
||||||
|
|
||||||
|
|
||||||
//each needs 19 bytes
|
//each needs 19 bytes
|
||||||
@ -2953,7 +2967,7 @@ uint16_t mode_popcorn(void) {
|
|||||||
Spark* popcorn = reinterpret_cast<Spark*>(SEGENV.data);
|
Spark* popcorn = reinterpret_cast<Spark*>(SEGENV.data);
|
||||||
|
|
||||||
bool hasCol2 = SEGCOLOR(2);
|
bool hasCol2 = SEGCOLOR(2);
|
||||||
SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1));
|
||||||
|
|
||||||
struct virtualStrip {
|
struct virtualStrip {
|
||||||
static void runStrip(uint16_t stripNr, Spark* popcorn) {
|
static void runStrip(uint16_t stripNr, Spark* popcorn) {
|
||||||
@ -3000,7 +3014,7 @@ uint16_t mode_popcorn(void) {
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!;!,!,!;!;;m12=1"; //bar
|
static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!,,,,,Overlay;!,!,!;!;;m12=1"; //bar
|
||||||
|
|
||||||
|
|
||||||
//values close to 100 produce 5Hz flicker, which looks very candle-y
|
//values close to 100 produce 5Hz flicker, which looks very candle-y
|
||||||
@ -3162,7 +3176,7 @@ uint16_t mode_starburst(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
|
||||||
for (int j=0; j<numStars; j++)
|
for (int j=0; j<numStars; j++)
|
||||||
{
|
{
|
||||||
@ -3227,7 +3241,7 @@ uint16_t mode_starburst(void) {
|
|||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
#undef STARBURST_MAX_FRAG
|
#undef STARBURST_MAX_FRAG
|
||||||
static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chance,Fragments;,!;!;;pal=11,m12=0";
|
static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chance,Fragments,,,,,Overlay;,!;!;;pal=11,m12=0";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3258,7 +3272,6 @@ uint16_t mode_exploding_fireworks(void)
|
|||||||
SEGENV.aux1 = dataSize;
|
SEGENV.aux1 = dataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
//SEGMENT.fill(BLACK);
|
|
||||||
SEGMENT.fade_out(252);
|
SEGMENT.fade_out(252);
|
||||||
|
|
||||||
Spark* sparks = reinterpret_cast<Spark*>(SEGENV.data);
|
Spark* sparks = reinterpret_cast<Spark*>(SEGENV.data);
|
||||||
@ -3379,7 +3392,7 @@ uint16_t mode_drip(void)
|
|||||||
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
|
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
|
||||||
Spark* drops = reinterpret_cast<Spark*>(SEGENV.data);
|
Spark* drops = reinterpret_cast<Spark*>(SEGENV.data);
|
||||||
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
|
||||||
|
|
||||||
struct virtualStrip {
|
struct virtualStrip {
|
||||||
static void runStrip(uint16_t stripNr, Spark* drops) {
|
static void runStrip(uint16_t stripNr, Spark* drops) {
|
||||||
@ -3449,7 +3462,7 @@ uint16_t mode_drip(void)
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips;!,!;!;;m12=1"; //bar
|
static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips,,,,,Overlay;!,!;!;;m12=1"; //bar
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3472,7 +3485,7 @@ uint16_t mode_tetrix(void) {
|
|||||||
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
|
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
|
||||||
Tetris* drops = reinterpret_cast<Tetris*>(SEGENV.data);
|
Tetris* drops = reinterpret_cast<Tetris*>(SEGENV.data);
|
||||||
|
|
||||||
if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D)
|
//if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D), then use drop->step = 0 below
|
||||||
|
|
||||||
// virtualStrip idea by @ewowi (Ewoud Wijma)
|
// virtualStrip idea by @ewowi (Ewoud Wijma)
|
||||||
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelcolor()
|
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelcolor()
|
||||||
@ -3482,9 +3495,8 @@ uint16_t mode_tetrix(void) {
|
|||||||
// initialize dropping on first call or segment full
|
// initialize dropping on first call or segment full
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
drop->stack = 0; // reset brick stack size
|
drop->stack = 0; // reset brick stack size
|
||||||
drop->step = 0;
|
drop->step = millis() + 2000; // start by fading out strip
|
||||||
if (SEGMENT.check1) drop->col = 0;// use only one color from palette
|
if (SEGMENT.check1) drop->col = 0;// use only one color from palette
|
||||||
//for (int i=0; i<SEGLEN; i++) SEGMENT.setPixelColor(indexToVStrip(i, stripNr), SEGCOLOR(1)); // will fill virtual strip only
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drop->step == 0) { // init brick
|
if (drop->step == 0) { // init brick
|
||||||
@ -3772,21 +3784,6 @@ uint16_t mode_pacifica()
|
|||||||
static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=51";
|
static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=51";
|
||||||
|
|
||||||
|
|
||||||
//Solid colour background with glitter
|
|
||||||
uint16_t mode_solid_glitter()
|
|
||||||
{
|
|
||||||
SEGMENT.fill(SEGCOLOR(0));
|
|
||||||
|
|
||||||
if (SEGMENT.intensity > random8())
|
|
||||||
{
|
|
||||||
SEGMENT.setPixelColor(random16(SEGLEN), ULTRAWHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FRAMETIME;
|
|
||||||
}
|
|
||||||
static const char _data_FX_MODE_SOLID_GLITTER[] PROGMEM = "Solid Glitter@,!;!;;;m12=0";
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mode simulates a gradual sunrise
|
* Mode simulates a gradual sunrise
|
||||||
*/
|
*/
|
||||||
@ -3800,7 +3797,7 @@ uint16_t mode_sunrise() {
|
|||||||
SEGENV.aux0 = SEGMENT.speed;
|
SEGENV.aux0 = SEGMENT.speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEGMENT.fill(0);
|
SEGMENT.fill(BLACK);
|
||||||
uint16_t stage = 0xFFFF;
|
uint16_t stage = 0xFFFF;
|
||||||
|
|
||||||
uint32_t s10SinceStart = (millis() - SEGENV.step) /100; //tenths of seconds
|
uint32_t s10SinceStart = (millis() - SEGENV.step) /100; //tenths of seconds
|
||||||
@ -4001,7 +3998,6 @@ static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //ver
|
|||||||
*/
|
*/
|
||||||
uint16_t mode_chunchun(void)
|
uint16_t mode_chunchun(void)
|
||||||
{
|
{
|
||||||
//SEGMENT.fill(SEGCOLOR(1));
|
|
||||||
SEGMENT.fade_out(254); // add a bit of trail
|
SEGMENT.fade_out(254); // add a bit of trail
|
||||||
uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4));
|
uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4));
|
||||||
uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment
|
uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment
|
||||||
@ -4629,8 +4625,8 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
|
|||||||
SEGENV.aux0 = 0; // start with red hue
|
SEGENV.aux0 = 0; // start with red hue
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dot = false;
|
bool dot = SEGMENT.check3;
|
||||||
bool grad = true;
|
bool grad = SEGMENT.check1;
|
||||||
|
|
||||||
byte numLines = SEGMENT.intensity/16 + 1;
|
byte numLines = SEGMENT.intensity/16 + 1;
|
||||||
|
|
||||||
@ -4646,24 +4642,26 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
|
|||||||
byte xsteps = abs8(x1 - y1) + 1;
|
byte xsteps = abs8(x1 - y1) + 1;
|
||||||
byte ysteps = abs8(x2 - y2) + 1;
|
byte ysteps = abs8(x2 - y2) + 1;
|
||||||
byte steps = xsteps >= ysteps ? xsteps : ysteps;
|
byte steps = xsteps >= ysteps ? xsteps : ysteps;
|
||||||
|
//Draw gradient line
|
||||||
for (size_t i = 1; i <= steps; i++) {
|
for (size_t i = 1; i <= steps; i++) {
|
||||||
byte dx = lerp8by8(x1, y1, i * 255 / steps);
|
uint8_t rate = i * 255 / steps;
|
||||||
byte dy = lerp8by8(x2, y2, i * 255 / steps);
|
byte dx = lerp8by8(x1, y1, rate);
|
||||||
|
byte dy = lerp8by8(x2, y2, rate);
|
||||||
|
//SEGMENT.setPixelColorXY(dx, dy, grad ? color.nscale8_video(255-rate) : color); // use addPixelColorXY for different look
|
||||||
SEGMENT.addPixelColorXY(dx, dy, color); // use setPixelColorXY for different look
|
SEGMENT.addPixelColorXY(dx, dy, color); // use setPixelColorXY for different look
|
||||||
if (grad) SEGMENT.fadePixelColorXY(dx, dy, (i * 255 / steps)); //Draw gradient line
|
if (grad) SEGMENT.fadePixelColorXY(dx, dy, rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dot) { //add white point at the ends of line
|
if (dot) { //add white point at the ends of line
|
||||||
SEGMENT.addPixelColorXY(x1, x2, WHITE);
|
SEGMENT.setPixelColorXY(x1, x2, WHITE);
|
||||||
SEGMENT.addPixelColorXY(y1, y2, WHITE);
|
SEGMENT.setPixelColorXY(y1, y2, DARKSLATEGRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SEGMENT.blur(4);
|
if (SEGMENT.custom3) SEGMENT.blur(SEGMENT.custom3/2);
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
} // mode_2DColoredBursts()
|
} // mode_2DColoredBursts()
|
||||||
static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Speed,# of lines;;!;2";
|
static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Speed,# of lines,,,Blur,Gradient,,Dots;;!;2;c3=16";
|
||||||
|
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
@ -4705,10 +4703,9 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
|
|||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
SEGMENT.setUpLeds();
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
SEGENV.aux0 = 0; // hue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t speeds = SEGMENT.speed/2;
|
uint8_t speeds = SEGMENT.speed/2 + 1;
|
||||||
uint8_t freq = SEGMENT.intensity/8;
|
uint8_t freq = SEGMENT.intensity/8;
|
||||||
|
|
||||||
uint32_t ms = millis() / 20;
|
uint32_t ms = millis() / 20;
|
||||||
@ -4717,17 +4714,21 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
|
|||||||
for (int i = 0; i < rows; i++) {
|
for (int i = 0; i < rows; i++) {
|
||||||
uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128);
|
uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128);
|
||||||
uint16_t x1 = beatsin8(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq);
|
uint16_t x1 = beatsin8(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq);
|
||||||
SEGENV.aux0 = i * 128 / cols + ms; //ewowi20210629: not width - 1 to avoid crash if width = 1
|
uint8_t hue = (i * 128 / rows) + ms;
|
||||||
|
// skip every 4th row every now and then (fade it more)
|
||||||
if ((i + ms / 8) & 3) {
|
if ((i + ms / 8) & 3) {
|
||||||
|
// draw a gradient line between x and x1
|
||||||
x = x / 2; x1 = x1 / 2;
|
x = x / 2; x1 = x1 / 2;
|
||||||
byte steps = abs8(x - x1) + 1;
|
uint8_t steps = abs8(x - x1) + 1;
|
||||||
for (size_t k = 1; k <= steps; k++) {
|
for (size_t k = 1; k <= steps; k++) {
|
||||||
byte dx = lerp8by8(x, x1, k * 255 / steps);
|
uint8_t rate = k * 255 / steps;
|
||||||
SEGMENT.addPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, SEGENV.aux0, 255, LINEARBLEND));
|
uint8_t dx = lerp8by8(x, x1, rate);
|
||||||
SEGMENT.fadePixelColorXY(dx, i, (k * 255 / steps));
|
//SEGMENT.setPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND).nscale8_video(rate));
|
||||||
|
SEGMENT.addPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND)); // use setPixelColorXY for different look
|
||||||
|
SEGMENT.fadePixelColorXY(dx, i, rate);
|
||||||
}
|
}
|
||||||
SEGMENT.addPixelColorXY(x, i, DARKSLATEGRAY);
|
SEGMENT.setPixelColorXY(x, i, DARKSLATEGRAY);
|
||||||
SEGMENT.addPixelColorXY(x1, i, WHITE);
|
SEGMENT.setPixelColorXY(x1, i, WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4843,17 +4844,18 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
const uint16_t cols = SEGMENT.virtualWidth();
|
const uint16_t cols = SEGMENT.virtualWidth();
|
||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
|
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
|
||||||
|
const uint16_t crcBufferLen = (SEGMENT.width() + SEGMENT.height())*71/100; // roughly sqrt(2)/2 for better repetition detection (Ewowi)
|
||||||
|
|
||||||
if (!SEGENV.allocateData(dataSize + sizeof(unsigned long))) return mode_static(); //allocation failed
|
if (!SEGENV.allocateData(dataSize + sizeof(uint16_t)*crcBufferLen)) return mode_static(); //allocation failed
|
||||||
CRGB *prevLeds = reinterpret_cast<CRGB*>(SEGENV.data);
|
CRGB *prevLeds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||||
unsigned long *resetMillis = reinterpret_cast<unsigned long*>(SEGENV.data + dataSize); // triggers reset
|
uint16_t *crcBuffer = reinterpret_cast<uint16_t*>(SEGENV.data + dataSize);
|
||||||
|
|
||||||
CRGB backgroundColor = SEGCOLOR(1);
|
CRGB backgroundColor = SEGCOLOR(1);
|
||||||
|
|
||||||
if (SEGENV.call == 0 || strip.now - *resetMillis > 5000) {
|
if (SEGENV.call == 0 || strip.now - SEGMENT.step > 5000) {
|
||||||
*resetMillis = strip.now;
|
SEGENV.step = strip.now;
|
||||||
|
SEGENV.aux0 = 0;
|
||||||
random16_set_seed(strip.now); //seed the random generator
|
random16_set_seed(millis()>>2); //seed the random generator
|
||||||
|
|
||||||
//give the leds random state and colors (based on intensity, colors from palette or all posible colors are chosen)
|
//give the leds random state and colors (based on intensity, colors from palette or all posible colors are chosen)
|
||||||
for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) {
|
for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) {
|
||||||
@ -4861,17 +4863,18 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
if (state == 0)
|
if (state == 0)
|
||||||
SEGMENT.setPixelColorXY(x,y, backgroundColor);
|
SEGMENT.setPixelColorXY(x,y, backgroundColor);
|
||||||
else
|
else
|
||||||
SEGMENT.setPixelColorXY(x,y, SEGMENT.color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 0));
|
SEGMENT.setPixelColorXY(x,y, SEGMENT.color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) prevLeds[XY(x,y)] = CRGB::Black;
|
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) prevLeds[XY(x,y)] = CRGB::Black;
|
||||||
|
memset(crcBuffer, 0, sizeof(uint16_t)*crcBufferLen);
|
||||||
|
} else if (strip.now - SEGENV.step < FRAMETIME_FIXED * (uint32_t)map(SEGMENT.speed,0,255,64,4)) {
|
||||||
SEGENV.aux1 = 0;
|
// update only when appropriate time passes (in 42 FPS slots)
|
||||||
SEGENV.aux0 = 0xFFFF;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
//copy previous leds (save previous generation)
|
//copy previous leds (save previous generation)
|
||||||
|
//NOTE: using lossy getPixelColor() is a benefit as endlessly repeating patterns will eventually fade out causing a reset
|
||||||
for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) prevLeds[XY(x,y)] = SEGMENT.getPixelColorXY(x,y);
|
for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) prevLeds[XY(x,y)] = SEGMENT.getPixelColorXY(x,y);
|
||||||
|
|
||||||
//calculate new leds
|
//calculate new leds
|
||||||
@ -4909,7 +4912,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
if ((col != bgc) && (neighbors < 2)) SEGMENT.setPixelColorXY(x,y, bgc); // Loneliness
|
if ((col != bgc) && (neighbors < 2)) SEGMENT.setPixelColorXY(x,y, bgc); // Loneliness
|
||||||
else if ((col != bgc) && (neighbors > 3)) SEGMENT.setPixelColorXY(x,y, bgc); // Overpopulation
|
else if ((col != bgc) && (neighbors > 3)) SEGMENT.setPixelColorXY(x,y, bgc); // Overpopulation
|
||||||
else if ((col == bgc) && (neighbors == 3)) { // Reproduction
|
else if ((col == bgc) && (neighbors == 3)) { // Reproduction
|
||||||
//find dominantcolor and assign to cell
|
//find dominant color and assign to cell
|
||||||
colorCount dominantColorCount = {backgroundColor, 0};
|
colorCount dominantColorCount = {backgroundColor, 0};
|
||||||
for (int i=0; i<9 && colorsCount[i].count != 0; i++)
|
for (int i=0; i<9 && colorsCount[i].count != 0; i++)
|
||||||
if (colorsCount[i].count > dominantColorCount.count) dominantColorCount = colorsCount[i];
|
if (colorsCount[i].count > dominantColorCount.count) dominantColorCount = colorsCount[i];
|
||||||
@ -4919,16 +4922,17 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
} //x,y
|
} //x,y
|
||||||
|
|
||||||
// calculate CRC16 of leds
|
// calculate CRC16 of leds
|
||||||
uint16_t crc = crc16((const unsigned char*)prevLeds, dataSize-1); //ewowi: prevLeds instead of leds work as well, tbd: compare more patterns, see SR!
|
uint16_t crc = crc16((const unsigned char*)prevLeds, dataSize);
|
||||||
|
|
||||||
// check if we had same CRC and reset if needed
|
// check if we had same CRC and reset if needed
|
||||||
|
bool repetition = false;
|
||||||
|
for (int i=0; i<crcBufferLen && !repetition; i++) repetition = (crc == crcBuffer[i]); // (Ewowi)
|
||||||
// same CRC would mean image did not change or was repeating itself
|
// same CRC would mean image did not change or was repeating itself
|
||||||
if (!(crc == SEGENV.aux0 || crc == SEGENV.aux1)) *resetMillis = strip.now; //if no repetition avoid reset
|
if (!repetition) SEGENV.step = strip.now; //if no repetition avoid reset
|
||||||
// remember last two
|
// remember CRCs across frames
|
||||||
SEGENV.aux1 = SEGENV.aux0;
|
crcBuffer[SEGENV.aux0] = crc;
|
||||||
SEGENV.aux0 = crc;
|
++SEGENV.aux0 %= crcBufferLen;
|
||||||
|
|
||||||
return FRAMETIME_FIXED * (128-(SEGMENT.speed>>1)); // update only when appropriate time passes (in 42 FPS slots)
|
return FRAMETIME;
|
||||||
} // mode_2Dgameoflife()
|
} // mode_2Dgameoflife()
|
||||||
static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!;!,!;!;2";
|
static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!;!,!;!;2";
|
||||||
|
|
||||||
@ -5086,11 +5090,11 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline
|
|||||||
for (int i=0; i < 256; i ++) {
|
for (int i=0; i < 256; i ++) {
|
||||||
//float xlocn = float(sin8(now/4+i*(SEGMENT.speed>>5))) / 255.0f;
|
//float xlocn = float(sin8(now/4+i*(SEGMENT.speed>>5))) / 255.0f;
|
||||||
//float ylocn = float(cos8(now/4+i*2)) / 255.0f;
|
//float ylocn = float(cos8(now/4+i*2)) / 255.0f;
|
||||||
uint8_t xlocn = sin8(strip.now/2+i*(SEGMENT.speed>>5));
|
uint8_t xlocn = sin8(millis()/4+i*(SEGMENT.speed>>5));
|
||||||
uint8_t ylocn = cos8(strip.now/2+i*2);
|
uint8_t ylocn = cos8(millis()/4+i*2);
|
||||||
xlocn = map(xlocn,0,255,0,cols-1);
|
xlocn = map(xlocn,0,255,0,cols-1);
|
||||||
ylocn = map(ylocn,0,255,0,rows-1);
|
ylocn = map(ylocn,0,255,0,rows-1);
|
||||||
SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0));
|
SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(millis()/100+i, false, PALETTE_SOLID_WRAP, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
@ -5173,15 +5177,15 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have
|
|||||||
float speed = 0.25f * (1+(SEGMENT.speed>>6));
|
float speed = 0.25f * (1+(SEGMENT.speed>>6));
|
||||||
|
|
||||||
// get some 2 random moving points
|
// get some 2 random moving points
|
||||||
uint8_t x2 = inoise8(strip.now * speed, 25355, 685 ) / 16;
|
uint8_t x2 = map(inoise8(strip.now * speed, 25355, 685), 0, 255, 0, cols-1);
|
||||||
uint8_t y2 = inoise8(strip.now * speed, 355, 11685 ) / 16;
|
uint8_t y2 = map(inoise8(strip.now * speed, 355, 11685), 0, 255, 0, rows-1);
|
||||||
|
|
||||||
uint8_t x3 = inoise8(strip.now * speed, 55355, 6685 ) / 16;
|
uint8_t x3 = map(inoise8(strip.now * speed, 55355, 6685), 0, 255, 0, cols-1);
|
||||||
uint8_t y3 = inoise8(strip.now * speed, 25355, 22685 ) / 16;
|
uint8_t y3 = map(inoise8(strip.now * speed, 25355, 22685), 0, 255, 0, rows-1);
|
||||||
|
|
||||||
// and one Lissajou function
|
// and one Lissajou function
|
||||||
uint8_t x1 = beatsin8(23 * speed, 0, 15);
|
uint8_t x1 = beatsin8(23 * speed, 0, cols-1);
|
||||||
uint8_t y1 = beatsin8(28 * speed, 0, 15);
|
uint8_t y1 = beatsin8(28 * speed, 0, rows-1);
|
||||||
|
|
||||||
for (int y = 0; y < rows; y++) {
|
for (int y = 0; y < rows; y++) {
|
||||||
for (int x = 0; x < cols; x++) {
|
for (int x = 0; x < cols; x++) {
|
||||||
@ -5200,7 +5204,7 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have
|
|||||||
dist += sqrt16((dx * dx) + (dy * dy));
|
dist += sqrt16((dx * dx) + (dy * dy));
|
||||||
|
|
||||||
// inverse result
|
// inverse result
|
||||||
byte color = 1000 / dist;
|
byte color = dist ? 1000 / dist : 255;
|
||||||
|
|
||||||
// map color between thresholds
|
// map color between thresholds
|
||||||
if (color > 0 and color < 60) {
|
if (color > 0 and color < 60) {
|
||||||
@ -5882,20 +5886,27 @@ uint16_t mode_2Dscrollingtext(void) {
|
|||||||
else SEGENV.aux0 = (cols + (numberOfLetters * letterWidth))/2;
|
else SEGENV.aux0 = (cols + (numberOfLetters * letterWidth))/2;
|
||||||
++SEGENV.aux1 &= 0xFF; // color shift
|
++SEGENV.aux1 &= 0xFF; // color shift
|
||||||
SEGENV.step = millis() + map(SEGMENT.speed, 0, 255, 10*FRAMETIME_FIXED, 2*FRAMETIME_FIXED);
|
SEGENV.step = millis() + map(SEGMENT.speed, 0, 255, 10*FRAMETIME_FIXED, 2*FRAMETIME_FIXED);
|
||||||
|
if (!SEGMENT.check2) {
|
||||||
// we need it 3 times
|
// we need it 3 times
|
||||||
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
|
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
|
||||||
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
|
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
|
||||||
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
|
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int i = 0; i < numberOfLetters; i++) {
|
for (int i = 0; i < numberOfLetters; i++) {
|
||||||
if (int(cols) - int(SEGENV.aux0) + letterWidth*(i+1) < 0) continue; // don't draw characters off-screen
|
if (int(cols) - int(SEGENV.aux0) + letterWidth*(i+1) < 0) continue; // don't draw characters off-screen
|
||||||
SEGMENT.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, SEGMENT.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0));
|
uint32_t col1 = SEGMENT.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0);
|
||||||
|
uint32_t col2 = BLACK;
|
||||||
|
if (SEGMENT.check1 && SEGMENT.palette == 0) {
|
||||||
|
col1 = SEGCOLOR(0);
|
||||||
|
col2 = SEGCOLOR(2);
|
||||||
}
|
}
|
||||||
|
SEGMENT.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, col1, col2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size;!,!;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0";
|
static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,,Gradient,Overlay;!,!,Gradient;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0";
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
@ -7305,6 +7316,61 @@ uint16_t mode_2DAkemi(void) {
|
|||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
} // mode_2DAkemi
|
} // mode_2DAkemi
|
||||||
static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Head palette,Arms & Legs,Eyes & Mouth;Face palette;2f;si=0"; //beatsin
|
static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Head palette,Arms & Legs,Eyes & Mouth;Face palette;2f;si=0"; //beatsin
|
||||||
|
|
||||||
|
|
||||||
|
// Distortion waves - ldirko
|
||||||
|
// https://editor.soulmatelights.com/gallery/1089-distorsion-waves
|
||||||
|
// apated for WLD by @blazoncek
|
||||||
|
uint16_t mode_2Ddistortionwaves() {
|
||||||
|
if (!strip.isMatrix) return mode_static(); // not a 2D set-up
|
||||||
|
|
||||||
|
const uint16_t cols = SEGMENT.virtualWidth();
|
||||||
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
|
uint8_t speed = SEGMENT.speed/32;
|
||||||
|
uint8_t scale = SEGMENT.intensity/32;
|
||||||
|
|
||||||
|
uint8_t w = 2;
|
||||||
|
|
||||||
|
uint16_t a = millis()/32;
|
||||||
|
uint16_t a2 = a/2;
|
||||||
|
uint16_t a3 = a/3;
|
||||||
|
|
||||||
|
uint16_t cx = beatsin8(10-speed,0,cols-1)*scale;
|
||||||
|
uint16_t cy = beatsin8(12-speed,0,rows-1)*scale;
|
||||||
|
uint16_t cx1 = beatsin8(13-speed,0,cols-1)*scale;
|
||||||
|
uint16_t cy1 = beatsin8(15-speed,0,rows-1)*scale;
|
||||||
|
uint16_t cx2 = beatsin8(17-speed,0,cols-1)*scale;
|
||||||
|
uint16_t cy2 = beatsin8(14-speed,0,rows-1)*scale;
|
||||||
|
|
||||||
|
uint16_t xoffs = 0;
|
||||||
|
for (int x = 0; x < cols; x++) {
|
||||||
|
xoffs += scale;
|
||||||
|
uint16_t yoffs = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < rows; y++) {
|
||||||
|
yoffs += scale;
|
||||||
|
|
||||||
|
byte rdistort = cos8((cos8(((x<<3)+a )&255)+cos8(((y<<3)-a2)&255)+a3 )&255)>>1;
|
||||||
|
byte gdistort = cos8((cos8(((x<<3)-a2)&255)+cos8(((y<<3)+a3)&255)+a+32 )&255)>>1;
|
||||||
|
byte bdistort = cos8((cos8(((x<<3)+a3)&255)+cos8(((y<<3)-a) &255)+a2+64)&255)>>1;
|
||||||
|
|
||||||
|
byte valueR = rdistort+ w* (a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 ));
|
||||||
|
byte valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ));
|
||||||
|
byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ));
|
||||||
|
|
||||||
|
valueR = gamma8(cos8(valueR));
|
||||||
|
valueG = gamma8(cos8(valueG));
|
||||||
|
valueB = gamma8(cos8(valueB));
|
||||||
|
|
||||||
|
SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale;;;2;";
|
||||||
|
|
||||||
#endif // WLED_DISABLE_2D
|
#endif // WLED_DISABLE_2D
|
||||||
|
|
||||||
|
|
||||||
@ -7503,6 +7569,7 @@ void WS2812FX::setupEffectData() {
|
|||||||
addEffect(FX_MODE_2DBLOBS, &mode_2Dfloatingblobs, _data_FX_MODE_2DBLOBS);
|
addEffect(FX_MODE_2DBLOBS, &mode_2Dfloatingblobs, _data_FX_MODE_2DBLOBS);
|
||||||
addEffect(FX_MODE_2DSCROLLTEXT, &mode_2Dscrollingtext, _data_FX_MODE_2DSCROLLTEXT);
|
addEffect(FX_MODE_2DSCROLLTEXT, &mode_2Dscrollingtext, _data_FX_MODE_2DSCROLLTEXT);
|
||||||
addEffect(FX_MODE_2DDRIFTROSE, &mode_2Ddriftrose, _data_FX_MODE_2DDRIFTROSE);
|
addEffect(FX_MODE_2DDRIFTROSE, &mode_2Ddriftrose, _data_FX_MODE_2DDRIFTROSE);
|
||||||
|
addEffect(FX_MODE_2DDISTORTIONWAVES, &mode_2Ddistortionwaves, _data_FX_MODE_2DDISTORTIONWAVES);
|
||||||
|
|
||||||
addEffect(FX_MODE_2DGEQ, &mode_2DGEQ, _data_FX_MODE_2DGEQ); // audio
|
addEffect(FX_MODE_2DGEQ, &mode_2DGEQ, _data_FX_MODE_2DGEQ); // audio
|
||||||
|
|
||||||
|
@ -250,6 +250,7 @@
|
|||||||
#define FX_MODE_2DBLOBS 121 //gap fill
|
#define FX_MODE_2DBLOBS 121 //gap fill
|
||||||
#define FX_MODE_2DSCROLLTEXT 122 //gap fill
|
#define FX_MODE_2DSCROLLTEXT 122 //gap fill
|
||||||
#define FX_MODE_2DDRIFTROSE 123 //gap fill
|
#define FX_MODE_2DDRIFTROSE 123 //gap fill
|
||||||
|
#define FX_MODE_2DDISTORTIONWAVES 124
|
||||||
|
|
||||||
// WLED-SR effects (SR compatible IDs !!!)
|
// WLED-SR effects (SR compatible IDs !!!)
|
||||||
#define FX_MODE_PIXELS 128
|
#define FX_MODE_PIXELS 128
|
||||||
@ -588,11 +589,13 @@ typedef struct Segment {
|
|||||||
void moveX(int8_t delta);
|
void moveX(int8_t delta);
|
||||||
void moveY(int8_t delta);
|
void moveY(int8_t delta);
|
||||||
void move(uint8_t dir, uint8_t delta);
|
void move(uint8_t dir, uint8_t delta);
|
||||||
|
void draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
||||||
void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
||||||
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c);
|
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c);
|
||||||
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
|
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
|
||||||
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color);
|
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0);
|
||||||
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
|
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
|
||||||
|
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0)); } // automatic inline
|
||||||
void wu_pixel(uint32_t x, uint32_t y, CRGB c);
|
void wu_pixel(uint32_t x, uint32_t y, CRGB c);
|
||||||
void blur1d(fract8 blur_amount); // blur all rows in 1 dimension
|
void blur1d(fract8 blur_amount); // blur all rows in 1 dimension
|
||||||
void blur2d(fract8 blur_amount) { blur(blur_amount); }
|
void blur2d(fract8 blur_amount) { blur(blur_amount); }
|
||||||
|
@ -164,6 +164,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
|
|||||||
if (leds) leds[XY(x,y)] = col;
|
if (leds) leds[XY(x,y)] = col;
|
||||||
|
|
||||||
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
||||||
|
if (!_bri_t && !transitional) return;
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
byte r = scale8(R(col), _bri_t);
|
byte r = scale8(R(col), _bri_t);
|
||||||
byte g = scale8(G(col), _bri_t);
|
byte g = scale8(G(col), _bri_t);
|
||||||
@ -271,7 +272,7 @@ void Segment::addPixelColorXY(int x, int y, uint32_t color) {
|
|||||||
|
|
||||||
void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) {
|
void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) {
|
||||||
CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade);
|
CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade);
|
||||||
setPixelColor(x, y, pix);
|
setPixelColorXY(x, y, pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// blurRow: perform a blur on a row of a rectangular matrix
|
// blurRow: perform a blur on a row of a rectangular matrix
|
||||||
@ -428,6 +429,29 @@ void Segment::move(uint8_t dir, uint8_t delta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||||
|
// Bresenham’s Algorithm
|
||||||
|
int d = 3 - (2*radius);
|
||||||
|
int y = radius, x = 0;
|
||||||
|
while (y >= x) {
|
||||||
|
setPixelColorXY(cx+x, cy+y, col);
|
||||||
|
setPixelColorXY(cx-x, cy+y, col);
|
||||||
|
setPixelColorXY(cx+x, cy-y, col);
|
||||||
|
setPixelColorXY(cx-x, cy-y, col);
|
||||||
|
setPixelColorXY(cx+y, cy+x, col);
|
||||||
|
setPixelColorXY(cx-y, cy+x, col);
|
||||||
|
setPixelColorXY(cx+y, cy-x, col);
|
||||||
|
setPixelColorXY(cx-y, cy-x, col);
|
||||||
|
x++;
|
||||||
|
if (d > 0) {
|
||||||
|
y--;
|
||||||
|
d += 4 * (x - y) + 10;
|
||||||
|
} else {
|
||||||
|
d += 4 * x + 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
||||||
void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
@ -437,7 +461,7 @@ void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
|||||||
if (x * x + y * y <= radius * radius &&
|
if (x * x + y * y <= radius * radius &&
|
||||||
int16_t(cx)+x>=0 && int16_t(cy)+y>=0 &&
|
int16_t(cx)+x>=0 && int16_t(cy)+y>=0 &&
|
||||||
int16_t(cx)+x<cols && int16_t(cy)+y<rows)
|
int16_t(cx)+x<cols && int16_t(cy)+y<rows)
|
||||||
addPixelColorXY(cx + x, cy + y, col);
|
setPixelColorXY(cx + x, cy + y, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,7 +483,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
|
|||||||
const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
|
const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
|
||||||
int16_t err = (dx>dy ? dx : -dy)/2, e2;
|
int16_t err = (dx>dy ? dx : -dy)/2, e2;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
addPixelColorXY(x0,y0,c);
|
setPixelColorXY(x0,y0,c);
|
||||||
if (x0==x1 && y0==y1) break;
|
if (x0==x1 && y0==y1) break;
|
||||||
e2 = err;
|
e2 = err;
|
||||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||||
@ -475,13 +499,16 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
|
|||||||
|
|
||||||
// draws a raster font character on canvas
|
// draws a raster font character on canvas
|
||||||
// only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
|
// only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
|
||||||
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) {
|
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2) {
|
||||||
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
|
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
|
||||||
chr -= 32; // align with font table entries
|
chr -= 32; // align with font table entries
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
const int font = w*h;
|
const int font = w*h;
|
||||||
|
|
||||||
|
CRGB col = CRGB(color);
|
||||||
|
CRGBPalette16 grad = CRGBPalette16(col, col2 ? CRGB(col2) : col);
|
||||||
|
|
||||||
//if (w<5 || w>6 || h!=8) return;
|
//if (w<5 || w>6 || h!=8) return;
|
||||||
for (int i = 0; i<h; i++) { // character height
|
for (int i = 0; i<h; i++) { // character height
|
||||||
int16_t y0 = y + i;
|
int16_t y0 = y + i;
|
||||||
@ -496,10 +523,11 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
|
|||||||
case 60: bits = pgm_read_byte_near(&console_font_5x12[(chr * h) + i]); break; // 5x12 font
|
case 60: bits = pgm_read_byte_near(&console_font_5x12[(chr * h) + i]); break; // 5x12 font
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
col = ColorFromPalette(grad, (i+1)*255/h, 255, NOBLEND);
|
||||||
for (int j = 0; j<w; j++) { // character width
|
for (int j = 0; j<w; j++) { // character width
|
||||||
int16_t x0 = x + (w-1) - j;
|
int16_t x0 = x + (w-1) - j;
|
||||||
if ((x0 >= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen
|
if ((x0 >= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen
|
||||||
addPixelColorXY(x0, y0, color);
|
addPixelColorXY(x0, y0, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,12 +243,12 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
|
|||||||
_lastPaletteChange = millis();
|
_lastPaletteChange = millis();
|
||||||
timeSinceLastChange = 0;
|
timeSinceLastChange = 0;
|
||||||
}
|
}
|
||||||
if (timeSinceLastChange <= 500) {
|
if (timeSinceLastChange <= 250) {
|
||||||
targetPalette = prevRandomPalette;
|
targetPalette = prevRandomPalette;
|
||||||
// there needs to be 255 palette blends (48) for full blend but that is too resource intensive
|
// there needs to be 255 palette blends (48) for full blend but that is too resource intensive
|
||||||
// so 128 is a compromise (we need to perform full blend of the two palettes as each segment can have random
|
// so 128 is a compromise (we need to perform full blend of the two palettes as each segment can have random
|
||||||
// palette selected but only 2 static palettes are used)
|
// palette selected but only 2 static palettes are used)
|
||||||
size_t noOfBlends = ((128U * timeSinceLastChange) / 500U);
|
size_t noOfBlends = ((128U * timeSinceLastChange) / 250U);
|
||||||
for (size_t i=0; i<noOfBlends; i++) nblendPaletteTowardPalette(targetPalette, randomPalette, 48);
|
for (size_t i=0; i<noOfBlends; i++) nblendPaletteTowardPalette(targetPalette, randomPalette, 48);
|
||||||
} else {
|
} else {
|
||||||
targetPalette = randomPalette;
|
targetPalette = randomPalette;
|
||||||
@ -459,18 +459,21 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
|||||||
// load default values from effect string
|
// load default values from effect string
|
||||||
if (loadDefaults) {
|
if (loadDefaults) {
|
||||||
int16_t sOpt;
|
int16_t sOpt;
|
||||||
sOpt = extractModeDefaults(fx, "sx"); if (sOpt >= 0) speed = sOpt;
|
sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED;
|
||||||
sOpt = extractModeDefaults(fx, "ix"); if (sOpt >= 0) intensity = sOpt;
|
sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY;
|
||||||
sOpt = extractModeDefaults(fx, "c1"); if (sOpt >= 0) custom1 = sOpt;
|
sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1;
|
||||||
sOpt = extractModeDefaults(fx, "c2"); if (sOpt >= 0) custom2 = sOpt;
|
sOpt = extractModeDefaults(fx, "c2"); custom2 = (sOpt >= 0) ? sOpt : DEFAULT_C2;
|
||||||
sOpt = extractModeDefaults(fx, "c3"); if (sOpt >= 0) custom3 = sOpt;
|
sOpt = extractModeDefaults(fx, "c3"); custom3 = (sOpt >= 0) ? sOpt : DEFAULT_C3;
|
||||||
|
sOpt = extractModeDefaults(fx, "o1"); check1 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||||
|
sOpt = extractModeDefaults(fx, "o2"); check2 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||||
|
sOpt = extractModeDefaults(fx, "o3"); check3 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||||
sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7);
|
sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7);
|
||||||
sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 7);
|
sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 7);
|
||||||
sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt;
|
sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt;
|
||||||
sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business
|
sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business
|
||||||
sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt;
|
sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt;
|
||||||
sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business
|
sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business
|
||||||
sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt);
|
sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0);
|
||||||
}
|
}
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
stateChanged = true; // send UDP/WS broadcast
|
||||||
}
|
}
|
||||||
@ -574,6 +577,20 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
|||||||
int y = roundf(cos_t(rad) * i);
|
int y = roundf(cos_t(rad) * i);
|
||||||
setPixelColorXY(x, y, col);
|
setPixelColorXY(x, y, col);
|
||||||
}
|
}
|
||||||
|
// Bresenham’s Algorithm (may not fill every pixel)
|
||||||
|
//int d = 3 - (2*i);
|
||||||
|
//int y = i, x = 0;
|
||||||
|
//while (y >= x) {
|
||||||
|
// setPixelColorXY(x, y, col);
|
||||||
|
// setPixelColorXY(y, x, col);
|
||||||
|
// x++;
|
||||||
|
// if (d > 0) {
|
||||||
|
// y--;
|
||||||
|
// d += 4 * (x - y) + 10;
|
||||||
|
// } else {
|
||||||
|
// d += 4 * x + 6;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case M12_pCorner:
|
case M12_pCorner:
|
||||||
@ -596,6 +613,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
|||||||
|
|
||||||
uint16_t len = length();
|
uint16_t len = length();
|
||||||
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
||||||
|
if (!_bri_t && !transitional) return;
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
byte r = scale8(R(col), _bri_t);
|
byte r = scale8(R(col), _bri_t);
|
||||||
byte g = scale8(G(col), _bri_t);
|
byte g = scale8(G(col), _bri_t);
|
||||||
@ -908,7 +926,7 @@ uint8_t Segment::get_random_wheel_index(uint8_t pos) {
|
|||||||
* Gets a single color from the currently selected palette.
|
* Gets a single color from the currently selected palette.
|
||||||
* @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically.
|
* @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically.
|
||||||
* @param mapping if true, LED position in segment is considered for color
|
* @param mapping if true, LED position in segment is considered for color
|
||||||
* @param wrap FastLED palettes will usally wrap back to the start smoothly. Set false to get a hard edge
|
* @param wrap FastLED palettes will usually wrap back to the start smoothly. Set false to get a hard edge
|
||||||
* @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead
|
* @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead
|
||||||
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
||||||
* @returns Single color from palette
|
* @returns Single color from palette
|
||||||
@ -1056,7 +1074,7 @@ void WS2812FX::service() {
|
|||||||
//if (seg.transitional && seg._modeP) (*_mode[seg._modeP])(progress());
|
//if (seg.transitional && seg._modeP) (*_mode[seg._modeP])(progress());
|
||||||
delay = (*_mode[seg.currentMode(seg.mode)])();
|
delay = (*_mode[seg.currentMode(seg.mode)])();
|
||||||
if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++;
|
if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++;
|
||||||
if (seg.transitional && delay > FRAMETIME) delay = FRAMETIME; // foce faster updates during transition
|
if (seg.transitional && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||||
|
|
||||||
seg.handleTransition();
|
seg.handleTransition();
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,14 @@ void shortPressAction(uint8_t b)
|
|||||||
applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET);
|
applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
// publish MQTT message
|
// publish MQTT message
|
||||||
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
||||||
mqtt->publish(subuf, 0, false, "short");
|
mqtt->publish(subuf, 0, false, "short");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void longPressAction(uint8_t b)
|
void longPressAction(uint8_t b)
|
||||||
@ -43,12 +45,14 @@ void longPressAction(uint8_t b)
|
|||||||
applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET);
|
applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
// publish MQTT message
|
// publish MQTT message
|
||||||
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
||||||
mqtt->publish(subuf, 0, false, "long");
|
mqtt->publish(subuf, 0, false, "long");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void doublePressAction(uint8_t b)
|
void doublePressAction(uint8_t b)
|
||||||
@ -62,12 +66,14 @@ void doublePressAction(uint8_t b)
|
|||||||
applyPreset(macroDoublePress[b], CALL_MODE_BUTTON_PRESET);
|
applyPreset(macroDoublePress[b], CALL_MODE_BUTTON_PRESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
// publish MQTT message
|
// publish MQTT message
|
||||||
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
||||||
mqtt->publish(subuf, 0, false, "double");
|
mqtt->publish(subuf, 0, false, "double");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isButtonPressed(uint8_t i)
|
bool isButtonPressed(uint8_t i)
|
||||||
@ -119,6 +125,7 @@ void handleSwitch(uint8_t b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
// publish MQTT message
|
// publish MQTT message
|
||||||
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
@ -126,6 +133,7 @@ void handleSwitch(uint8_t b)
|
|||||||
else sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
else sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
|
||||||
mqtt->publish(subuf, 0, false, !buttonPressedBefore[b] ? "off" : "on");
|
mqtt->publish(subuf, 0, false, !buttonPressedBefore[b] ? "off" : "on");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
buttonLongPressed[b] = buttonPressedBefore[b]; //save the last "long term" switch state
|
buttonLongPressed[b] = buttonPressedBefore[b]; //save the last "long term" switch state
|
||||||
}
|
}
|
||||||
|
@ -404,6 +404,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(e131SkipOutOfSequence, if_live_dmx[F("seqskip")]);
|
CJSON(e131SkipOutOfSequence, if_live_dmx[F("seqskip")]);
|
||||||
CJSON(DMXAddress, if_live_dmx[F("addr")]);
|
CJSON(DMXAddress, if_live_dmx[F("addr")]);
|
||||||
if (!DMXAddress || DMXAddress > 510) DMXAddress = 1;
|
if (!DMXAddress || DMXAddress > 510) DMXAddress = 1;
|
||||||
|
CJSON(DMXSegmentSpacing, if_live_dmx[F("dss")]);
|
||||||
|
if (DMXSegmentSpacing > 150) DMXSegmentSpacing = 0;
|
||||||
CJSON(DMXMode, if_live_dmx["mode"]);
|
CJSON(DMXMode, if_live_dmx["mode"]);
|
||||||
|
|
||||||
tdd = if_live[F("timeout")] | -1;
|
tdd = if_live[F("timeout")] | -1;
|
||||||
@ -864,6 +866,7 @@ void serializeConfig() {
|
|||||||
if_live_dmx[F("uni")] = e131Universe;
|
if_live_dmx[F("uni")] = e131Universe;
|
||||||
if_live_dmx[F("seqskip")] = e131SkipOutOfSequence;
|
if_live_dmx[F("seqskip")] = e131SkipOutOfSequence;
|
||||||
if_live_dmx[F("addr")] = DMXAddress;
|
if_live_dmx[F("addr")] = DMXAddress;
|
||||||
|
if_live_dmx[F("dss")] = DMXSegmentSpacing;
|
||||||
if_live_dmx["mode"] = DMXMode;
|
if_live_dmx["mode"] = DMXMode;
|
||||||
|
|
||||||
if_live[F("timeout")] = realtimeTimeoutMs / 100;
|
if_live[F("timeout")] = realtimeTimeoutMs / 100;
|
||||||
|
@ -169,10 +169,14 @@
|
|||||||
#define DMX_MODE_DISABLED 0 //not used
|
#define DMX_MODE_DISABLED 0 //not used
|
||||||
#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels)
|
#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels)
|
||||||
#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels)
|
#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels)
|
||||||
#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (11 channels)
|
#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (15 channels)
|
||||||
|
#define DMX_MODE_EFFECT_W 7 //trigger standalone effects of WLED (18 channels)
|
||||||
#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels)
|
#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels)
|
||||||
#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels)
|
#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels)
|
||||||
#define DMX_MODE_MULTIPLE_RGBW 6 //every LED is addressed with its own RGBW (ledCount * 4 channels)
|
#define DMX_MODE_MULTIPLE_RGBW 6 //every LED is addressed with its own RGBW (ledCount * 4 channels)
|
||||||
|
#define DMX_MODE_EFFECT_SEGMENT 8 //trigger standalone effects of WLED (15 channels per segement)
|
||||||
|
#define DMX_MODE_EFFECT_SEGMENT_W 9 //trigger standalone effects of WLED (18 channels per segement)
|
||||||
|
#define DMX_MODE_PRESET 10 //apply presets (1 channel)
|
||||||
|
|
||||||
//Light capability byte (unused) 0bRCCCTTTT
|
//Light capability byte (unused) 0bRCCCTTTT
|
||||||
//bits 0/1/2/3: specifies a type of LED driver. A single "driver" may have different chip models but must have the same protocol/behavior
|
//bits 0/1/2/3: specifies a type of LED driver. A single "driver" may have different chip models but must have the same protocol/behavior
|
||||||
|
@ -436,6 +436,9 @@ button {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -92px;
|
margin-left: -92px;
|
||||||
|
|
||||||
|
/* Ensure tooltip goes away when mouse leaves control */
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
/* Fade in tooltip */
|
/* Fade in tooltip */
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.75s;
|
transition: opacity 0.75s;
|
||||||
|
@ -807,7 +807,7 @@ function populateSegments(s)
|
|||||||
if (!isM && !noNewSegs && (cfg.comp.seglen?parseInt(gId(`seg${lSeg}s`).value):0)+parseInt(gId(`seg${lSeg}e`).value)<ledCount) gId(`segr${lSeg}`).style.display = "inline";
|
if (!isM && !noNewSegs && (cfg.comp.seglen?parseInt(gId(`seg${lSeg}s`).value):0)+parseInt(gId(`seg${lSeg}e`).value)<ledCount) gId(`segr${lSeg}`).style.display = "inline";
|
||||||
gId('segutil2').style.display = (segCount > 1) ? "block":"none"; // rsbtn parent
|
gId('segutil2').style.display = (segCount > 1) ? "block":"none"; // rsbtn parent
|
||||||
|
|
||||||
if (Array.isArray(li.maps) && li.maps.length>1) {
|
if (!isM && Array.isArray(li.maps) && li.maps.length>1) {
|
||||||
let cont = `Ledmap: <select class="sel-sg" onchange="requestJson({'ledmap':parseInt(this.value)})"><option value="" selected>Unchanged</option>`;
|
let cont = `Ledmap: <select class="sel-sg" onchange="requestJson({'ledmap':parseInt(this.value)})"><option value="" selected>Unchanged</option>`;
|
||||||
for (const k of (li.maps||[])) cont += `<option value="${k}">${k==0?'Default':'ledmap'+k+'.json'}</option>`;
|
for (const k of (li.maps||[])) cont += `<option value="${k}">${k==0?'Default':'ledmap'+k+'.json'}</option>`;
|
||||||
cont += "</select></div>";
|
cont += "</select></div>";
|
||||||
@ -837,7 +837,7 @@ function populateEffects()
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (let ef of effects) {
|
for (let ef of effects) {
|
||||||
// WLEDSR: add slider and color control to setFX (used by requestjson)
|
// add slider and color control to setFX (used by requestjson)
|
||||||
let id = ef.id;
|
let id = ef.id;
|
||||||
let nm = ef.name+" ";
|
let nm = ef.name+" ";
|
||||||
let fd = "";
|
let fd = "";
|
||||||
@ -1362,7 +1362,7 @@ function readState(s,command=false)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WLEDSR: control HTML elements for Slider and Color Control
|
// control HTML elements for Slider and Color Control (original ported form WLED-SR)
|
||||||
// Technical notes
|
// Technical notes
|
||||||
// ===============
|
// ===============
|
||||||
// If an effect name is followed by an @, slider and color control is effective.
|
// If an effect name is followed by an @, slider and color control is effective.
|
||||||
@ -1485,6 +1485,14 @@ function setEffectParameters(idx)
|
|||||||
pall.innerHTML = '<i class="icons sel-icon" onclick="tglHex()"></i> Color palette not used';
|
pall.innerHTML = '<i class="icons sel-icon" onclick="tglHex()"></i> Color palette not used';
|
||||||
palw.style.display = "none";
|
palw.style.display = "none";
|
||||||
}
|
}
|
||||||
|
// not all color selectors shown, hide palettes created from color selectors
|
||||||
|
// NOTE: this will disallow user to select "* Color ..." palettes which may be undesirable in some cases or for some users
|
||||||
|
//for (let e of (gId('pallist').querySelectorAll('.lstI')||[])) {
|
||||||
|
// let fltr = "* C";
|
||||||
|
// if (cslCnt==1 && csel==0) fltr = "* Colors";
|
||||||
|
// else if (cslCnt==2) fltr = "* Colors Only";
|
||||||
|
// if (cslCnt < 3 && e.querySelector('.lstIname').innerText.indexOf(fltr)>=0) e.classList.add('hide'); else e.classList.remove('hide');
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonTimeout;
|
var jsonTimeout;
|
||||||
@ -1840,7 +1848,7 @@ ${makePlSel(plJson[i].end?plJson[i].end:0, true)}
|
|||||||
<input type="checkbox" id="p${i}sbchk">
|
<input type="checkbox" id="p${i}sbchk">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>`;
|
</label>`;
|
||||||
if (Array.isArray(lastinfo.maps) && lastinfo.maps.length>1) {
|
if (!isM && Array.isArray(lastinfo.maps) && lastinfo.maps.length>1) {
|
||||||
content += `<div class="lbl-l">Ledmap: <div class="sel-p"><select class="sel-p" id="p${i}lmp"><option value="">Unchanged</option>`;
|
content += `<div class="lbl-l">Ledmap: <div class="sel-p"><select class="sel-p" id="p${i}lmp"><option value="">Unchanged</option>`;
|
||||||
for (const k of (lastinfo.maps||[])) content += `<option value="${k}"${(i>0 && pJson[i].ledmap==k)?" selected":""}>${k==0?'Default':'ledmap'+k+'.json'}</option>`;
|
for (const k of (lastinfo.maps||[])) content += `<option value="${k}"${(i>0 && pJson[i].ledmap==k)?" selected":""}>${k==0?'Default':'ledmap'+k+'.json'}</option>`;
|
||||||
content += "</select></div></div>";
|
content += "</select></div></div>";
|
||||||
|
@ -68,9 +68,9 @@
|
|||||||
<button type=submit id="b" onclick="window.location='/'">Back</button>
|
<button type=submit id="b" onclick="window.location='/'">Back</button>
|
||||||
<button type="submit" onclick="window.location='./settings/wifi'">WiFi Setup</button>
|
<button type="submit" onclick="window.location='./settings/wifi'">WiFi Setup</button>
|
||||||
<button type="submit" onclick="window.location='./settings/leds'">LED Preferences</button>
|
<button type="submit" onclick="window.location='./settings/leds'">LED Preferences</button>
|
||||||
<button type="submit" onclick="window.location='./settings/2D'">2D Configuration</button>
|
<button id="2dbtn" style="display:none;" type="submit" onclick="window.location='./settings/2D'">2D Configuration</button>
|
||||||
<button type="submit" onclick="window.location='./settings/ui'">User Interface</button>
|
<button type="submit" onclick="window.location='./settings/ui'">User Interface</button>
|
||||||
<button id="dmxbtn" style="display: none;" type="submit" onclick="window.location='./settings/dmx'">DMX Output</button>
|
<button id="dmxbtn" style="display:none;" type="submit" onclick="window.location='./settings/dmx'">DMX Output</button>
|
||||||
<button type="submit" onclick="window.location='./settings/sync'">Sync Interfaces</button>
|
<button type="submit" onclick="window.location='./settings/sync'">Sync Interfaces</button>
|
||||||
<button type="submit" onclick="window.location='./settings/time'">Time & Macros</button>
|
<button type="submit" onclick="window.location='./settings/time'">Time & Macros</button>
|
||||||
<button type="submit" onclick="window.location='./settings/um'">Usermods</button>
|
<button type="submit" onclick="window.location='./settings/um'">Usermods</button>
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
var d=document,laprev=55,maxB=1,maxV=0,maxM=4000,maxPB=4096,maxL=1333,maxLbquot=0; //maximum bytes for LED allocation: 4kB for 8266, 32kB for 32
|
var d=document,laprev=55,maxB=1,maxV=0,maxM=4000,maxPB=4096,maxL=1333,maxLbquot=0; //maximum bytes for LED allocation: 4kB for 8266, 32kB for 32
|
||||||
var customStarts=false,startsDirty=[],maxCOOverrides=5;
|
var customStarts=false,startsDirty=[],maxCOOverrides=5;
|
||||||
var loc = false, locip;
|
var loc = false, locip;
|
||||||
|
d.um_p = [];
|
||||||
|
d.rsvd = [];
|
||||||
|
d.ro_gpio = [];
|
||||||
|
d.max_gpio = 39;
|
||||||
function H(){window.open("https://kno.wled.ge/features/settings/#led-settings");}
|
function H(){window.open("https://kno.wled.ge/features/settings/#led-settings");}
|
||||||
function B(){window.open("/settings","_self");}
|
function B(){window.open("/settings","_self");}
|
||||||
function gId(n){return d.getElementById(n);}
|
function gId(n){return d.getElementById(n);}
|
||||||
@ -23,10 +27,6 @@
|
|||||||
// success event
|
// success event
|
||||||
scE.addEventListener("load", () => {
|
scE.addEventListener("load", () => {
|
||||||
//console.log("File loaded");
|
//console.log("File loaded");
|
||||||
d.um_p = [];
|
|
||||||
d.rsvd = [];
|
|
||||||
d.ro_pins = [];
|
|
||||||
d.max_gpio = 39;
|
|
||||||
GetV();checkSi();setABL();
|
GetV();checkSi();setABL();
|
||||||
if (d.um_p[0]==-1) d.um_p.shift();
|
if (d.um_p[0]==-1) d.um_p.shift();
|
||||||
});
|
});
|
||||||
@ -66,7 +66,7 @@
|
|||||||
for (k=0;k<d.rsvd.length;k++) p.push(d.rsvd[k]); // fill with reservations
|
for (k=0;k<d.rsvd.length;k++) p.push(d.rsvd[k]); // fill with reservations
|
||||||
for (k=0;k<d.um_p.length;k++) p.push(d.um_p[k]); // fill with usermod pins
|
for (k=0;k<d.um_p.length;k++) p.push(d.um_p[k]); // fill with usermod pins
|
||||||
if (p.some((e)=>e==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(p)} can't be used.`);LCs[i].value="";LCs[i].focus();return false;}
|
if (p.some((e)=>e==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(p)} can't be used.`);LCs[i].value="";LCs[i].focus();return false;}
|
||||||
else if (!(nm == "IR" || nm=="BT") && d.ro_pins.some((e)=>e==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(d.ro_gpio)} are input only.`);LCs[i].value="";LCs[i].focus();return false;}
|
else if (!(nm == "IR" || nm=="BT") && d.ro_gpio.some((e)=>e==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(d.ro_gpio)} are input only.`);LCs[i].value="";LCs[i].focus();return false;}
|
||||||
for (j=i+1; j<LCs.length; j++)
|
for (j=i+1; j<LCs.length; j++)
|
||||||
{
|
{
|
||||||
var n2 = LCs[j].name.substring(0,2);
|
var n2 = LCs[j].name.substring(0,2);
|
||||||
|
@ -148,15 +148,20 @@ Start universe: <input name="EU" type="number" min="0" max="63999" required><br>
|
|||||||
<i>Reboot required.</i> Check out <a href="https://github.com/LedFx/LedFx" target="_blank">LedFx</a>!<br>
|
<i>Reboot required.</i> Check out <a href="https://github.com/LedFx/LedFx" target="_blank">LedFx</a>!<br>
|
||||||
Skip out-of-sequence packets: <input type="checkbox" name="ES"><br>
|
Skip out-of-sequence packets: <input type="checkbox" name="ES"><br>
|
||||||
DMX start address: <input name="DA" type="number" min="1" max="510" required><br>
|
DMX start address: <input name="DA" type="number" min="1" max="510" required><br>
|
||||||
|
DMX segment spacing: <input name="XX" type="number" min="0" max="150" required><br>
|
||||||
DMX mode:
|
DMX mode:
|
||||||
<select name=DM>
|
<select name=DM>
|
||||||
<option value=0>Disabled</option>
|
<option value=0>Disabled</option>
|
||||||
<option value=1>Single RGB</option>
|
<option value=1>Single RGB</option>
|
||||||
<option value=2>Single DRGB</option>
|
<option value=2>Single DRGB</option>
|
||||||
<option value=3>Effect</option>
|
<option value=3>Effect</option>
|
||||||
|
<option value=7>Effect + White</option>
|
||||||
|
<option value=8>Effect Segment</option>
|
||||||
|
<option value=9>Effect Segment + White</option>
|
||||||
<option value=4>Multi RGB</option>
|
<option value=4>Multi RGB</option>
|
||||||
<option value=5>Dimmer + Multi RGB</option>
|
<option value=5>Dimmer + Multi RGB</option>
|
||||||
<option value=6>Multi RGBW</option>
|
<option value=6>Multi RGBW</option>
|
||||||
|
<option value=10>Preset</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<a href="https://kno.wled.ge/interfaces/e1.31-dmx/" target="_blank">E1.31 info</a><br>
|
<a href="https://kno.wled.ge/interfaces/e1.31-dmx/" target="_blank">E1.31 info</a><br>
|
||||||
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
<title>Usermod Settings</title>
|
<title>Usermod Settings</title>
|
||||||
<script>
|
<script>
|
||||||
var d = document;
|
var d = document;
|
||||||
|
d.max_gpio = 39;
|
||||||
|
d.um_p = [];
|
||||||
|
d.rsvd = [];
|
||||||
|
d.ro_gpio = [];
|
||||||
var umCfg = {};
|
var umCfg = {};
|
||||||
var pins = [], pinO = [], owner;
|
var pins = [], pinO = [], owner;
|
||||||
var loc = false, locip;
|
var loc = false, locip;
|
||||||
@ -25,11 +29,6 @@
|
|||||||
d.body.appendChild(scE);
|
d.body.appendChild(scE);
|
||||||
// success event
|
// success event
|
||||||
scE.addEventListener("load", () => {
|
scE.addEventListener("load", () => {
|
||||||
//console.log("File loaded");
|
|
||||||
d.um_p = [];
|
|
||||||
d.rsvd = [];
|
|
||||||
d.ro_pins = [];
|
|
||||||
d.max_gpio = 39;
|
|
||||||
GetV();
|
GetV();
|
||||||
for (let k=0; k<d.rsvd.length; k++) { pins.push(d.rsvd[k]); pinO.push("rsvd"); }
|
for (let k=0; k<d.rsvd.length; k++) { pins.push(d.rsvd[k]); pinO.push("rsvd"); }
|
||||||
if (d.um_p[0]==-1) d.um_p.shift();
|
if (d.um_p[0]==-1) d.um_p.shift();
|
||||||
@ -38,6 +37,8 @@
|
|||||||
d.Sf.MOSI.max = d.max_gpio;
|
d.Sf.MOSI.max = d.max_gpio;
|
||||||
d.Sf.SCLK.max = d.max_gpio;
|
d.Sf.SCLK.max = d.max_gpio;
|
||||||
d.Sf.MISO.max = d.max_gpio;
|
d.Sf.MISO.max = d.max_gpio;
|
||||||
|
let inp = d.getElementsByTagName("input");
|
||||||
|
for (let i of inp) if (i.type === "number" && i.name.replace("[]","").substr(-3) === "pin") i.max = d.max_gpio;
|
||||||
});
|
});
|
||||||
// error event
|
// error event
|
||||||
scE.addEventListener("error", (ev) => {
|
scE.addEventListener("error", (ev) => {
|
||||||
|
105
wled00/e131.cpp
105
wled00/e131.cpp
@ -132,7 +132,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
|
|||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_SINGLE_RGB: // RGB only
|
case DMX_MODE_SINGLE_RGB: // 3 channel: [R,G,B]
|
||||||
if (uni != e131Universe) return;
|
if (uni != e131Universe) return;
|
||||||
if (availDMXLen < 3) return;
|
if (availDMXLen < 3) return;
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
|
|||||||
setRealtimePixel(i, e131_data[dataOffset+0], e131_data[dataOffset+1], e131_data[dataOffset+2], wChannel);
|
setRealtimePixel(i, e131_data[dataOffset+0], e131_data[dataOffset+1], e131_data[dataOffset+2], wChannel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_SINGLE_DRGB: // Dimmer + RGB
|
case DMX_MODE_SINGLE_DRGB: // 4 channel: [Dimmer,R,G,B]
|
||||||
if (uni != e131Universe) return;
|
if (uni != e131Universe) return;
|
||||||
if (availDMXLen < 4) return;
|
if (availDMXLen < 4) return;
|
||||||
|
|
||||||
@ -162,38 +162,77 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
|
|||||||
setRealtimePixel(i, e131_data[dataOffset+1], e131_data[dataOffset+2], e131_data[dataOffset+3], wChannel);
|
setRealtimePixel(i, e131_data[dataOffset+1], e131_data[dataOffset+2], e131_data[dataOffset+3], wChannel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_EFFECT: // Length 1: Apply Preset ID, length 11-13: apply effect config
|
case DMX_MODE_PRESET: // 2 channel: [Dimmer,Preset]
|
||||||
if (uni != e131Universe) return;
|
if (uni != e131Universe || availDMXLen < 2) return;
|
||||||
if (availDMXLen < 11) {
|
applyPreset(e131_data[dataOffset+1], CALL_MODE_NOTIFICATION);
|
||||||
if (availDMXLen > 1) return;
|
if (bri != e131_data[dataOffset]) {
|
||||||
applyPreset(e131_data[dataOffset+0], CALL_MODE_NOTIFICATION);
|
bri = e131_data[dataOffset];
|
||||||
|
strip.setBrightness(bri, true);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (bri != e131_data[dataOffset+0]) {
|
|
||||||
bri = e131_data[dataOffset+0];
|
|
||||||
}
|
|
||||||
if (e131_data[dataOffset+1] < strip.getModeCount())
|
|
||||||
effectCurrent = e131_data[dataOffset+ 1];
|
|
||||||
effectSpeed = e131_data[dataOffset+ 2]; // flickers
|
|
||||||
effectIntensity = e131_data[dataOffset+ 3];
|
|
||||||
effectPalette = e131_data[dataOffset+ 4];
|
|
||||||
col[0] = e131_data[dataOffset+ 5];
|
|
||||||
col[1] = e131_data[dataOffset+ 6];
|
|
||||||
col[2] = e131_data[dataOffset+ 7];
|
|
||||||
colSec[0] = e131_data[dataOffset+ 8];
|
|
||||||
colSec[1] = e131_data[dataOffset+ 9];
|
|
||||||
colSec[2] = e131_data[dataOffset+10];
|
|
||||||
if (availDMXLen > 11)
|
|
||||||
{
|
|
||||||
col[3] = e131_data[dataOffset+11]; //white
|
|
||||||
colSec[3] = e131_data[dataOffset+12];
|
|
||||||
}
|
|
||||||
transitionDelayTemp = 0; // act fast
|
|
||||||
colorUpdated(CALL_MODE_NOTIFICATION); // don't send UDP
|
|
||||||
return; // don't activate realtime live mode
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DMX_MODE_EFFECT: // 15 channels [bri,effectCurrent,effectSpeed,effectIntensity,effectPalette,effectOption,R,G,B,R2,G2,B2,R3,G3,B3]
|
||||||
|
case DMX_MODE_EFFECT_W: // 18 channels, same as above but with extra +3 white channels [..,W,W2,W3]
|
||||||
|
case DMX_MODE_EFFECT_SEGMENT: // 15 channels per segment;
|
||||||
|
case DMX_MODE_EFFECT_SEGMENT_W: // 18 Channels per segment;
|
||||||
|
{
|
||||||
|
if (uni != e131Universe) return;
|
||||||
|
bool isSegmentMode = DMXMode == DMX_MODE_EFFECT_SEGMENT || DMXMode == DMX_MODE_EFFECT_SEGMENT_W;
|
||||||
|
uint8_t dmxEffectChannels = (DMXMode == DMX_MODE_EFFECT || DMXMode == DMX_MODE_EFFECT_SEGMENT) ? 15 : 18;
|
||||||
|
for (uint8_t id = 0; id < strip.getSegmentsNum(); id++) {
|
||||||
|
Segment& seg = strip.getSegment(id);
|
||||||
|
if (isSegmentMode)
|
||||||
|
dataOffset = DMXAddress + id * (dmxEffectChannels + DMXSegmentSpacing);
|
||||||
|
else
|
||||||
|
dataOffset = DMXAddress;
|
||||||
|
// Modify address for Art-Net data
|
||||||
|
if (protocol == P_ARTNET && dataOffset > 0)
|
||||||
|
dataOffset--;
|
||||||
|
// Skip out of universe addresses
|
||||||
|
if (dataOffset > dmxChannels - dmxEffectChannels + 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (e131_data[dataOffset+1] < strip.getModeCount())
|
||||||
|
if (e131_data[dataOffset+1] != seg.mode) seg.setMode( e131_data[dataOffset+1]);
|
||||||
|
if (e131_data[dataOffset+2] != seg.speed) seg.speed = e131_data[dataOffset+2];
|
||||||
|
if (e131_data[dataOffset+3] != seg.intensity) seg.intensity = e131_data[dataOffset+3];
|
||||||
|
if (e131_data[dataOffset+4] != seg.palette) seg.setPalette(e131_data[dataOffset+4]);
|
||||||
|
|
||||||
|
uint8_t segOption = (uint8_t)floor(e131_data[dataOffset+5]/64.0);
|
||||||
|
if (segOption == 0 && (seg.mirror || seg.reverse )) {seg.setOption(SEG_OPTION_MIRROR, false); seg.setOption(SEG_OPTION_REVERSED, false);}
|
||||||
|
if (segOption == 1 && (seg.mirror || !seg.reverse)) {seg.setOption(SEG_OPTION_MIRROR, false); seg.setOption(SEG_OPTION_REVERSED, true);}
|
||||||
|
if (segOption == 2 && (!seg.mirror || seg.reverse )) {seg.setOption(SEG_OPTION_MIRROR, true); seg.setOption(SEG_OPTION_REVERSED, false);}
|
||||||
|
if (segOption == 3 && (!seg.mirror || !seg.reverse)) {seg.setOption(SEG_OPTION_MIRROR, true); seg.setOption(SEG_OPTION_REVERSED, true);}
|
||||||
|
|
||||||
|
uint32_t colors[3];
|
||||||
|
byte whites[3] = {0,0,0};
|
||||||
|
if (dmxEffectChannels == 18) {
|
||||||
|
whites[0] = e131_data[dataOffset+15];
|
||||||
|
whites[1] = e131_data[dataOffset+16];
|
||||||
|
whites[2] = e131_data[dataOffset+17];
|
||||||
|
}
|
||||||
|
colors[0] = RGBW32(e131_data[dataOffset+ 6], e131_data[dataOffset+ 7], e131_data[dataOffset+ 8], whites[0]);
|
||||||
|
colors[1] = RGBW32(e131_data[dataOffset+ 9], e131_data[dataOffset+10], e131_data[dataOffset+11], whites[1]);
|
||||||
|
colors[2] = RGBW32(e131_data[dataOffset+12], e131_data[dataOffset+13], e131_data[dataOffset+14], whites[2]);
|
||||||
|
if (colors[0] != seg.colors[0]) seg.setColor(0, colors[0]);
|
||||||
|
if (colors[1] != seg.colors[1]) seg.setColor(1, colors[1]);
|
||||||
|
if (colors[2] != seg.colors[2]) seg.setColor(2, colors[2]);
|
||||||
|
|
||||||
|
// Set segment opacity or global brightness
|
||||||
|
if (isSegmentMode) {
|
||||||
|
if (e131_data[dataOffset] != seg.opacity) seg.setOpacity(e131_data[dataOffset]);
|
||||||
|
} else if ( id == strip.getSegmentsNum()-1 ) {
|
||||||
|
if (bri != e131_data[dataOffset]) {
|
||||||
|
bri = e131_data[dataOffset];
|
||||||
|
strip.setBrightness(bri, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DMX_MODE_MULTIPLE_DRGB:
|
case DMX_MODE_MULTIPLE_DRGB:
|
||||||
case DMX_MODE_MULTIPLE_RGB:
|
case DMX_MODE_MULTIPLE_RGB:
|
||||||
case DMX_MODE_MULTIPLE_RGBW:
|
case DMX_MODE_MULTIPLE_RGBW:
|
||||||
@ -279,7 +318,11 @@ void handleArtnetPollReply(IPAddress ipAddress) {
|
|||||||
|
|
||||||
case DMX_MODE_SINGLE_RGB:
|
case DMX_MODE_SINGLE_RGB:
|
||||||
case DMX_MODE_SINGLE_DRGB:
|
case DMX_MODE_SINGLE_DRGB:
|
||||||
|
case DMX_MODE_PRESET:
|
||||||
case DMX_MODE_EFFECT:
|
case DMX_MODE_EFFECT:
|
||||||
|
case DMX_MODE_EFFECT_W:
|
||||||
|
case DMX_MODE_EFFECT_SEGMENT:
|
||||||
|
case DMX_MODE_EFFECT_SEGMENT_W:
|
||||||
break; // 1 universe is enough
|
break; // 1 universe is enough
|
||||||
|
|
||||||
case DMX_MODE_MULTIPLE_DRGB:
|
case DMX_MODE_MULTIPLE_DRGB:
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
#ifndef WLED_FCN_DECLARE_H
|
#ifndef WLED_FCN_DECLARE_H
|
||||||
#define WLED_FCN_DECLARE_H
|
#define WLED_FCN_DECLARE_H
|
||||||
#include <Arduino.h>
|
|
||||||
#include "src/dependencies/espalexa/EspalexaDevice.h"
|
|
||||||
#include "src/dependencies/e131/ESPAsyncE131.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All globally accessible functions are declared here
|
* All globally accessible functions are declared here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//alexa.cpp
|
//alexa.cpp
|
||||||
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
void onAlexaChange(EspalexaDevice* dev);
|
void onAlexaChange(EspalexaDevice* dev);
|
||||||
void alexaInit();
|
void alexaInit();
|
||||||
void handleAlexa();
|
void handleAlexa();
|
||||||
void onAlexaChange(EspalexaDevice* dev);
|
void onAlexaChange(EspalexaDevice* dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
//blynk.cpp
|
//blynk.cpp
|
||||||
#ifndef WLED_DISABLE_BLYNK
|
#ifndef WLED_DISABLE_BLYNK
|
||||||
|
1498
wled00/html_other.h
1498
wled00/html_other.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2241
wled00/html_simple.h
2241
wled00/html_simple.h
File diff suppressed because it is too large
Load Diff
3104
wled00/html_ui.h
3104
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -170,13 +170,20 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_2D
|
||||||
|
bool reverse = seg.reverse;
|
||||||
|
bool mirror = seg.mirror;
|
||||||
|
#endif
|
||||||
seg.selected = elem["sel"] | seg.selected;
|
seg.selected = elem["sel"] | seg.selected;
|
||||||
seg.reverse = elem["rev"] | seg.reverse;
|
seg.reverse = elem["rev"] | seg.reverse;
|
||||||
seg.mirror = elem["mi"] | seg.mirror;
|
seg.mirror = elem["mi"] | seg.mirror;
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
|
bool reverse_y = seg.reverse_y;
|
||||||
|
bool mirror_y = seg.mirror_y;
|
||||||
seg.reverse_y = elem["rY"] | seg.reverse_y;
|
seg.reverse_y = elem["rY"] | seg.reverse_y;
|
||||||
seg.mirror_y = elem["mY"] | seg.mirror_y;
|
seg.mirror_y = elem["mY"] | seg.mirror_y;
|
||||||
seg.transpose = elem[F("tp")] | seg.transpose;
|
seg.transpose = elem[F("tp")] | seg.transpose;
|
||||||
|
if (seg.is2D() && seg.map1D2D == M12_pArc && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.fill(BLACK); // clear entire segment (in case of Arc 1D to 2D expansion)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte fx = seg.mode;
|
byte fx = seg.mode;
|
||||||
@ -221,11 +228,11 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
for (size_t i = 0; i < iarr.size(); i++) {
|
for (size_t i = 0; i < iarr.size(); i++) {
|
||||||
if(iarr[i].is<JsonInteger>()) {
|
if(iarr[i].is<JsonInteger>()) {
|
||||||
if (!set) {
|
if (!set) {
|
||||||
start = iarr[i];
|
start = abs(iarr[i].as<int>());
|
||||||
set = 1;
|
set++;
|
||||||
} else {
|
} else {
|
||||||
stop = iarr[i];
|
stop = abs(iarr[i].as<int>());
|
||||||
set = 2;
|
set++;
|
||||||
}
|
}
|
||||||
} else { //color
|
} else { //color
|
||||||
uint8_t rgbw[] = {0,0,0,0};
|
uint8_t rgbw[] = {0,0,0,0};
|
||||||
@ -241,16 +248,13 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set < 2) stop = start + 1;
|
if (set < 2 || stop <= start) stop = start + 1;
|
||||||
uint32_t c = gamma32(RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]));
|
uint32_t c = gamma32(RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]));
|
||||||
for (int i = start; i < stop; i++) {
|
while (start < stop) seg.setPixelColor(start++, c);
|
||||||
seg.setPixelColor(i, c);
|
|
||||||
}
|
|
||||||
if (!set) start++;
|
|
||||||
set = 0;
|
set = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strip.trigger();
|
strip.trigger(); // force segment update
|
||||||
}
|
}
|
||||||
// send UDP/WS if segment options changed (except selection; will also deselect current preset)
|
// send UDP/WS if segment options changed (except selection; will also deselect current preset)
|
||||||
if (seg.differs(prev) & 0x7F) stateChanged = true;
|
if (seg.differs(prev) & 0x7F) stateChanged = true;
|
||||||
@ -477,11 +481,13 @@ void serializeSegment(JsonObject& root, Segment& seg, byte id, bool forPreset, b
|
|||||||
root["sel"] = seg.isSelected();
|
root["sel"] = seg.isSelected();
|
||||||
root["rev"] = seg.reverse;
|
root["rev"] = seg.reverse;
|
||||||
root["mi"] = seg.mirror;
|
root["mi"] = seg.mirror;
|
||||||
|
#ifndef WLED_DISABLE_2D
|
||||||
if (strip.isMatrix) {
|
if (strip.isMatrix) {
|
||||||
root["rY"] = seg.reverse_y;
|
root["rY"] = seg.reverse_y;
|
||||||
root["mY"] = seg.mirror_y;
|
root["mY"] = seg.mirror_y;
|
||||||
root[F("tp")] = seg.transpose;
|
root[F("tp")] = seg.transpose;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
root["o1"] = seg.check1;
|
root["o1"] = seg.check1;
|
||||||
root["o2"] = seg.check2;
|
root["o2"] = seg.check2;
|
||||||
root["o3"] = seg.check3;
|
root["o3"] = seg.check3;
|
||||||
|
@ -180,7 +180,9 @@ void handleTransitions()
|
|||||||
{
|
{
|
||||||
//handle still pending interface update
|
//handle still pending interface update
|
||||||
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > INTERFACE_UPDATE_COOLDOWN) updateInterfaces(interfaceUpdateCallMode);
|
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > INTERFACE_UPDATE_COOLDOWN) updateInterfaces(interfaceUpdateCallMode);
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
if (doPublishMqtt) publishMqtt();
|
if (doPublishMqtt) publishMqtt();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (transitionActive && transitionDelayTemp > 0)
|
if (transitionActive && transitionDelayTemp > 0)
|
||||||
{
|
{
|
||||||
|
@ -177,8 +177,4 @@ bool initMqtt()
|
|||||||
mqtt->connect();
|
mqtt->connect();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
bool initMqtt(){return false;}
|
|
||||||
void publishMqtt(){}
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -284,8 +284,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (t >= 0 && t <= 63999) e131Universe = t;
|
if (t >= 0 && t <= 63999) e131Universe = t;
|
||||||
t = request->arg(F("DA")).toInt();
|
t = request->arg(F("DA")).toInt();
|
||||||
if (t >= 0 && t <= 510) DMXAddress = t;
|
if (t >= 0 && t <= 510) DMXAddress = t;
|
||||||
|
t = request->arg(F("XX")).toInt();
|
||||||
|
if (t >= 0 && t <= 150) DMXSegmentSpacing = t;
|
||||||
t = request->arg(F("DM")).toInt();
|
t = request->arg(F("DM")).toInt();
|
||||||
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_MULTIPLE_RGBW) DMXMode = t;
|
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_PRESET) DMXMode = t;
|
||||||
t = request->arg(F("ET")).toInt();
|
t = request->arg(F("ET")).toInt();
|
||||||
if (t > 99 && t <= 65000) realtimeTimeoutMs = t;
|
if (t > 99 && t <= 65000) realtimeTimeoutMs = t;
|
||||||
arlsForceMaxBri = request->hasArg(F("FB"));
|
arlsForceMaxBri = request->hasArg(F("FB"));
|
||||||
@ -681,7 +683,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
|
|
||||||
lastEditTime = millis();
|
lastEditTime = millis();
|
||||||
if (subPage != 2 && !doReboot) doSerializeConfig = true; //serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
if (subPage != 2 && !doReboot) doSerializeConfig = true; //serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
||||||
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
if (subPage == 4) alexaInit();
|
if (subPage == 4) alexaInit();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,9 @@ void WLED::loop()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
handleTime();
|
handleTime();
|
||||||
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too
|
handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too
|
||||||
|
#endif
|
||||||
handleConnection();
|
handleConnection();
|
||||||
handleSerial();
|
handleSerial();
|
||||||
handleNotifications();
|
handleNotifications();
|
||||||
@ -64,7 +66,9 @@ void WLED::loop()
|
|||||||
|
|
||||||
yield();
|
yield();
|
||||||
handleIO();
|
handleIO();
|
||||||
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
handleIR();
|
handleIR();
|
||||||
|
#endif
|
||||||
#ifndef WLED_DISABLE_ALEXA
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
handleAlexa();
|
handleAlexa();
|
||||||
#endif
|
#endif
|
||||||
@ -135,7 +139,9 @@ void WLED::loop()
|
|||||||
}
|
}
|
||||||
if (millis() - lastMqttReconnectAttempt > 30000 || lastMqttReconnectAttempt == 0) { // lastMqttReconnectAttempt==0 forces immediate broadcast
|
if (millis() - lastMqttReconnectAttempt > 30000 || lastMqttReconnectAttempt == 0) { // lastMqttReconnectAttempt==0 forces immediate broadcast
|
||||||
lastMqttReconnectAttempt = millis();
|
lastMqttReconnectAttempt = millis();
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
initMqtt();
|
initMqtt();
|
||||||
|
#endif
|
||||||
yield();
|
yield();
|
||||||
// refresh WLED nodes list
|
// refresh WLED nodes list
|
||||||
refreshNodeList();
|
refreshNodeList();
|
||||||
@ -414,8 +420,10 @@ void WLED::setup()
|
|||||||
|
|
||||||
// fill in unique mdns default
|
// fill in unique mdns default
|
||||||
if (strcmp(cmDNS, "x") == 0) sprintf_P(cmDNS, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
if (strcmp(cmDNS, "x") == 0) sprintf_P(cmDNS, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
if (mqttDeviceTopic[0] == 0) sprintf_P(mqttDeviceTopic, PSTR("wled/%*s"), 6, escapedMac.c_str() + 6);
|
if (mqttDeviceTopic[0] == 0) sprintf_P(mqttDeviceTopic, PSTR("wled/%*s"), 6, escapedMac.c_str() + 6);
|
||||||
if (mqttClientID[0] == 0) sprintf_P(mqttClientID, PSTR("WLED-%*s"), 6, escapedMac.c_str() + 6);
|
if (mqttClientID[0] == 0) sprintf_P(mqttClientID, PSTR("WLED-%*s"), 6, escapedMac.c_str() + 6);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_ADALIGHT
|
#ifdef WLED_ENABLE_ADALIGHT
|
||||||
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
|
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
|
||||||
@ -674,9 +682,11 @@ void WLED::initInterfaces()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
// init Alexa hue emulation
|
// init Alexa hue emulation
|
||||||
if (alexaEnabled)
|
if (alexaEnabled)
|
||||||
alexaInit();
|
alexaInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_OTA
|
#ifndef WLED_DISABLE_OTA
|
||||||
if (aOtaEnabled)
|
if (aOtaEnabled)
|
||||||
@ -715,7 +725,9 @@ void WLED::initInterfaces()
|
|||||||
e131.begin(e131Multicast, e131Port, e131Universe, E131_MAX_UNIVERSE_COUNT);
|
e131.begin(e131Multicast, e131Port, e131Universe, E131_MAX_UNIVERSE_COUNT);
|
||||||
ddp.begin(false, DDP_DEFAULT_PORT);
|
ddp.begin(false, DDP_DEFAULT_PORT);
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
initMqtt();
|
initMqtt();
|
||||||
|
#endif
|
||||||
interfacesInited = true;
|
interfacesInited = true;
|
||||||
wasConnected = true;
|
wasConnected = true;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2301030
|
#define VERSION 2301170
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -121,6 +121,7 @@
|
|||||||
#define ESPALEXA_MAXDEVICES 10
|
#define ESPALEXA_MAXDEVICES 10
|
||||||
// #define ESPALEXA_DEBUG
|
// #define ESPALEXA_DEBUG
|
||||||
#include "src/dependencies/espalexa/Espalexa.h"
|
#include "src/dependencies/espalexa/Espalexa.h"
|
||||||
|
#include "src/dependencies/espalexa/EspalexaDevice.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_DISABLE_BLYNK
|
#ifndef WLED_DISABLE_BLYNK
|
||||||
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
|
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
|
||||||
@ -135,7 +136,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/dependencies/e131/ESPAsyncE131.h"
|
#include "src/dependencies/e131/ESPAsyncE131.h"
|
||||||
|
#ifdef WLED_ENABLE_MQTT
|
||||||
#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h"
|
#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ARDUINOJSON_DECODE_UNICODE 0
|
#define ARDUINOJSON_DECODE_UNICODE 0
|
||||||
#include "src/dependencies/json/AsyncJson-v6.h"
|
#include "src/dependencies/json/AsyncJson-v6.h"
|
||||||
@ -402,12 +405,18 @@ WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings fo
|
|||||||
WLED_GLOBAL uint16_t e131Port _INIT(5568); // DMX in port. E1.31 default is 5568, Art-Net is 6454
|
WLED_GLOBAL uint16_t e131Port _INIT(5568); // DMX in port. E1.31 default is 5568, Art-Net is 6454
|
||||||
WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.)
|
WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.)
|
||||||
WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol]
|
WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol]
|
||||||
|
WLED_GLOBAL uint16_t DMXSegmentSpacing _INIT(0); // Number of void/unused channels between each segments DMX channels
|
||||||
WLED_GLOBAL byte e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss
|
WLED_GLOBAL byte e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss
|
||||||
WLED_GLOBAL bool e131Multicast _INIT(false); // multicast or unicast
|
WLED_GLOBAL bool e131Multicast _INIT(false); // multicast or unicast
|
||||||
WLED_GLOBAL bool e131SkipOutOfSequence _INIT(false); // freeze instead of flickering
|
WLED_GLOBAL bool e131SkipOutOfSequence _INIT(false); // freeze instead of flickering
|
||||||
WLED_GLOBAL uint16_t pollReplyCount _INIT(0); // count number of replies for ArtPoll node report
|
WLED_GLOBAL uint16_t pollReplyCount _INIT(0); // count number of replies for ArtPoll node report
|
||||||
|
|
||||||
|
// mqtt
|
||||||
|
WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0); // used for other periodic tasks too
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
|
WLED_GLOBAL AsyncMqttClient *mqtt _INIT(NULL);
|
||||||
WLED_GLOBAL bool mqttEnabled _INIT(false);
|
WLED_GLOBAL bool mqttEnabled _INIT(false);
|
||||||
|
WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers
|
||||||
WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac)
|
WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac)
|
||||||
WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices)
|
WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices)
|
||||||
WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL)
|
WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL)
|
||||||
@ -415,6 +424,10 @@ WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username
|
|||||||
WLED_GLOBAL char mqttPass[65] _INIT(""); // optional: password for MQTT auth
|
WLED_GLOBAL char mqttPass[65] _INIT(""); // optional: password for MQTT auth
|
||||||
WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID
|
WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID
|
||||||
WLED_GLOBAL uint16_t mqttPort _INIT(1883);
|
WLED_GLOBAL uint16_t mqttPort _INIT(1883);
|
||||||
|
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())
|
||||||
|
#else
|
||||||
|
#define WLED_MQTT_CONNECTED false
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_HUESYNC
|
#ifndef WLED_DISABLE_HUESYNC
|
||||||
WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state
|
WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state
|
||||||
@ -590,11 +603,8 @@ WLED_GLOBAL uint8_t tpmPacketCount _INIT(0);
|
|||||||
WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0);
|
WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0);
|
||||||
WLED_GLOBAL bool useMainSegmentOnly _INIT(false);
|
WLED_GLOBAL bool useMainSegmentOnly _INIT(false);
|
||||||
|
|
||||||
// mqtt
|
|
||||||
WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0);
|
|
||||||
WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0);
|
WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0);
|
||||||
WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT);
|
WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT);
|
||||||
WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers
|
|
||||||
|
|
||||||
// alexa udp
|
// alexa udp
|
||||||
WLED_GLOBAL String escapedMac;
|
WLED_GLOBAL String escapedMac;
|
||||||
@ -655,8 +665,7 @@ WLED_GLOBAL AsyncWebServer server _INIT_N(((80)));
|
|||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
WLED_GLOBAL AsyncWebSocket ws _INIT_N((("/ws")));
|
WLED_GLOBAL AsyncWebSocket ws _INIT_N((("/ws")));
|
||||||
#endif
|
#endif
|
||||||
WLED_GLOBAL AsyncClient* hueClient _INIT(NULL);
|
WLED_GLOBAL AsyncClient *hueClient _INIT(NULL);
|
||||||
WLED_GLOBAL AsyncMqttClient* mqtt _INIT(NULL);
|
|
||||||
WLED_GLOBAL AsyncWebHandler *editHandler _INIT(nullptr);
|
WLED_GLOBAL AsyncWebHandler *editHandler _INIT(nullptr);
|
||||||
|
|
||||||
// udp interface objects
|
// udp interface objects
|
||||||
@ -766,7 +775,6 @@ WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
|
|||||||
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
|
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
|
||||||
#endif
|
#endif
|
||||||
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
|
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
|
||||||
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())
|
|
||||||
|
|
||||||
#ifndef WLED_AP_SSID_UNIQUE
|
#ifndef WLED_AP_SSID_UNIQUE
|
||||||
#define WLED_SET_AP_SSID() do { \
|
#define WLED_SET_AP_SSID() do { \
|
||||||
|
@ -599,10 +599,14 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
|
|||||||
case 4: response = request->beginResponse_P(200, "text/html", PAGE_settings_sync, PAGE_settings_sync_length); break;
|
case 4: response = request->beginResponse_P(200, "text/html", PAGE_settings_sync, PAGE_settings_sync_length); break;
|
||||||
case 5: response = request->beginResponse_P(200, "text/html", PAGE_settings_time, PAGE_settings_time_length); break;
|
case 5: response = request->beginResponse_P(200, "text/html", PAGE_settings_time, PAGE_settings_time_length); break;
|
||||||
case 6: response = request->beginResponse_P(200, "text/html", PAGE_settings_sec, PAGE_settings_sec_length); break;
|
case 6: response = request->beginResponse_P(200, "text/html", PAGE_settings_sec, PAGE_settings_sec_length); break;
|
||||||
|
#ifdef WLED_ENABLE_DMX
|
||||||
case 7: response = request->beginResponse_P(200, "text/html", PAGE_settings_dmx, PAGE_settings_dmx_length); break;
|
case 7: response = request->beginResponse_P(200, "text/html", PAGE_settings_dmx, PAGE_settings_dmx_length); break;
|
||||||
|
#endif
|
||||||
case 8: response = request->beginResponse_P(200, "text/html", PAGE_settings_um, PAGE_settings_um_length); break;
|
case 8: response = request->beginResponse_P(200, "text/html", PAGE_settings_um, PAGE_settings_um_length); break;
|
||||||
case 9: response = request->beginResponse_P(200, "text/html", PAGE_update, PAGE_update_length); break;
|
case 9: response = request->beginResponse_P(200, "text/html", PAGE_update, PAGE_update_length); break;
|
||||||
|
#ifndef WLED_DISABLE_2D
|
||||||
case 10: response = request->beginResponse_P(200, "text/html", PAGE_settings_2D, PAGE_settings_2D_length); break;
|
case 10: response = request->beginResponse_P(200, "text/html", PAGE_settings_2D, PAGE_settings_2D_length); break;
|
||||||
|
#endif
|
||||||
case 251: {
|
case 251: {
|
||||||
correctPIN = !strlen(settingsPIN); // lock if a pin is set
|
correctPIN = !strlen(settingsPIN); // lock if a pin is set
|
||||||
createEditHandler(correctPIN);
|
createEditHandler(correctPIN);
|
||||||
|
@ -287,6 +287,9 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
|
|
||||||
if (subPage == 0)
|
if (subPage == 0)
|
||||||
{
|
{
|
||||||
|
#ifndef WLED_DISABLE_2D // include only if 2D is compiled in
|
||||||
|
oappend(PSTR("gId('2dbtn').style.display='';"));
|
||||||
|
#endif
|
||||||
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
|
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
|
||||||
oappend(PSTR("gId('dmxbtn').style.display='';"));
|
oappend(PSTR("gId('dmxbtn').style.display='';"));
|
||||||
#endif
|
#endif
|
||||||
@ -505,6 +508,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',SET_F("EM"),e131Multicast);
|
sappend('c',SET_F("EM"),e131Multicast);
|
||||||
sappend('v',SET_F("EU"),e131Universe);
|
sappend('v',SET_F("EU"),e131Universe);
|
||||||
sappend('v',SET_F("DA"),DMXAddress);
|
sappend('v',SET_F("DA"),DMXAddress);
|
||||||
|
sappend('v',SET_F("XX"),DMXSegmentSpacing);
|
||||||
sappend('v',SET_F("DM"),DMXMode);
|
sappend('v',SET_F("DM"),DMXMode);
|
||||||
sappend('v',SET_F("ET"),realtimeTimeoutMs);
|
sappend('v',SET_F("ET"),realtimeTimeoutMs);
|
||||||
sappend('c',SET_F("FB"),arlsForceMaxBri);
|
sappend('c',SET_F("FB"),arlsForceMaxBri);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user