Skip to content

Commit 69436a6

Browse files
committed
Merge branch 'mdev' into ESP32-HUB75-MatrixPanel-DMA
2 parents 43320a0 + e7bf24c commit 69436a6

22 files changed

+173
-8455
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ wled-update.sh
2222
/wled00/my_config.h
2323
/wled00/Release
2424
/wled00/wled00.ino.cpp
25+
/wled00/html_*.h

pio-scripts/build-html.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Import('env')
2+
import glob
3+
import os
4+
5+
if not os.path.isdir('node_modules'):
6+
env.Execute("npm ci")
7+
8+
if not os.path.exists('wled00/html_ui.h'):
9+
env.Execute("npm run build")
10+
11+
latest_source = max(glob.glob('wled00/data/*.htm'), key=os.path.getmtime)
12+
latest_export = max(glob.glob('wled00/html_*.h'), key=os.path.getmtime)
13+
14+
if os.path.getmtime(latest_source) > os.path.getmtime(latest_export):
15+
env.Execute("npm run build")

platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ ldscript_16m14m = eagle.flash.16m14m.ld
210210
[scripts_defaults]
211211
extra_scripts =
212212
pre:pio-scripts/set_version.py
213+
pre:pio-scripts/build-html.py
213214
post:pio-scripts/output_bins.py
214215
post:pio-scripts/strip-floats.py
215216
pre:pio-scripts/user_config_copy.py

