38 in fixture · 7 clusters · 35 LEDs · 7 drivers · ESP32 NodeMCU-32S

Seven-Cluster Reef Light

Live model of the whole fixture. It runs the same schedule, dimming, button logic, fan control and heat protection as the firmware further down. Change the time, press the five buttons, drag any slider or heat the sensor, and the LEDs, fans and circuit respond.

06:40
Sunrise Auto sunrise/sunset · on Day clusters · auto Night clusters · auto

Physical buttons

Daylight on/offGPIO32auto
Night/Blue on/offGPIO33auto
BrighterGPIO23
DimmerGPIO13
Auto sunrise/sunsetGPIO34on

B1 and B2 flip their clusters on or off against the schedule. The override clears itself at the next schedule change (sunrise, daylight, sunset, night, off). B3 and B4 change the master brightness in 10% steps. B5 switches the automatic sunrise/sunset schedule off: the lights hold where they are, B1 and B2 switch the groups by hand, and nothing changes with the clock until you press B5 again.

Brightness

100%
100%
100%
20%

Day clusters C2, C4, C6 light only in daytime; night clusters C1, C3, C5, C7 light only at night. Each cluster's slider sets its level in its own period. Daylight brightness scales the day clusters. Night clusters start at “Night start” right after sunset and dim gradually to “Night end” by the lights-off time.

Schedule

Daytime lights only the day clusters. Night lights only the night clusters. Sunrise starts with a dim blue dawn on the night clusters, then crossfades to the day clusters. The day clusters come up to the ramp start level, rise gradually to full over the daylight ramp time, and ease back down the same way before sunset. Sunset fades the day clusters out while the night clusters fade in. The night clusters then dim gradually from “Night start” to “Night end”. After “Night lights off” everything is dark until the next sunrise.

Fans & temperature

Fans off
Heatsink
--
Fan PWM
0%
LED limit
100%
PSU load
0 W
29.0 °C

Auto: fans run at 30% whenever any LED is on, then ramp to 100% between 35 and 45 °C. Manual: your speed, but above 45 °C or with a sensor fault the fans go to full anyway. LEDs dim from 50 °C, halve at 60 °C and shut off at 65 °C until the heatsink cools to 55 °C.

