|
1 | | -# RingLight ESP LED Controller |
2 | | - |
| 1 | +# Over-engineered Headphone Stand with Wireless Phone Charger |
3 | 2 |  |
4 | 3 |
|
5 | | -## Features |
6 | | -* Two LED rings - outer (141 LEDs) and inner (126 LEDs) wired up in series for a total of 267 LEDs |
7 | | -* Controlled by ESP32 (most stable). Code is compatible with ESP8266, but I was suffering stability issues with wifi and longer LED strips. |
8 | | -* WiFi connected and managed |
9 | | - * creates a default AP, listening to http://192.168.4.1 |
10 | | - * capable of joining existing 2.4GHz networks |
11 | | - * serves a webpage for managing LED - strip size, mode, brightness |
12 | | -* Firmware update over WiFi - new `firmware.bin` file can be uploaded at `/update` after the IP address |
13 | | - |
14 | | -## Components |
15 | | -* ESP32 - https://www.amazon.com/gp/product/B086MGH7JV |
16 | | -* JST SM 3PIN LED Connector - https://www.amazon.com/gp/product/B075K4HLTQ |
17 | | -* DC power connector - https://www.amazon.com/gp/product/B01N8VV78D |
18 | | -* WS2812B LED strip high density strips 144 LEDs per strip x 2 - https://www.amazon.com/gp/product/B088FKZWDQ |
19 | | -* DC 5v adapter - https://www.amazon.com/gp/product/B078RXZM4C |
20 | | - |
21 | | -## 3D filament |
22 | | -I used the ones below but likely many others will work. Make sure the white is translucent enough, print a 3 layer sheet and put it in-front of some LEDs. |
23 | | -* ESUN PLA+ warm white - https://www.amazon.com/gp/product/B01EKEMIIS |
24 | | -* ERYONE Matte PLA black - https://www.amazon.com/gp/product/B08HX1XF55 |
25 | | - |
26 | | -## Assembly and wiring |
27 | | - |
28 | | -Print 4 of each: |
29 | | -* [Dark Ring](stl/DarkRing.stl) |
30 | | -* [Light Ring](stl/LightRing.stl) |
31 | | -* [Bridge Hanger](stl/Hanger.stl) |
32 | | - |
33 | | -Assemble as described below. Rotate the light ring segments by 45 degrees so they join in the middle of the dark ring segments. |
34 | | -This improves stability. If loose-fitting, use a few drops of superglue to set the dark and light rings together. |
35 | | - |
36 | | - |
37 | | -Cut the two LED strips to 141 and 126 LEDs. Keep as many of the existing wires and connectors as possible. |
38 | | -Wire the strips data in series - outer first then inner. The beginning of the outer ring data pin goes to the connector data pin. |
39 | | -Join the power wires in parallel: 5V/VCC together to the 5V connector pin; GND(-) together to GND on connector pin. |
40 | | -Providing power to both start and ends of the strips reduces voltage sag and ensures even light at all brightness levels. |
41 | | - |
42 | | - |
43 | | - |
44 | | - |
45 | | - |
46 | | -By default in `Configuration.h` the LEDs data is connected to pin 12 on the ESP, but most other GPIO pins can be used if needed. |
47 | | - |
48 | | -__LED_PIN_STRIP = 12__ - GPIO12 - above VIN (5V), GND and GPIO13 |
49 | | - |
50 | | - |
51 | | - |
52 | | -Solder the power and data cables between the LED connector, ESP32 and DC connector as shown below, using the basic 3D printable enclosure. |
53 | | -The board is mounted above the DC connector with 3mm screws |
54 | | - |
55 | | - |
56 | | - |
57 | | - |
58 | | -Enclosure STL files. Print in PLA, PETG or any other hard filament. |
59 | | -* [ESP32 Case STL](stl/ESP32Case.stl) |
60 | | -* [ESP32 Lid STL](stl/ESP32Lid.stl) |
61 | | - |
62 | | -## Configuration.h |
| 4 | +https://makerworld.com/en/models/2347791-over-engineered-headphone-stand-and-phone-charger#profileId-2567275 |
63 | 5 |
|
64 | | -This file configures various default settings, like: |
65 | | -* ESP pin used to drive the LED data (defaults are referenced below) |
66 | | -* WiFi AP name/password |
67 | | -* LED strip type, size, default brightness |
| 6 | +## Description |
| 7 | +* Headphone stand |
| 8 | +* Wireless phone charger with Magsafe |
| 9 | +* LEDs driven by an ESP32C3 with OLED display accessible via wifi/web to change mode, brightness and more |
| 10 | + |
| 11 | +## Getting the firmware |
| 12 | + |
| 13 | +You can obtain `firmware.bin` in one of two ways: |
| 14 | + |
| 15 | +### Option 1: Build from source |
| 16 | +1. Clone this repository and install [PlatformIO](https://platformio.org/). |
| 17 | +2. Build the firmware: |
| 18 | + ```bash |
| 19 | + pio run -e esp32c3 |
| 20 | + ``` |
| 21 | +3. The built binary is at `.pio/build/esp32c3/firmware.bin`. |
| 22 | + |
| 23 | +### Option 2: Download a pre-built binary |
| 24 | +1. Go to the GitHub repository: https://github.com/jaisor/ESP_LED_Controller/tree/led_headphone_stand |
| 25 | +2. Download `firmware.bin` from the latest **release tag** or from the **build artifacts** attached to the most recent workflow run. |
| 26 | + |
| 27 | +## Firmware flashing |
| 28 | + |
| 29 | +### Initial (USB) |
| 30 | +1. Connect the ESP32C3 via USB and flash using `esptool`: |
| 31 | + ```bash |
| 32 | + esptool.py --chip esp32c3 --port <COM_PORT> --baud 921600 write_flash 0x0 firmware.bin |
| 33 | + ``` |
| 34 | + Replace `<COM_PORT>` with your serial port (e.g. `COM3` on Windows, `/dev/ttyUSB0` on Linux). |
| 35 | + |
| 36 | + Alternatively, if you built from source, use PlatformIO's built-in upload: |
| 37 | + ```bash |
| 38 | + pio run -e esp32c3 -t upload |
| 39 | + ``` |
| 40 | + |
| 41 | +### OTA |
| 42 | +1. Open a browser and navigate to `http://<device_ip>/update` (the device IP is shown on the OLED display or in serial output). |
| 43 | +2. The ElegantOTA interface will load — select `firmware.bin` and click **Update**. |
| 44 | +3. The device will flash the new firmware and reboot automatically. |
| 45 | + |
| 46 | +## WiFi connection |
| 47 | + |
| 48 | + |
| 49 | +1. On first boot (or after a factory reset), the device has no saved WiFi credentials. It will automatically create a **soft access point** named `ESP32C3LED_<device_id>` with the default password `password123`. |
| 50 | +2. Connect to that network from your phone or computer. |
| 51 | +3. Open a browser and go to `http://192.168.4.1/wifi`. |
| 52 | +4. Enter your home WiFi network SSID and password, then submit the form. |
| 53 | +5. The device will save the credentials to EEPROM, reboot, and connect to your WiFi network. |
| 54 | +6. Once connected, the device's IP address is displayed on the OLED screen. Use that IP to access the web UI and API. |
| 55 | + |
| 56 | +> **Tip:** If the device ever fails to connect to the saved network, it will fall back to creating the soft AP again so you can reconfigure it. |
| 57 | +
|
| 58 | +## Factory Reset |
| 59 | +If the device is misbehaving or you want to start fresh, you can trigger a factory reset by **power-cycling the device 3 times within 2 seconds** (plug/unplug rapidly). On the third boot the firmware detects the rapid reboot pattern, wipes EEPROM, and restores all settings to defaults. After a factory reset the device will boot with no saved WiFi credentials and create its soft access point again (see [WiFi connection](#wifi-connection) above). |
| 60 | + |
| 61 | +You can also trigger a factory reset from the web UI by sending a POST request to `/factory_reset`. |
| 62 | + |
| 63 | +## LED configuration |
| 64 | + |
| 65 | + |
| 66 | +The main page (`/`) lets you control all LED-related settings: |
| 67 | + |
| 68 | +| Setting | Description | |
| 69 | +|---|---| |
| 70 | +| **LED Type** | The LED chipset type (e.g. WS2812B, WS2811, etc.). Changing this requires a reboot. | |
| 71 | +| **LED Mode** | The active animation pattern. Each registered mode has an index shown in the mode list. | |
| 72 | +| **Brightness** | Global LED brightness (0–100%). | |
| 73 | +| **Delay (ms)** | Frame delay in milliseconds — lower values produce faster animations. | |
| 74 | +| **Strip Size** | Number of LEDs on the strip. Changing this requires a reboot. | |
| 75 | +| **Cycle Mode (s)** | Seconds between automatic mode changes. Set to 0 to disable auto-cycling. | |
| 76 | +| **Mode Cycling Selection** | Choose to cycle through all modes or provide a comma-separated list of specific mode indices. | |
| 77 | + |
| 78 | +### Power-save schedule |
| 79 | +The power-save feature lets you dim the LEDs during certain hours (e.g. overnight): |
| 80 | + |
| 81 | +| Setting | Description | |
| 82 | +|---|---| |
| 83 | +| **PS Brightness** | Brightness multiplier during power-save hours (0–100%, applied on top of the global brightness). | |
| 84 | +| **PS Start Hour** | Hour of the day (0–23) when power-save begins. | |
| 85 | +| **PS End Hour** | Hour of the day (0–23) when power-save ends. | |
| 86 | + |
| 87 | +> **Important:** The power-save schedule relies on knowing the current time. This requires an active **WiFi connection to the internet** so the device can sync with an NTP server. You must also set your correct **timezone** on the `/device` page — otherwise the hours will not match your local time. |
| 88 | +
|
| 89 | +## Other device configuration |
| 90 | + |
| 91 | + |
| 92 | +The device page (`/device`) provides general device settings: |
| 93 | + |
| 94 | +| Setting | Description | |
| 95 | +|---|---| |
| 96 | +| **LED Enabled** | Master on/off toggle for the LED strip. | |
| 97 | +| **Device Name** | A friendly name for the device (stored in EEPROM). | |
| 98 | +| **Timezone** | Select your local timezone from the dropdown. This is used by the NTP time sync and directly affects the power-save schedule described above. Daylight saving time adjustments are handled automatically via POSIX timezone rules. | |
| 99 | + |
| 100 | +The device page also provides a **Reboot** and **Factory Reset** option. |
| 101 | + |
| 102 | +## BOM: |
| 103 | +* LED strip - https://www.amazon.com/dp/B088FKZWDQ |
| 104 | +* LED ring - https://www.amazon.com/dp/B08GPL6N37 |
| 105 | +* ESP32C3 with OLED - https://www.amazon.com/dp/B0F37JWCDW |
| 106 | +* Wireless charger module - https://www.amazon.com/dp/B0BRMMYZR2 |
| 107 | +* Magsafe magnets - https://www.amazon.com/dp/B09FZ5Z7S4 |
| 108 | +* 5v stepdown, should work with 5v input too - https://www.amazon.com/dp/B07MS1ND5M |
| 109 | +* M4 screws 16mm - https://www.amazon.com/dp/B07CK5C5MM (smaller sizes will work too like 12mm, 10mm) |
| 110 | +* M3 screws 6mm - https://www.amazon.com/B01B1OD0IC |
| 111 | +* Glue - anything that will hold the PLA in place like CA, superglue, E6000, all purpose glue, etc. https://www.amazon.com/dp/B00C32MKLK |
0 commit comments