wled00/FX.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5062,8 +5062,8 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli
50625062
unsigned long t_20 = t/20; // softhack007: pre-calculating this gives about 10% speedup
50635063
for (float i = 1; i < maxDim; i += 0.25) {
50645064
float angle = radians(t * (maxDim - i));
5065-
uint16_t myX = (cols>>1) + (uint16_t)(sin_t(angle) * i) + (cols%2);
5066-
uint16_t myY = (rows>>1) + (uint16_t)(cos_t(angle) * i) + (rows%2);
5065+
uint16_t myX = (cols>>1) + (uint16_t)(sinf(angle) * i) + (cols%2);
5066+
uint16_t myY = (rows>>1) + (uint16_t)(cosf(angle) * i) + (rows%2);
50675067
SEGMENT.setPixelColorXY(myX, myY, ColorFromPalette(SEGPALETTE, (i * 20) + t_20, 255, LINEARBLEND));
50685068
}
50695069
SEGMENT.blur(SEGMENT.intensity>>3);
@@ -5338,8 +5338,8 @@ uint16_t mode_2DJulia(void) { // An animated Julia set
53385338
reAl = -0.94299f; // PixelBlaze example
53395339
imAg = 0.3162f;
53405340

5341-
reAl += sin_t((float)strip.now/305.f)/20.f;
5342-
imAg += sin_t((float)strip.now/405.f)/20.f;
5341+
reAl += sinf((float)strip.now/305.f)/20.f;
5342+
imAg += sinf((float)strip.now/405.f)/20.f;
53435343

53445344
dx = (xmax - xmin) / (cols); // Scale the delta x and y values to our matrix size.
53455345
dy = (ymax - ymin) / (rows);
@@ -6067,8 +6067,8 @@ uint16_t mode_2Dghostrider(void) {
60676067
CRGB color = CRGB::White;
60686068
SEGMENT.wu_pixel(lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color);
60696069

6070-
lighter->gPosX += lighter->Vspeed * sin_t(radians(lighter->gAngle));
6071-
lighter->gPosY += lighter->Vspeed * cos_t(radians(lighter->gAngle));
6070+
lighter->gPosX += lighter->Vspeed * sinf(radians(lighter->gAngle));
6071+
lighter->gPosY += lighter->Vspeed * cosf(radians(lighter->gAngle));
60726072
lighter->gAngle += lighter->angleSpeed;
60736073
if (lighter->gPosX < 0) lighter->gPosX = (cols - 1) * 10;
60746074
if (lighter->gPosX > (cols - 1) * 10) lighter->gPosX = 0;
@@ -6090,8 +6090,8 @@ uint16_t mode_2Dghostrider(void) {
60906090
lighter->time[i] = 0;
60916091
lighter->reg[i] = false;
60926092
} else {
6093-
lighter->lightersPosX[i] += -7 * sin_t(radians(lighter->Angle[i]));
6094-
lighter->lightersPosY[i] += -7 * cos_t(radians(lighter->Angle[i]));
6093+
lighter->lightersPosX[i] += -7 * sinf(radians(lighter->Angle[i]));
6094+
lighter->lightersPosY[i] += -7 * cosf(radians(lighter->Angle[i]));
60956095
}
60966096
SEGMENT.wu_pixel(lighter->lightersPosX[i] * 256 / 10, lighter->lightersPosY[i] * 256 / 10, ColorFromPalette(SEGPALETTE, (256 - lighter->time[i])));
60976097
}
@@ -6303,8 +6303,8 @@ uint16_t mode_2Ddriftrose(void) {
63036303

63046304
SEGMENT.fadeToBlackBy(32+(SEGMENT.speed>>3));
63056305
for (size_t i = 1; i < 37; i++) {
6306-
uint32_t x = (CX + (sin_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f;
6307-
uint32_t y = (CY + (cos_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f;
6306+
uint32_t x = (CX + (sinf(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f;
6307+
uint32_t y = (CY + (cosf(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f;
63086308
SEGMENT.wu_pixel(x, y, CHSV(i * 10, 255, 255));
63096309
}
63106310
SEGMENT.blur((SEGMENT.intensity>>4)+1);

wled00/FX_fcn.cpp

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,16 @@ void Segment::deletejMap() {
776776
}
777777
}
778778

779+
780+
// WLEDMM constants for mapping mode "Pinwheel"
781+
constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32; 60fps
782+
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
783+
constexpr int Pinwheel_Steps_Big = 360; // no holes expected up to 58x58; 40fps
784+
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
785+
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
786+
// WLEDMM end
787+
788+
779789
// 1D strip
780790
uint16_t Segment::virtualLength() const {
781791
#ifndef WLED_DISABLE_2D
@@ -806,7 +816,11 @@ uint16_t Segment::virtualLength() const {
806816
vLen = max(vW,vH) * 0.5; // get the longest dimension
807817
break;
808818
case M12_sPinWheel: //WLEDMM
809-
vLen = 360; // full circle
819+
//vLen = full circle
820+
if (max(vW,vH) <= Pinwheel_Size_Medium)
821+
vLen = Pinwheel_Steps_Medium;
822+
else
823+
vLen = Pinwheel_Steps_Big;
810824
break;
811825
}
812826
return vLen;
@@ -875,13 +889,26 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT
875889
else {
876890
//WLEDMM: drawArc(0, 0, i, col); could work as alternative
877891

878-
float step = HALF_PI / (2.85f*i);
879-
for (float rad = 0.0f; rad <= HALF_PI+step/2; rad += step) {
892+
//WLEDMM: some optimizations for the drawing loop
893+
// pre-calculate loop limits, exploit symmetry at 45deg
894+
float radius = float(i);
895+
// float step = HALF_PI / (2.85f * radius); // upstream uses this
896+
float step = HALF_PI / (M_PI * radius); // WLEDMM we use the correct circumference
897+
bool useSymmetry = (max(vH, vW) > 20); // for segments wider than 20 pixels, we exploit symmetry
898+
unsigned numSteps;
899+
if (useSymmetry) numSteps = 1 + ((HALF_PI/2.0f + step/2.0f) / step); // with symmetry
900+
else numSteps = 1 + ((HALF_PI + step/2.0f) / step); // without symmetry
901+
902+
float rad = 0.0f;
903+
for (unsigned count = 0; count < numSteps; count++) {
880904
// may want to try float version as well (with or without antialiasing)
881-
int x = roundf(sin_t(rad) * i);
882-
int y = roundf(cos_t(rad) * i);
905+
int x = roundf(sinf(rad) * radius);
906+
int y = roundf(cosf(rad) * radius);
883907
setPixelColorXY(x, y, col);
908+
if(useSymmetry) setPixelColorXY(y, x, col);// WLEDMM
909+
rad += step;
884910
}
911+
885912
// Bresenham’s Algorithm (may not fill every pixel)
886913
//int d = 3 - (2*i);
887914
//int y = i, x = 0;
@@ -909,8 +936,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT
909936
case M12_sCircle: //WLEDMM
910937
if (vStrip > 0)
911938
{
912-
int x = roundf(sin_t(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
913-
int y = roundf(cos_t(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
939+
int x = roundf(sinf(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
940+
int y = roundf(cosf(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
914941
setPixelColorXY(x + vW/2, y + vH/2, col);
915942
}
916943
else // pArc -> circle
@@ -935,24 +962,35 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT
935962
}
936963
}
937964
break;
938-
case M12_sPinWheel: {
939-
// i = 0 through 359
940-
float centerX = (vW-1) / 2;
941-
float centerY = (vH-1) / 2;
965+
case M12_sPinWheel: { // WLEDMM
966+
// i = angle --> 0 through 359 (Big), OR 0 through 208 (Medium)
967+
float centerX = roundf((vW-1) / 2.0f);
968+
float centerY = roundf((vH-1) / 2.0f);
942969
// int maxDistance = sqrt(centerX * centerX + centerY * centerY) + 1;
943-
944-
int distance = 0;
945-
float cosVal = cos(i * DEG_TO_RAD); // i = current angle
946-
float sinVal = sin(i * DEG_TO_RAD);
947-
while (true) {
948-
int x = round(centerX + distance * cosVal);
949-
int y = round(centerY + distance * sinVal);
950-
// Check bounds
951-
if (x < 0 || x >= vW || y < 0 || y >= vH) {
952-
break;
953-
}
970+
float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
971+
float cosVal = cosf(angleRad);
972+
float sinVal = sinf(angleRad);
973+
974+
// draw line at angle, starting at center and ending at the segment edge
975+
// we use fixed point math for better speed. Starting distance is 0.5 for better rounding
976+
constexpr int_fast32_t Fixed_Scale = 512; // fixpoint scaling factor
977+
int_fast32_t posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point
978+
int_fast32_t posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point
979+
int_fast16_t inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point)
980+
int_fast16_t inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point)
981+
982+
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
983+
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
984+
// draw until we hit any edge
985+
while ((posx > 0) && (posy > 0) && (posx < maxX) && (posy < maxY)) {
986+
// scale down to integer (compiler will replace division with appropriate bitshift)
987+
int x = posx / Fixed_Scale;
988+
int y = posy / Fixed_Scale;
989+
// set pixel
954990
setPixelColorXY(x, y, col);
955-
distance++;
991+
// advance to next position
992+
posx += inc_x;
993+
posy += inc_y;
956994
}
957995
break;
958996
}
@@ -1076,8 +1114,8 @@ uint32_t Segment::getPixelColor(int i)
10761114
case M12_sCircle: //WLEDMM
10771115
if (vStrip > 0)
10781116
{
1079-
int x = roundf(sin_t(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
1080-
int y = roundf(cos_t(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
1117+
int x = roundf(sinf(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
1118+
int y = roundf(cosf(360*i/SEGLEN*DEG_TO_RAD) * vW * (vStrip+1)/nrOfVStrips());
10811119
return getPixelColorXY(x + vW/2, y + vH/2);
10821120
}
10831121
else
@@ -1094,12 +1132,13 @@ uint32_t Segment::getPixelColor(int i)
10941132
return getPixelColorXY(vW / 2, vH / 2 - i - 1);
10951133
break;
10961134
case M12_sPinWheel: //WLEDMM
1097-
// not 100% accurate, returns outer edge of circle
1098-
int distance = min(vH, vW) / 2;
1099-
float centerX = (vW - 1) / 2;
1100-
float centerY = (vH - 1) / 2;
1101-
int x = round(centerX + distance * cos(i * DEG_TO_RAD));
1102-
int y = round(centerY + distance * sin(i * DEG_TO_RAD));
1135+
// not 100% accurate, returns outer edge of circle
1136+
float distance = max(1.0f, min(vH-1, vW-1) / 2.0f);
1137+
float centerX = (vW - 1) / 2.0f;
1138+
float centerY = (vH - 1) / 2.0f;
1139+
float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
1140+
int x = roundf(centerX + distance * cosf(angleRad));
1141+
int y = roundf(centerY + distance * sinf(angleRad));
11031142
return getPixelColorXY(x, y);
11041143
}
11051144
return 0;

wled00/const.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@
347347
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
348348
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)
349349
#define ERR_UNDERVOLT 32 // An attached voltmeter has measured a voltage below the threshold (not implemented)
350+
#define ERR_LOW_MEM 33 // low memory (RAM)
350351

351352
// Timer mode types
352353
#define NL_MODE_SET 0 //After nightlight time elapsed, set to target brightness

wled00/data/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,9 @@ function readState(s,command=false)
19671967
case 19:
19681968
errstr = "A filesystem error has occured.";
19691969
break;
1970+
case 33:
1971+
errstr = "Warning: Low Memory (RAM).";
1972+
break;
19701973
}
19711974
showToast('Error ' + s.error + ": " + errstr, true);
19721975
}

0 commit comments

Comments
 (0)