Serial monitor · 115200

    Photoperiod (auto schedule, before master and heat limit)

    Night clusters C1 C3 C5 C7Day clusters C2 C4 C6
    Click any part or net

    Circuit diagram

    The four shaded areas are the four separate systems: mains to 24 V, high power (drivers and LED strings), fan power, and low-voltage control. LED current only flows in the red area. The ESP32 only sends PWM signals, and the moving dashes on each string show LED current from its own driver. Every ⏚ symbol is the same common ground, returning to PSU −V.

    Select a part

    Tap the ESP32, a driver, a button, the MOSFET or a sensor to see its terminals and what they connect to.

    The ESP32 is drawn by function. On the terminal adapter, find each screw terminal by the GPIO number printed beside it. Only 5V, 3V3 and GND terminals carry power, and they only power the ESP32 itself and the two sensors.

    Point-to-point

    Wiring list

    Every connection, one per row. Driver terminal names follow the 7-pin 700 mA driver module you chose (IN+, IN−, PWM, LED+, LED−). IN+ and IN− each have two pins; either one works.

    FromToWireNotes
    Left to right along the fixture

    Clusters and strings

    One driver and one GPIO per cluster, all LEDs in each cluster in series. Night clusters carry the strongest fluorescence colours (royal blue 445 and UV 410) for the evening glow. Day clusters mix royal blue, ice blue 480, a 10000 K white and UV 410 for a blue-rich reef look that keeps corals glowing in daytime too. Clusters sit every 137.9 mm (5.4 in), with 68.9 mm from each end of the 965 mm fixture to the first and last cluster centre.

    ClusterCentre from leftLEDsSeries orderDriver · PWMString V typ / maxPower at 100%
    What the ESP32 does every 50 ms

    Control workflow

    %%{init: {'theme':'dark'}}%%
    flowchart TD
      A[Power on] --> B[All 7 PWM at 0. Pull-downs hold drivers off]
      B --> C[Start DS3231, DS18B20, 5 buttons, serial]
      C --> L{Every 50 ms}
      L --> K[Read buttons B1 to B5]
      K --> T[Read heatsink temperature once per second]
      T --> P{Heat check}
      P -- sensor fault --> P0[LEDs capped 50 percent, fans 100 percent]
      P -- up to 50 C --> P1[LED limit 100 percent]
      P -- 50 to 60 C --> P2[LED limit falls to 50 percent]
      P -- 65 C or more --> P3[LEDs off until 55 C]
      P0 --> S
      P1 --> S
      P2 --> S
      P3 --> S
      S[For each cluster: override or schedule level] --> X[x master x heat limit]
      X --> F[Fade toward target at 25 percent per second]
      F --> W[Write 12-bit PWM at 1 kHz to its driver]
      W --> Fan[Fans: 30 percent while LEDs on, 35 to 45 C ramps to 100 percent]
      Fan --> L
    
    %%{init: {'theme':'dark'}}%%
    stateDiagram-v2
      [*] --> Off
      Off --> Sunrise: sunrise start
      Sunrise --> Daylight: start + duration
      Daylight --> Sunset: sunset start
      Sunset --> Night: start + duration
      Night --> Off: night lights off
      state "B1 or B2 pressed" as O
      Daylight --> O: override that group
      Night --> O: override that group
      O --> Auto: next schedule change
      state "Manual hold (B5)" as MH
      Daylight --> MH: B5 off
      Night --> MH: B5 off
      MH --> Off: B5 on, schedule resumes
    
    Spec sheet

    Spec, power budget and design checks

    Every cluster is 5 LEDs, so a plain 24 V supply is enough. A night string (4 royal blue + UV 410) needs at most 18.2 V, typically 16.6 V. A buck constant-current driver needs about 3 V more than its LEDs, so at most 21.2 V, and the sealed 24 V supply leaves 2.8 V to spare with any LED batch. It has no voltage adjustment and needs none.

    Design checks

      Power budget, every cluster at 100%

      LoadCurrent at 24 VPower

      Typical forward voltage at 700 mA: royal and ice blue 3.3 V (max 3.6), UV 410 3.4 V (max 3.8), white 3.2 V (max 3.4).

      Bill of materials

      RefPartQtyNotes
      Arduino IDE · board “ESP32 Dev Module” (NodeMCU-32S)

      Firmware

      Install RTClib (Adafruit), OneWire and DallasTemperature from the Library Manager. Written for ESP32 Arduino core 3.x, with a shim so it also builds on 2.x. Every threshold and timing matches the simulator.

      Serial commands: status · auto · day on|off|auto · night on|off|auto · peak 3 75 · daylevel 90 · nightlevel 100 · nightend 20 · dayramp 120 40 · master 70 · sunrise 06:00 60 · sunset 18:00 60 · nightoff 21:00 · schedule on|off · dim normal|inverted · fan auto or fan 60 · time 14:30

      Compiled-in defaults

      Change any value below and the firmware code updates to match — these become the values baked into setup(), the same ones the comments call “change here or over serial”. They're still changeable later too, live, with the serial commands above.

      Cluster levels · peakPct[7] (each cluster's level in its own period)

      Before buying all 35 LEDs

      7-LED test build and power-up order

      Test build

      Build one complete night cluster plus one white. That tests the longest string (the 5-LED night cluster) before you buy the rest.

      PWMDriverLEDs in seriesString V max
      GPIO25Driver 14 royal blue + UV 410 in one row on a 120 mm heatsink (full C1)18.2 V
      GPIO26Driver 21 white 10000 K3.4 V

      That is 6 LEDs and 2 drivers. The firmware runs all seven channels anyway; unconnected GPIOs are harmless. Fit the DS18B20, one fan with the MOSFET, and at least one button.

      What to measure: with a multimeter in series with the Driver 1 string, check the current at 100%. It should read about 680–700 mA. Also measure the supply's actual output voltage, and note the heatsink temperature after one hour at 100%.

      Check the dimming direction on the first driver. The listing contradicts itself about whether PWM high means on or off. Type night on, then master 10. If the LEDs are very dim, it is normal. If they are almost fully bright, type dim inverted. If that fixes it, set DIM_INVERTED_DEFAULT = true in the code and move each 10 kΩ PWM resistor from GND to 3V3.

      Power-up order

      1. PSU alone. Mains and earth only, nothing on the output. Switch on and check it reads about 24 V with the multimeter.
      2. Set the bucks with no load. 12.0 V on the fan buck and 5.0 V on the ESP32 buck, measured with a meter.
      3. Check the common ground. Power off. Beep IN− to OUT− on each buck and each buck IN− to PSU −V.
      4. Flash the ESP32 over USB-C with the 5 V buck unplugged. Open the serial monitor at 115200.
      5. Sensors. Connect DS3231 and DS18B20. Check the time and temperature in the status line; set the clock with time HH:MM.
      6. One driver at a time. Wire it with its 10 kΩ PWM pull-down, then day on or night on, and step master from 10 to 100 while watching the current.
      7. Fans and buttons. Fans should start at 30% as soon as an LED is on. Warm the sensor to see them ramp. Press each button and watch the serial log.
      8. Thermal soak. One hour at full daylight, fixture closed. The sensor should stay under 50 °C, so the heat limit never engages.