Ghost Rider: Custom LED Flaming Head

by pix3lot in Craft > Costumes & Cosplay

858 Views, 7 Favorites, 0 Comments

Ghost Rider: Custom LED Flaming Head

My 12-year-old asked to be Ghost Rider a comic book character that sold his soul and now rides around on a motorcycle as a skeleton with his head permanently on fire. As costume briefs go its all pretty straight forward, except for having your head on fire.

I told my son we could do it with real fire but it would only work once and he would be bald after, and surprisingly he didn't like that idea. So, back to the drawing table.

Our last Instructable went up almost ten years ago. In this one I programmed LED panels for Pac-Man costumes, so it seemed to be a good place to start.

Here is the idea, wrap his head in flexible LED panels, and put on a particle fire effect — we ended up with 4 16x16 panels for 1,024 pixels of pure flaming skull, powered from a 20,000 mAh battery on a belt, that can run it all Halloween night.

Supplies

  1. 4 × WS2812B 16×16 flexible panels (6.3 in square)
  2. ESP32-S3 dev board + screw-terminal expansion base (I used ESP32-S3-N16R8)
  3. USB-C PD power bank, 20,000 mAh
  4. USB-C PD trigger board with screw terminals
  5. Wago 221-415 lever nuts (Two minimum, five ports each - I bought an assortment which was super helpful so I avoided soldering and shrink tubes)
  6. 18 AWG silicone wire, red and black
  7. Multimeter
  8. Inline USB power meter
  9. Duck tape
  10. Zip ties
  11. Fanny pack
  12. Skull mask
  13. Awesome biker jacket
  14. Black jeans

Plan the Geometry

A cylinder is the easy case, and it is worth understanding why before you buy panels.

On a dome, "up" points a different direction at every point on the surface, so a flame effect has to be remapped to look right. On a cylinder, up is the same direction on every column. That means a band around the head maps perfectly onto a flat grid — the only difference from a flat panel is that the last column sits next to the first.

So: wrap a band, don't try to cover the whole skull.

The numbers for four 6.3-inch panels:

  1. Circumference: 4 × 6.3 in = 25 inches of band
  2. Measure the wearer's head with the mask on. 25" was perfect for my son.
  3. Band height: 16 rows at 0.4 in pitch = 6.3 inches tall, roughly brow to above the crown

We went with a basic skull mask, but if you want the face covered in LEDs too, buy a separate app-controlled LED mask rather than extending the band.

Setup the Board

Work out what board you have

Read the N-R code printed on the metal module itself, not the carrier board. N8R8 means 8 MB flash and 8 MB PSRAM; N16R8 means 16 MB flash.


The flash size. You need this to pick the right firmware. I had the best luck with the 16.x nightly build. The stable build was not stable for me for whatever reason.


Which USB port to use. Some ESP32-S3 boards have one USB-C port, some have two. If yours has two, look for the one labelled COM or UART and use that one

If your board only has one port, you can still flash it. Hold the BOOT button while plugging in the cable, then release it. That puts the ROM bootloader in charge of USB so the chip does not reset itself out from under the installer.


Flash it

  1. Plug the board into your computer using the COM port if it has one. Use a cable you know carries data — charge-only USB-C cables will power the board and nothing else, and this wastes a surprising amount of time.
  2. Check it appeared. On Windows, Device Manager → Ports (COM & LPT); you want a new COM number. On Mac or Linux, ls /dev/cu.* or ls /dev/ttyACM*. Nothing there means the cable or the port is wrong.
  3. Open the installer at wled-install.github.io in Chrome or Edge. Firefox and Safari cannot do WebSerial, so they will not work.
  4. Pick your firmware. Choose the build matching the flash size you read in the last step — for example ESP32-S3 (8MB Flash, OPI FLASH).
  5. Click Install and choose your port from the browser's prompt. If several appear, pick the one that showed up when you plugged the board in.
  6. Let it erase and write. It takes a couple of minutes. Leave the tab visible; some browsers throttle background tabs and slow the write to a crawl.
  7. Unplug and replug when it finishes, rather than hitting reset.

If the installer hangs at "Wrapping up", the write has already finished — that step is just the post-flash reconnect, which often fails on S3. Close the tab, replug, and carry on to the next section.


Helpful note: watch for the XMC flash errata

This one cost me a whole evening and a board. Run an erase first and read the output:

python -m esptool --chip esp32s3 --port COM5 erase-flash

If you see this, the board is faulty:

WARNING: XMC flash chip boot-up failure detected!
WARNING: Could not confirm XMC flash chip boot-up fix. The flash chip may not work.

Board are cheap and I had a few that were faulty, buy them in a three-pack. They are $6 each and this is why.


Then Connect

