Skip to content

Commit 49a4789

Browse files
committed
SE16: add mirroredPins and swapRowCol, FastLED latest, add rippleYZ
Server - pio.ini: default chipset is WS2812B, GRB, update to latest FastLED, USB settings on S3 - Layouts: SE16: add mirroredPins and swapRowCol - Modifiers: add rippleYZ (WIP) - Info: add FastLED - Nodes: remove _time, use beat8
1 parent 62e286d commit 49a4789

File tree

6 files changed

+132
-34
lines changed

6 files changed

+132
-34
lines changed

platformio.ini

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ build_flags =
2222
-D FT_MOONLIGHT=1
2323
-D FT_MONITOR=1
2424
; ML_CHIPSET: Used by FastLED driver.init
25-
-D ML_CHIPSET=NEOPIXEL ; GRB, for normal leds (why GRB is normal???)
26-
; -D ML_CHIPSET=WS2812B ; RGB, for fairy lights or https://www.waveshare.com/wiki/ESP32-S3-Matrix
25+
-D ML_CHIPSET=WS2812B ; RGB, for fairy lights or https://www.waveshare.com/wiki/ESP32-S3-Matrix
2726
; -D ML_CHIPSET=APA106 ; for Cube202020 / some fairy curtain strings do not work with WS2812B
2827
; -D ML_CHIPSET=SK6812 ; WIP
28+
-D ML_COLOR_ORDER=GRB ; define your color order here if needed (why WS2812 has GRB instead of RGB?)
29+
; -D ML_RGBW=1 ; define whether to enable RGBW (1 = yes, 0 = no) ... could be derived from ML_CHIPSET???
30+
; tests to resolve flicker in IDF 5...
2931
; -D FASTLED_RMT_BUILTIN_DRIVER=true
3032
; -D FASTLED_RMT5
31-
; -D ML_COLOR_ORDER=GRB ; define your color order here if needed
32-
; -D ML_RGBW=1 ; define whether to enable RGBW (1 = yes, 0 = no)
3333
lib_deps =
34-
https://github.com/FastLED/FastLED.git#3.9.19 ; june 2025
34+
https://github.com/FastLED/FastLED.git#3.10.1 ; june 2025
3535
https://github.com/netmindz/WLED-sync#48cb28f11632b217f9ccd9f72149373919c28af5 ; sourceIP
3636

