Merge branch 'main' into 0_15

This commit is contained in:
Blaz Kristan 2023-09-24 16:59:27 +02:00
commit d011ca0626
7 changed files with 53 additions and 39 deletions

View File

@ -1,12 +1,17 @@
## WLED changelog ## WLED changelog
#### Build 2309240
- Release of WLED beta version 0.14.0-b6 "Hoshi"
- Effect bugfixes and improvements (Meteor, Meteor Smooth, Scrolling Text)
- audioreactive: bugfixes for ES8388 and ES7243 init; minor improvements for analog inputs
#### Build 2309100 #### Build 2309100
- Release of WLED beta version 0.14.0-b5 "Hoshi" - Release of WLED beta version 0.14.0-b5 "Hoshi"
- New standard esp32 build with audioreactive - New standard esp32 build with audioreactive
- Effect blending bugfixes, and minor optimizations - Effect blending bugfixes, and minor optimizations
#### Build 2309050 #### Build 2309050
- Effect blending (#3311) (finally efect transitions!) - Effect blending (#3311) (finally effect transitions!)
*WARNING*: May not work well with ESP8266, with plenty of segments or usermods (low RAM condition)!!! *WARNING*: May not work well with ESP8266, with plenty of segments or usermods (low RAM condition)!!!
- Added receive and send sync groups to JSON API (#3317) (you can change sync groups using preset) - Added receive and send sync groups to JSON API (#3317) (you can change sync groups using preset)
- Internal temperature usermod (#3246) - Internal temperature usermod (#3246)
@ -35,7 +40,7 @@
- Preset cycle bugfix (#3262) - Preset cycle bugfix (#3262)
- Rotary encoder ALT fix for large LED count (#3276) - Rotary encoder ALT fix for large LED count (#3276)
- effect updates (2D Plasmaball), `blur()` speedup - effect updates (2D Plasmaball), `blur()` speedup
- On/Off toggle from nodes view (may show unknow device type on older versions) (#3291) - On/Off toggle from nodes view (may show unknown device type on older versions) (#3291)
- various fixes and improvements (ABL, crashes when changing presets with different segments) - various fixes and improvements (ABL, crashes when changing presets with different segments)
#### Build 2306270 #### Build 2306270
@ -48,7 +53,7 @@
#### Build 2306210 #### Build 2306210
- 0.14.0-b3 release - 0.14.0-b3 release
- respect global I2C in all usermods (no local initilaisation of I2C bus) - respect global I2C in all usermods (no local initialization of I2C bus)
- Multi relay usermod compile-time enabled option (-D MULTI_RELAY_ENABLED=true|false) - Multi relay usermod compile-time enabled option (-D MULTI_RELAY_ENABLED=true|false)
#### Build 2306180 #### Build 2306180
@ -74,7 +79,7 @@
#### Build 2306020 #### Build 2306020
- Support for segment sets (PR #3171) - Support for segment sets (PR #3171)
- Reduce sound simulation modes to 2 to facilitiate segment sets - Reduce sound simulation modes to 2 to facilitate segment sets
- Trigger button immediately on press if all configured presets are the same (PR #3226) - Trigger button immediately on press if all configured presets are the same (PR #3226)
- Changes for allowing Alexa to change light color to White when auto-calculating from RGB (PR #3211) - Changes for allowing Alexa to change light color to White when auto-calculating from RGB (PR #3211)

View File

@ -1184,6 +1184,7 @@ class AudioReactive : public Usermod {
DEBUGSR_PRINTLN(F("AR: Analog Microphone (left channel only).")); DEBUGSR_PRINTLN(F("AR: Analog Microphone (left channel only)."));
audioSource = new I2SAdcSource(SAMPLE_RATE, BLOCK_SIZE); audioSource = new I2SAdcSource(SAMPLE_RATE, BLOCK_SIZE);
delay(100); delay(100);
useBandPassFilter = true; // PDM bandpass filter seems to help for bad quality analog
if (audioSource) audioSource->initialize(audioPin); if (audioSource) audioSource->initialize(audioPin);
break; break;
#endif #endif

View File

@ -122,7 +122,7 @@ class AudioSource {
This function needs to take care of anything that needs to be done This function needs to take care of anything that needs to be done
before samples can be obtained from the microphone. before samples can be obtained from the microphone.
*/ */
virtual void initialize(int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) = 0; virtual void initialize(int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) = 0;
/* Deinitialize /* Deinitialize
Release all resources and deactivate any functionality that is used Release all resources and deactivate any functionality that is used
@ -191,7 +191,8 @@ class I2SSource : public AudioSource {
}; };
} }
virtual void initialize(int8_t i2swsPin = I2S_PIN_NO_CHANGE, int8_t i2ssdPin = I2S_PIN_NO_CHANGE, int8_t i2sckPin = I2S_PIN_NO_CHANGE, int8_t mclkPin = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { virtual void initialize(int8_t i2swsPin = I2S_PIN_NO_CHANGE, int8_t i2ssdPin = I2S_PIN_NO_CHANGE, int8_t i2sckPin = I2S_PIN_NO_CHANGE, int8_t mclkPin = I2S_PIN_NO_CHANGE) {
DEBUGSR_PRINTLN("I2SSource:: initialize().");
if (i2swsPin != I2S_PIN_NO_CHANGE && i2ssdPin != I2S_PIN_NO_CHANGE) { if (i2swsPin != I2S_PIN_NO_CHANGE && i2ssdPin != I2S_PIN_NO_CHANGE) {
if (!pinManager.allocatePin(i2swsPin, true, PinOwner::UM_Audioreactive) || if (!pinManager.allocatePin(i2swsPin, true, PinOwner::UM_Audioreactive) ||
!pinManager.allocatePin(i2ssdPin, false, PinOwner::UM_Audioreactive)) { // #206 !pinManager.allocatePin(i2ssdPin, false, PinOwner::UM_Audioreactive)) { // #206
@ -412,6 +413,7 @@ public:
}; };
void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) { void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) {
DEBUGSR_PRINTLN("ES7243:: initialize();");
if ((i2sckPin < 0) || (mclkPin < 0)) { if ((i2sckPin < 0) || (mclkPin < 0)) {
DEBUGSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin); DEBUGSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin);
return; return;
@ -527,7 +529,7 @@ class ES8388Source : public I2SSource {
}; };
void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) { void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) {
DEBUGSR_PRINTLN("ES8388Source:: initialize();");
if ((i2sckPin < 0) || (mclkPin < 0)) { if ((i2sckPin < 0) || (mclkPin < 0)) {
DEBUGSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin); DEBUGSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin);
return; return;
@ -584,7 +586,8 @@ class I2SAdcSource : public I2SSource {
/* identify Audiosource type - I2S-ADC*/ /* identify Audiosource type - I2S-ADC*/
AudioSourceType getType(void) {return(Type_I2SAdc);} AudioSourceType getType(void) {return(Type_I2SAdc);}
void initialize(int8_t audioPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { void initialize(int8_t audioPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) {
DEBUGSR_PRINTLN("I2SAdcSource:: initialize().");
_myADCchannel = 0x0F; _myADCchannel = 0x0F;
if(!pinManager.allocatePin(audioPin, false, PinOwner::UM_Audioreactive)) { if(!pinManager.allocatePin(audioPin, false, PinOwner::UM_Audioreactive)) {
DEBUGSR_PRINTF("failed to allocate GPIO for audio analog input: %d\n", audioPin); DEBUGSR_PRINTF("failed to allocate GPIO for audio analog input: %d\n", audioPin);
@ -755,7 +758,8 @@ class SPH0654 : public I2SSource {
I2SSource(sampleRate, blockSize, sampleScale) I2SSource(sampleRate, blockSize, sampleScale)
{} {}
void initialize(uint8_t i2swsPin, uint8_t i2ssdPin, uint8_t i2sckPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t = I2S_PIN_NO_CHANGE) {
DEBUGSR_PRINTLN("SPH0654:: initialize();");
I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin); I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin);
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
// these registers are only existing in "classic" ESP32 // these registers are only existing in "classic" ESP32

View File

@ -2260,17 +2260,18 @@ uint16_t mode_meteor() {
byte* trail = SEGENV.data; byte* trail = SEGENV.data;
byte meteorSize= 1+ SEGLEN / 10; const unsigned meteorSize= 1 + SEGLEN / 20; // 5%
uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8);
uint16_t in = counter * SEGLEN >> 16; uint16_t in = counter * SEGLEN >> 16;
const int max = SEGMENT.palette==5 || !SEGMENT.check1 ? 240 : 255;
// fade all leds to colors[1] in LEDs one step // fade all leds to colors[1] in LEDs one step
for (int i = 0; i < SEGLEN; i++) { for (int i = 0; i < SEGLEN; i++) {
if (random8() <= 255 - SEGMENT.intensity) if (random8() <= 255 - SEGMENT.intensity) {
{ byte meteorTrailDecay = 162 + random8(92);
byte meteorTrailDecay = 128 + random8(127);
trail[i] = scale8(trail[i], meteorTrailDecay); trail[i] = scale8(trail[i], meteorTrailDecay);
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, false, 0), trail[i])); uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(i, true, false, 0, trail[i]) : SEGMENT.color_from_palette(trail[i], false, true, 255);
SEGMENT.setPixelColor(i, col);
} }
} }
@ -2280,13 +2281,14 @@ uint16_t mode_meteor() {
if (index >= SEGLEN) { if (index >= SEGLEN) {
index -= SEGLEN; index -= SEGLEN;
} }
trail[index] = 240; trail[index] = max;
SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(index, true, false, 0)); uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(index, true, false, 0, trail[index]) : SEGMENT.color_from_palette(trail[index], false, true, 255);
SEGMENT.setPixelColor(index, col);
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail length;!,!;!;1"; static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail,,,,Gradient;;!;1";
// smooth meteor effect // smooth meteor effect
@ -2298,18 +2300,17 @@ uint16_t mode_meteor_smooth() {
byte* trail = SEGENV.data; byte* trail = SEGENV.data;
byte meteorSize= 1+ SEGLEN / 10; const unsigned meteorSize= 1+ SEGLEN / 20; // 5%
uint16_t in = map((SEGENV.step >> 6 & 0xFF), 0, 255, 0, SEGLEN -1); uint16_t in = map((SEGENV.step >> 6 & 0xFF), 0, 255, 0, SEGLEN -1);
const int max = SEGMENT.palette==5 || !SEGMENT.check1 ? 240 : 255;
// fade all leds to colors[1] in LEDs one step // fade all leds to colors[1] in LEDs one step
for (int i = 0; i < SEGLEN; i++) { for (int i = 0; i < SEGLEN; i++) {
if (trail[i] != 0 && random8() <= 255 - SEGMENT.intensity) if (/*trail[i] != 0 &&*/ random8() <= 255 - SEGMENT.intensity) {
{ int change = trail[i] + 4 - random8(24); //change each time between -20 and +4
int change = 3 - random8(12); //change each time between -8 and +3 trail[i] = constrain(change, 0, max);
trail[i] += change; uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(i, true, false, 0, trail[i]) : SEGMENT.color_from_palette(trail[i], false, true, 255);
if (trail[i] > 245) trail[i] = 0; SEGMENT.setPixelColor(i, col);
if (trail[i] > 240) trail[i] = 240;
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, false, 0), trail[i]));
} }
} }
@ -2319,14 +2320,15 @@ uint16_t mode_meteor_smooth() {
if (index >= SEGLEN) { if (index >= SEGLEN) {
index -= SEGLEN; index -= SEGLEN;
} }
trail[index] = 240; trail[index] = max;
SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(index, true, false, 0)); uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(index, true, false, 0, trail[index]) : SEGMENT.color_from_palette(trail[index], false, true, 255);
SEGMENT.setPixelColor(index, col);
} }
SEGENV.step += SEGMENT.speed +1; SEGENV.step += SEGMENT.speed +1;
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_METEOR_SMOOTH[] PROGMEM = "Meteor Smooth@!,Trail length;!,!;!;1"; static const char _data_FX_MODE_METEOR_SMOOTH[] PROGMEM = "Meteor Smooth@!,Trail,,,,Gradient;;!;1";
//Railway Crossing / Christmas Fairy lights //Railway Crossing / Christmas Fairy lights
@ -5984,12 +5986,12 @@ uint16_t mode_2Dscrollingtext(void) {
col1 = SEGCOLOR(0); col1 = SEGCOLOR(0);
col2 = SEGCOLOR(2); col2 = SEGCOLOR(2);
} }
SEGMENT.drawCharacter(text[i], xoffset, yoffset, letterWidth, letterHeight, col1, col2, (SEGMENT.custom3+1)>>3); SEGMENT.drawCharacter(text[i], xoffset, yoffset, letterWidth, letterHeight, col1, col2, map(SEGMENT.custom3, 0, 31, -2, 2));
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,Rotate,Gradient,Overlay,Reverse;!,!,Gradient;!;2;ix=128,c1=0,c3=0,rev=0,mi=0,rY=0,mY=0"; static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,Rotate,Gradient,Overlay,Reverse;!,!,Gradient;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0";
//////////////////////////// ////////////////////////////

View File

@ -625,9 +625,9 @@ typedef struct Segment {
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, uint32_t col2 = 0, uint8_t rotate = 0); void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0, int8_t rotate = 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, uint8_t rotate = 0) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0), rotate); } // automatic inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0), rotate); } // 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); }
@ -657,8 +657,9 @@ typedef struct Segment {
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) {} void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {}
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 = 0, int8_t = 0) {}
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {} void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {}
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) {}
void wu_pixel(uint32_t x, uint32_t y, CRGB c) {} void wu_pixel(uint32_t x, uint32_t y, CRGB c) {}
#endif #endif
} segment; } segment;