Flash the board. Some installers offer to take your WiFi credentials during the write; on S3 boards that step often never appears, and it didn't on mine. Use the access point instead.

  1. Power-cycle the board once flashing finishes
  2. Join the WiFi network WLED-AP, password wled1234
  3. Browse to 4.3.2.1
  4. Config → WiFi Setup, and enter your home network there

Then look for the board at http://wled.local. If that doesn't resolve — Windows mDNS is unreliable and it failed for me — find the device in your router's client list, usually named something like wled-a1b2c3, and use its IP directly. Give it a DHCP reservation while you are in there, so it doesn't move between sessions.

You don't strictly need it on your home network. AP mode works fine for the costume, and you won't be in range of your router on Halloween anyway. Joining your network is a convenience while you build. What makes it work untethered is saving a preset that loads on boot — then it comes up running fire the moment it gets power, with no phone involved.

Light One Panel

One panel, low brightness, before anything else gets wired.

  1. Set master brightness to zero in the WLED interface first. This is your insurance policy.
  2. Wire one panel. The pigtail colors are printed on the box: red = VCC, white = GND, green = data. Connect at the DIN end — the panels have arrows printed on them showing signal direction. DIN and DOUT look identical and wiring into DOUT gives you a panel that never lights while everything else appears correct.
  3. Green → GPIO 16. White → board GND. Red → 5V (but read the warning below first).
  4. In Config → LED Preferences: length 256, type WS281x, color order GRB, GPIO 16, max current 800 mA.
  5. Raise brightness to 10%.


Safe GPIOs on the S3 are 1–18. Avoid 0, 3, 45, 46 (strapping pins), 19 and 20 (native USB), and 26–37 (flash and PSRAM).


Learn from my mistake:

The 5V pin may be an input. On many ESP32 dev boards, the pin labelled 5V is a power input, not an output. USB power goes straight to the onboard regulator and down to 3.3 V; there is often a blocking diode between VBUS and that pin.

My symptom: 5.2 V going into the board on a USB meter, and 0.7 V measured at the 5V pin. That 0.7 V is a diode drop, not a rail. D'oh!

I spent an evening checking continuity, reflowing joints and suspecting dead panels. The panel was fine. It was simply never receiving power.


Check this before anything else. Meter DC volts between the board's own GND and 5V pins. If it reads under 1 V, the pin is an input and you skip straight to Step 4 — you cannot run even a single panel off the board.

A panel moved to 3V3 will usually light, dim and color-shifted. Useful as a ten-second diagnostic. Not something to build on.


If the panel lights up - on to the next step!

Wiring the Panels

Notes

I ran two 5V feeds for four panels, one per pair. Each fed panel passes power to its neighbor through the JST jumpers that already carries the data line as well. How far you can push that depends entirely on brightness, but from my experience you don't need much brightness on these panels, especially at night.


Meter before you connect

This was super helpful for diagnostics to make sure signals and power were being passed where it was expected.

  1. Set the trigger board to 5V and plug it into the bank with nothing on the output.
  2. Meter across its screw terminals. Confirm it reads close to 5 V.
  3. Only then wire it to the Wago blocks, and meter once more at the blocks themselves.

If the trigger negotiated 20 V and you wire that to the panels, all four die instantly. If it will not negotiate above 5 V, the cause is almost always the USB-C cable — a charge-only cable cannot carry the PD negotiation.


Capacity

I used a single power bank with two outputs to run the LEDs and the board - rather than having the extra weight of another power supply.

This detail that makes this work is that both outputs share the bank's internal ground, so the panels and the controller have a common ground reference without a wire between them. The data signal needs that reference to mean anything.

Two banks have no shared ground, and the data line then has nothing to measure against — you get flicker and garbage that looks exactly like a wiring fault. One bank, two outputs.

Using the inline USB-C power meter we could see what was being drawn and do a little math and found out that one 20,000 mAh bank was plenty to run the costume all night.

Most banks also drop every port to 5V once you draw from more than one, which is normally a limitation, but here this is what we wanted anyway.

A 221-415 block has five ports: one in, four out. With just two panel feeds, one block per rail is plenty. Feed every panel directly and the GND side needs five, so you would bridge a second block with a short jumper. The data split uses a third block of its own.


Chain all four panels

Decide the physical arrangement before you wire, because the matrix configuration in Step 6 has to match it.

  1. Data: panel 1 DOUT → panel 2 DIN → panel 3 DIN → panel 4 DIN. The JST connectors mate directly.
  2. Check every arrow. Each jumper runs DOUT → DIN. The connectors mate happily backwards, and a reversed link gives you a chain that lights up to that point and then stops dead.
  3. Power: run a feed to panels 1 and 3 from the Wago blocks. Panels 2 and 4 get theirs through the jumpers. See Step 4 for when that is not enough.
  4. Update LED Preferences: length 1024, and raise the max current.


Panels alternate direction