3737
; 💫 currently only enabled on s3 as esp32dev runs over 100%
@@ -59,14 +59,21 @@ lib_deps =
5959
framework = arduino ;espidf will not work as libs rely on arduino (e.g. PhysicHTTP, ...)
6060
; https://github.com/platformio/platform-espressif32/releases
6161
; platform = espressif32 @ 6.10.0 ;Jan 2025, ESP-IDF v4.4.7-dirty / Arduino v2.0.17
62-
platform = espressif32 @ 6.11.0 ; June 2025, ESP-IDF v4.4.7-dirty / Arduino v2.0.17 latest v4.4.7 !
62+
platform = espressif32 @ 6.11.0 ; June 2025, ESP-IDF v4.4.7-dirty / Arduino v2.0.17 latest v4.4.7-dirty ! framework-arduinoespressif32 @ ~3.20017.0
6363
; v4 -> v5 flash size from 1955 to 2238 KB on S3 ! esp32 > 100%...
6464
; v5 resulting in FastLED hickups on all listed versions:
6565
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/2024.07.00/platform-espressif32.zip ; Jul 15, 2024 espressif Arduino core 3.0.2 / IDF 5.1.4: error: no matching function for call to 'NetworkClientSecure::setCACertBundle(const uint8_t [], int)'
6666
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10/platform-espressif32.zip ; Dec 16, 2024 Arduino core 3.1.0 based on IDF 5.3.2.241210
6767
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.11/platform-espressif32.zip ; Jan 19, 2025 Arduino core 3.1.1 based on IDF 5.3.2.241224
6868
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip ; March 28, 2025 Latest release! ESP-IDF v5.4.1-1-g2f7dcd862a-dirty / Arduino v3.2.0
6969
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13/platform-espressif32.zip ; June 2025 not 54.03? used in latest upstream ESP-IDF v5.3.2-584-g489d7a2b3a-dirty / Arduino v3.1.3
70+
71+
;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them)
72+
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.06.02/platform-espressif32.zip ;; Tasmota Arduino Core 2.0.9 with IPv6 support, based on IDF 4.4.4
73+
;from 92% to 71% !!! Flash: [======= ] 71.8% (used 1412441 bytes from 1966080 bytes)
74+
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.06.00/platform-espressif32.zip
75+
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2025.05.30/platform-espressif32.zip ;; Platform Tasmota Arduino Core 3.1.3.250504based on IDF 5.3.3.250501platform_packages
76+
; platform_packages = framework-arduinoespressif32 @ 3.1.3
7077
build_flags =
7178
${factory_settings.build_flags}
7279
${features.build_flags}
@@ -226,12 +233,15 @@ board_build.partitions = min_spiffs.csv
226233
build_flags =
227234
${env.build_flags}
228235
${moonlight.build_flags}
236+
; ${livescripts.build_flags}
229237
-D LED_BUILTIN=2
230238
-D KEY_BUILTIN=0
231239
-D HTTPD_STACK_SIZE=8192 ; default 4096 but not enough for more complex read and update (esp32 has no livescripts therefore set this explicitly here
240+
; -D LOLIN_WIFI_FIX ; some boards have wifi issues if this is not defined, this sets WIFI_POWER_8_5dBm
232241
lib_deps =
233242
${env.lib_deps}
234243
${moonlight.lib_deps}
244+
; ${livescripts.lib_deps}
235245

236246
[env:esp32devPD]
237247
extends = env:esp32dev
@@ -320,6 +330,10 @@ build_flags =
320330
${moonlight.build_flags}
321331
${livescripts.build_flags}
322332
-D CONFIG_IDF_TARGET_ESP32S3=1
333+
; -D ARDUINO_USB_MODE=0 ; which USB device classes are enabled on your ESP32 at boot. default 1 in board definition (serial only)
334+
; -D ARDUINO_USB_CDC_ON_BOOT=0 ;Communications Device Class: controls whether the ESP32's USB serial port is enabled automatically at boot, default 1 in board definition
335+
-D ARDUINO_USB_MSC_ON_BOOT=0 ;Mass Storage Class, disable
336+
-D ARDUINO_USB_DFU_ON_BOOT=0 ;download firmware update, disable
323337
-D LOLIN_WIFI_FIX ; some boards have wifi issues if this is not defined, this sets WIFI_POWER_8_5dBm
324338
lib_deps =
325339
${env.lib_deps}

src/MoonLight/Layouts.h

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,25 +158,28 @@ class SE16Layout: public Node {
158158
static uint8_t dim() {return _2D;}
159159
static const char * tags() {return "";}
160160

161+
bool mirroredPins = false;
162+
bool swapRowCol = false;
161163
uint8_t height = 10;
162164

163165
void setup() override {
164166
hasLayout = true;
165167

168+
addControl(mirroredPins, "mirroredPins", "checkbox");
169+
addControl(swapRowCol, "swapRowCol", "checkbox");
166170
addControl(height, "height", "range", 1, 255);
167171
}
168172

169173
void addStrip( uint8_t xposition, uint8_t start_y, uint8_t stop_y, uint8_t pin) {
170-
if (start_y > stop_y){
171-
for (int y = start_y; y>=stop_y; y--) {
174+
175+
bool increasing = (start_y < stop_y);
176+
for (int y = start_y; increasing ? (y <= stop_y) : (y >= stop_y); y += increasing?1:-1) {
177+
if (swapRowCol)
172178
addLight(intToCoord3D(xposition, y, 0));
173-
}
174-
}
175-
else {
176-
for (uint8_t y = start_y; y<=stop_y; y++) {
177-
addLight(intToCoord3D(xposition, y, 0));
178-
}
179+
else
180+
addLight(intToCoord3D(y, xposition, 0));
179181
}
182+
180183
addPin(pin);
181184
}
182185

@@ -192,14 +195,25 @@ class SE16Layout: public Node {
192195
// 10-02
193196
// 03-01
194197

195-
addStrip(7, height, 2*height-1, 47); addStrip(7, height-1, 0, 48);
196-
addStrip(6, height, 2*height-1, 21); addStrip(6, height-1, 0, 38);
197-
addStrip(5, height, 2*height-1, 14); addStrip(5, height-1, 0, 39);
198-
addStrip(4, height, 2*height-1, 13); addStrip(4, height-1, 0, 40);
199-
addStrip(3, height, 2*height-1, 12); addStrip(3, height-1, 0, 41);
200-
addStrip(2, height, 2*height-1, 11); addStrip(2, height-1, 0, 42);
201-
addStrip(1, height, 2*height-1, 10); addStrip(1, height-1, 0, 2);
202-
addStrip(0, height, 2*height-1, 3); addStrip(0, height-1, 0, 1);
198+
if (mirroredPins) {
199+
addStrip(7, height, 2*height-1, 47); addStrip(7, height-1, 0, 48);
200+
addStrip(6, height, 2*height-1, 21); addStrip(6, height-1, 0, 38);
201+
addStrip(5, height, 2*height-1, 14); addStrip(5, height-1, 0, 39);
202+
addStrip(4, height, 2*height-1, 13); addStrip(4, height-1, 0, 40);
203+
addStrip(3, height, 2*height-1, 12); addStrip(3, height-1, 0, 41);
204+
addStrip(2, height, 2*height-1, 11); addStrip(2, height-1, 0, 42);
205+
addStrip(1, height, 2*height-1, 10); addStrip(1, height-1, 0, 2);
206+
addStrip(0, height, 2*height-1, 3); addStrip(0, height-1, 0, 1);
207+
} else {
208+
addStrip(14, 0, height-1, 47); addStrip(15, 0, height-1, 48);
209+
addStrip(12, 0, height-1, 21); addStrip(13, 0, height-1, 38);
210+
addStrip(10, 0, height-1, 14); addStrip(11, 0, height-1, 39);
211+
addStrip(8, 0, height-1, 13); addStrip(9, 0, height-1, 40);
212+
addStrip(6, 0, height-1, 12); addStrip(7, 0, height-1, 41);
213+
addStrip(4, 0, height-1, 11); addStrip(5, 0, height-1, 42);
214+
addStrip(2, 0, height-1, 10); addStrip(3, 0, height-1, 2);
215+
addStrip(0, 0, height-1, 3); addStrip(1, 0, height-1, 1);
216+
}
203217
}
204218
};
205219

src/MoonLight/Modifiers.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,77 @@ class PinwheelModifier: public Node {
196196
}
197197
};
198198

199+
//Idea and first implementation (WLEDMM ARtNet) by @Troy
200+
class RippleYZModifier: public Node {
201+
public:
202+
203+
static const char * name() {return "RippleYZ 💎💡💫";}
204+
static const char * tags() {return "";}
205+
206+
bool shrink = true;
207+
bool towardsY = true;
208+
bool towardsZ = false;
209+
210+
void setup() override {
211+
212+
hasModifier = true;
213+
214+
addControl(shrink, "shrink", "checkbox");
215+
addControl(towardsY, "towardsY", "checkbox");
216+
addControl(towardsZ, "towardsZ", "checkbox");
217+
}
218+
219+
void modifySize() override {
220+
// modifyPosition(layerV->size);
221+
// change the size to be one bigger in each dimension
222+
// layerV->size.x++;
223+
// layerV->size.y++;
224+
// layerV->size.z++;
225+
if (shrink) {
226+
if (towardsY)
227+
layerV->size.y = 1;
228+
if (towardsZ)
229+
layerV->size.z = 1;
230+
}
231+
}
232+
233+
void modifyPosition(Coord3D &position) override {
234+
if (shrink) {
235+
if (towardsY)
236+
position.y = 0;
237+
if (towardsZ)
238+
position.z = 0;
239+
}
240+
}
241+
242+
void loop() override {
243+
244+
//1D->2D: each X is rippled through the y-axis
245+
if (towardsY) {
246+
// if (leds.effectDimension == _1D && leds.projectionDimension > _1D) {
247+
for (int y=layerV->size.y-1; y>=1; y--) {
248+
for (int x=0; x<layerV->size.x; x++) {
249+
layerV->setRGB(intToCoord3D(x, y, 0), layerV->getRGB(intToCoord3D(x,y-1,0)));
250+
}
251+
}
252+
// }
253+
}
254+
255+
//2D->3D: each XY plane is rippled through the z-axis
256+
if (towardsZ) { //not relevant for 2D fixtures
257+
// if (leds.effectDimension < _3D && leds.projectionDimension == _3D) {
258+
for (int z=layerV->size.z-1; z>=1; z--) {
259+
for (int y=0; y<layerV->size.y; y++) {
260+
for (int x=0; x<layerV->size.x; x++) {
261+
layerV->setRGB(intToCoord3D(x, y, z), layerV->getRGB(intToCoord3D(x,y,z-1)));
262+
}
263+
}
264+
}
265+
// }
266+
}
267+
}
268+
}; //RippleYZ
269+
199270
// RotateNodifier rotates the light position around the center of the layout.
200271
// It can flip the x and y coordinates, reverse the rotation direction, and alternate the rotation
201272
// direction every full rotation. It also supports shear transformations to create a more dynamic effect.

src/MoonLight/ModuleEditor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class ModuleEditor : public Module
140140
values.add(CircleModifier::name());
141141
values.add(MirrorModifier::name());
142142
values.add(MultiplyModifier::name());
143+
values.add(RippleYZModifier::name());
143144
values.add(PinwheelModifier::name());
144145
values.add(RotateNodifier::name());
145146

src/MoonLight/ModuleMoonLightInfo.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class ModuleMoonLightInfo : public Module
3434

3535
property = root.add<JsonObject>(); property["name"] = "nrOfLights"; property["type"] = "number"; property["max"] = 65536;
3636
property = root.add<JsonObject>(); property["name"] = "channelsPerLight"; property["type"] = "number"; property["max"] = 65536;
37-
property = root.add<JsonObject>(); property["name"] = "chipset"; property["type"] = "text"; property["max"] = 20;
37+
property = root.add<JsonObject>(); property["name"] = "chipset"; property["type"] = "text"; property["max"] = 32;
38+
property = root.add<JsonObject>(); property["name"] = "FastLED"; property["type"] = "text"; property["max"] = 32;
3839
property = root.add<JsonObject>(); property["name"] = "size"; property["type"] = "coord3D";
3940
property = root.add<JsonObject>(); property["name"] = "layers"; property["type"] = "array"; details = property["n"].to<JsonArray>();
4041
{
@@ -58,6 +59,8 @@ class ModuleMoonLightInfo : public Module
5859
data["nrOfLights"] = layerP.lights.header.nrOfLights;
5960
data["channelsPerLight"] = layerP.lights.header.channelsPerLight;
6061
data["chipset"] = TOSTRING(ML_CHIPSET);
62+
const char* fastledVersion = TOSTRING(FASTLED_VERSION);// "." TOSTRING(FASTLED_VERSION_MINOR) "." TOSTRING(FASTLED_VERSION_PATCH);
63+
data["FastLED"] = fastledVersion;
6164
data["size"]["x"] = layerP.lights.header.size.x;
6265
data["size"]["y"] = layerP.lights.header.size.y;
6366
data["size"]["z"] = layerP.lights.header.size.z;

src/MoonLight/Nodes.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,6 @@ static void _setRGBPal(uint16_t indexV, uint8_t index, uint8_t brightness) { gNo
6969
static void _setPan(uint16_t indexV, uint8_t value) {gNode->layerV->setPan(indexV, value);}
7070
static void _setTilt(uint16_t indexV, uint8_t value) {gNode->layerV->setTilt(indexV, value);}
7171

72-
static float _time(float j) {
73-
float myVal = millis();
74-
myVal = myVal / 65535 / j; // PixelBlaze uses 1000/65535 = .015259.
75-
myVal = fmod(myVal, 1.0); // ewowi: with 0.015 as input, you get fmod(millis/1000,1.0), which has a period of 1 second, sounds right
76-
return myVal;
77-
}
78-
7972
volatile xSemaphoreHandle WaitAnimationSync = xSemaphoreCreateBinary();
8073

8174
void sync() {
@@ -147,7 +140,7 @@ void LiveScriptNode::setup() {
147140
addExternal( "uint8_t inoise8(uint16_t,uint16_t,uint16_t)", (void *)(uint8_t (*)(uint16_t,uint16_t,uint16_t))inoise8);
148141
addExternal( "uint8_t beatsin8(uint16_t,uint8_t,uint8_t,uint32_t,uint8_t)", (void *)beatsin8);
149142
addExternal( "float hypot(float,float)", (void*)(float (*)(float,float))hypot);
150-
addExternal( "float time(float)", (void *)_time);
143+
addExternal( "float beat8(uint8_t,uint32_t)", (void *)beat8); //saw wave
151144
addExternal( "uint8_t triangle8(uint8_t)", (void *)triangle8);
152145

153146
//MoonLight functions
@@ -178,9 +171,10 @@ void LiveScriptNode::setup() {
178171
addExternal( "uint8_t depth", &layerV->size.z);
179172
addExternal( "bool on", &on);
180173

181-
for (asm_external el: external_links) {
182-
ESP_LOGD(TAG, "elink %s %s %d", el.shortname.c_str(), el.name.c_str(), el.type);
183-
}
174+
// for (asm_external el: external_links) {
175+
// ESP_LOGD(TAG, "elink %s %s %d", el.shortname.c_str(), el.name.c_str(), el.type);
176+
// }
177+
184178

185179
runningPrograms.setPrekill(layerV->layerP->ledsDriver.preKill, layerV->layerP->ledsDriver.postKill); //for clockless driver...
186180
runningPrograms.setFunctionToSync(sync);
@@ -196,6 +190,7 @@ void LiveScriptNode::loop() {
196190

197191
void LiveScriptNode::addLayout() {
198192
if (hasLayout) {
193+
ESP_LOGD(TAG, "%s", animation);
199194
scriptRuntime.execute(animation, "addLayout");
200195
}
201196
}

0 commit comments

Comments
 (0)