View File

@ -556,7 +556,7 @@ 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, uint32_t col2, uint8_t rotate) { void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2, int8_t rotate) {
if (!isActive()) return; // not active if (!isActive()) return; // not active
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
@ -582,10 +582,11 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
for (int j = 0; j<w; j++) { // character width for (int j = 0; j<w; j++) { // character width
int x0, y0; int x0, y0;
switch (rotate) { switch (rotate) {
case 3: x0 = x + (h-1) - i; y0 = y + (w-1) - j; break; case -1: x0 = x + (h-1) - i; y0 = y + (w-1) - j; break; // -90 deg
case 2: x0 = x + j; y0 = y + (h-1) - i; break; case -2:
case 1: x0 = x + i; y0 = y + j; break; case 2: x0 = x + j; y0 = y + (h-1) - i; break; // 180 deg
default: x0 = x + (w-1) - j; y0 = y + i; break; case 1: x0 = x + i; y0 = y + j; break; // +90 deg
default: x0 = x + (w-1) - j; y0 = y + i; break; // no rotation
} }
if (x0 < 0 || x0 >= cols || y0 < 0 || y0 >= rows) continue; // drawing off-screen if (x0 < 0 || x0 >= cols || y0 < 0 || y0 >= rows) continue; // drawing off-screen
if (((bits>>(j+(8-w))) & 0x01)) { // bit set if (((bits>>(j+(8-w))) & 0x01)) { // bit set

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2309120 #define VERSION 2309241
//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