Worth knowing before Step 6: when you tape panels in a row, panel 1's DOUT sits at its right edge, so panel 2's DIN is also on the right and panel 2 runs right-to-left. Panels alternate direction down the chain.

WLED handles this natively because it lets you set the first-LED corner per panel. Any custom mapping you write yourself has to account for it, and it is not obvious until you see mirrored output at the seams.

Configure the Matrix

Until you do this, WLED treats the whole thing as one long strip and effects run along the physical wiring path. The symptom is unmistakable: a snake crawling back and forth instead of a picture.


Go to Config → 2D Configuration and set Number of panels to 4.


Then set the size to 16x16 for each panel, check serpentine on. Leave Offset Y at 0, but change offset X like this:

Panel 0 - Offset X: 0

Panel 1 - Offset X: 16

Panel 2 - Offset X: 32

Panel 3 - Offset X: 48


Notes:

The offsets are what place the panels side by side. Leave them all at zero — the default — and WLED stacks all four in the same spot.

First LED and Orientation start at Top / Left / Horizontal. That worked for my panels; yours may differ.


Verify with the test pattern, not with fire

This matters more than it sounds. A fire effect looks like scattered pixels whether your mapping is right or wrong, so you cannot judge the matrix from it. Use the built-in test pattern, confirm nothing is mirrored or jumping at a seam, and only then switch to fire.

If one panel reads backwards, change that panel's First LED corner. Work one panel at a time.

Light Up the Fire!

WLED ships three approaches, and they look genuinely different.

  1. Fire 2012 - Random sparks at the base, heat diffuses upward and cools, columns independent. Flickery and alive, but each column burns on its own
  2. 2D Firenoise - Samples a Perlin noise field that scrolls upward. Coherent connected flame shapes, soft taper, smoother
  3. PS Fire - Particle system — emitters release particles that rise, drift and cool. Broken base, soft tips, most convincing of the three

I used PS Fire. The base breaks up and the tips fade out as a property of the physics rather than something you tune in.


Improvements

  1. All three effects emit from a fixed bottom row, so the base of the fire reads as a straight horizontal line. I think if this was a variable bottom edge it would be better, but I didn't have time to fix it :(
  2. Add a layer of mesh or diffusion material so the LEDs are not as defined

Finishing Touches

Create the Cylinder

Duct tape, across the backs of the four panels. Cheap, simple, effective — my favourite kind of solution. The tape spine holds the band in a cylinder and takes the strain off the JST connectors between panels.

The finished cylinder sits on the crown of the head and rises from there, above a skull mask. It reads as a crown of fire rather than a burning face, which is both easier to build and closer to the character.

Mind the overlap at the back where the ends meet. A gap there is invisible in use; overlapping panels hides columns and stops matching your matrix config.


Create a "Bundle"

Zip-tie the board and the power bank together into a single bundle that rides at the waist. Keeping them as one object means there is one thing to stow, not three things to work loose.

Three wires run from the bundle up to the head, long enough to reach from the waist to the back of the skull:

  1. (1) 5v power from the trigger board (fed by the power bank)
  2. (2) Ground wire from GND of ESP32-S3 board
  3. (3) Data line from GRIO 16 on the ESP32-S3 board

That's it. The Wago blocks live at the head end, inside the cylinder, where the 5V splits to the two panel feeds and the data splits to the two chains. Only three conductors make the trip up the back.

Note - this bundle can look a bit...explosive, so maybe don't let the kid bring it to school ¯\_(ツ)_/¯


Manage the Wires

Small zip ties and electrical tape, everywhere. Nothing should stick out, and no wire should ever take a pull that reaches a connector.

This step matters more than it sounds. A 12-year-old running down a street is a more demanding mechanical environment than a workbench, and every connection you made is a connection that can be yanked apart. Strain-relieve the umbilical where it leaves the bundle and again where it enters the cylinder, so a snag pulls on tape rather than on a JST plug.


Order to put it all on

It only assembles one way:

  1. Bundle into a fanny pack, fanny pack around the waist
  2. Skull mask on
  3. LED cylinder over the mask, wires run down the back
  4. Leather jacket over the wires

The jacket is doing real work here — it hides the umbilical and holds it against the back, so there is nothing swinging loose.


Let them switch it on themselves

I showed my son how to unplug the cable at the power bank. Crude, but it means he controls his own head and he can kill it if anything feels wrong.

Tidier options: wire an inline switch, or buy a power bank that has its own on/off button. If you fit a switch, put it on the 5V line between the trigger and the Wagos, and use one with an explicit DC rating — a switch marked only for AC may handle a fraction of its rated current on DC.

PROFIT!

The most important step, and the one most builds skip.

Get on your motorcycle, ride around the neighborhood being awesome, and collect candy.

If you are twelve and do not have a motorcycle, a bicycle is canonically acceptable and so is walking. The flaming skull is doing the heavy lifting.