Skip to content

SineEffectModule

A multi-type effect producer. Switches between a 3D sine-wave pattern and a 3D ripples effect via a runtime type selector. Writes colored RGB values into an EffectsLayer each loop(). Introduced in Release 1, Sprint 4; refactored in Release 1, Sprint 5; extended with the waveform selector in Release 7, Sprint 9; dynamic type selector added in Release 8, Sprint 1.


What it does

A type dropdown selects the active effect. Only the parameters relevant to the selected type are shown in the UI; the rest are hidden until needed.

Type 0: Sine

Fills a 3D pixel grid with a colored waveform. Each color channel responds to a different spatial axis:

R = amplitude × wave(frequency × (x + tick))
G = amplitude × wave(frequency × (y + tick) + 2π/3)
B = amplitude × wave(frequency × (z + tick) + 4π/3)

waveform selects the wave shape: sine, square, triangle, or sawtooth.

Type 1: Ripples

Radial wave from the centre of the XZ floor. One pixel column per (x, z) position is lit at a height determined by a sine phase driven by distance and time:

y = h/2 × (1 + sin(dist/ripple_interval + time))

Colour cycles through a hue wheel over time.


Controls

Common

Parameter Type Default Description
type select 0 (sine) Effect variant. Switches the visible control set at runtime.
enabled toggle true When false, loop() is skipped.

Sine controls (type = 0)

Parameter Default Description
frequency 1 Spatial + temporal wave frequency (1-20).
amplitude 255 Output amplitude (0-255, DMX-aligned).
waveform 0 (sine) Wave shape: sine, square, triangle, sawtooth.

Ripples controls (type = 1)

Parameter Default Description
speed 50 Animation speed (0 = stopped, 99 = fast).
interval 128 Wavefront spacing (1 = tight, 254 = wide).

Parameter values are preserved when switching between types: setting frequency to 15, switching to Ripples and back restores frequency = 15.


Dynamic controls

SineEffectModule overrides rebuildControls() and onUpdate(). When type changes, onUpdate("type") calls rebuildControls(), which calls clearControls() (saving current non-system values to the pending stash) and re-registers only the controls for the new type. The UI receives an early WebSocket push so the control card updates without waiting for the next 200 ms cycle.


Platform notes

Uses sinf() and sqrtf(). The module owns no pixel memory — allocation is in EffectsLayer. On ESP32, both functions use the hardware FPU.


Test coverage

Sine Effect — deterministic output, zero residue after teardown, checksum propagation through layers.

Controls and KV — type selector schema (4 controls in Sine mode), type switch to Ripples, frequency preserved across round-trip.

Also covered in Health Checks (healthReport format, checksum consistency).

Source