Exocortex Labs

Builder guide

From an empty bench to a helmet on a head. It follows the design docs; the docs are the authority, and this page links to the section each step comes from. Nothing below has been done on a real helmet yet. Steps marked (unverified) are written from the design and will change when the first unit is built.

Before you start: the order files are not all ready. Of the 9 tile designs, routing is finished for some and in progress for the rest; the tile panels' Gerbers, BOMs and CPLs come once all nine are clean (design § where it stands, boards § routing). The hub and camera files are ready. Check the status table on the site's build page before you order.

What you need

what
money about $2,085 for one helmet, all parts, boards, assembly and fees, before shipping and import duty (ordering)
printer an FDM printer that prints PETG; the settings are for an Ender-3 V3 SE with a 0.4 mm nozzle (shell § print settings)
tools a soldering-iron tip for heat-set inserts (M2 × 3), a #1 Phillips and a Torx T6 driver (for the M2 screws; check the heads you got), flush cutters for supports and panel tabs, tweezers, epoxy for the splice tabs, Kapton or 0.2 mm double-sided PI tape (cameras)
programmers a two-wire debug probe for the CH32V203 tiles (WCH-LinkE class) (unverified: the repo does not name one yet); a Raspberry Pi Debug Probe (or a USB cable to the RP2350 test pads); a 3.3 V USB-serial adapter for the ESP32-S3s
a computer to run the app (app/, Node 22.18 or later) and the flashing tools

1. Order the parts

Follow ordering one helmet exactly. It is regenerated from the boards, so its numbers are current. Summary:

  1. JLCPCB, four orders: CAP-01 and CAP-02 (the tile panels), HUB and CAM. Every option on each order form is in that page's tables: layers, thickness, ENIG, via filling, assembly on both sides, PCBA quantity 2.
  2. On JLC's parts page, check every line against out/sourcing/cost.json: the same LCSC number, stock green. In the placement preview, check pin 1 of every QFN, the SC70 parts, the FPC connectors' orientation, and that every pogo pin is on the scalp face.
  3. LCSC cart: the FPC jumpers (all Type B, 12-way), the M2 screws and the inserts. Check the photo of the 400 mm cable (C55509681) before you buy: its part number says type B, its description says "Same Side".
  4. Other suppliers: five OV2640 160° camera modules (Probots), the 2000 mAh 1S battery with a JST-PH lead (MaxAmps), a Carhartt A18 beanie, 1 kg of PETG. The battery: the MaxAmps pack in the order is a hobby RC pack with no protection circuit of its own. The regulatory review recommends a 1S pouch with its own protection circuit and a 10 kΩ NTC lead, tested to IEC 62133-2 and UN 38.3, rated at least 3.8 A continuous, that fits the 72 × 47 × 10 mm pocket . Prefer one when you build for wearing.

JLC builds two of every panel, so the order makes one helmet plus a spare pair of each tile design, a spare hub and a spare camera board. Keep the spares; they are your repair stock.

2. Print the shell

  1. Print out/stl/EXO-140.stl to EXO-144.stl in PETG (shell § print settings): 0.2 mm layers, 7 walls (so the 2.8 mm wall prints solid), 5 top and bottom layers, 20 % infill, 240 °C nozzle, 80 °C bed, 60 mm/s, 40 % fan, a brim. The crown and the two bands need tree supports; the tabs and the battery cover print flat without. [docs/order.md says 6 walls; docs/shell.md explains why it is 7. Use 7.]
  2. The parts are already in print orientation: the crown dome down, the bands upside down on the seam plane.
  3. Remove the supports. Check every standoff for stringing in its Ø1.7 mm pilot hole: the screws cut their own thread there.
  4. Epoxy the splice tabs (EXO-143) across the three seams on the inner face, clear of the boards.
  5. Heat-set the four M2 × 3 inserts for the battery cover.

3. Flash the boards

Boards arrive assembled and blank. Flash each before it goes into the shell: a tile buried under cables is hard to reach.

Tiles (132 CH32V203 microcontrollers, two per tile) (unverified).

  1. Build: cd firmware/tile && make sdk && make gives build/tile.bin (the whole flash: boot stub and application) (protocol § tile firmware).
  2. Program each converter through its debug pads (TPD, TPC, TPR) with the probe. Power the tile through its IN connector's VIN and GND (3.6 V) or the probe's supply.
  3. After the first flash, every later update goes over the chain from the hub (FW_BEGIN / FW_DATA / FW_COMMIT to all converters on a port); you never need the probe again unless a converter is bricked.

A pogo-pin fixture that holds one tile and touches both sets of pads saves hours over 66 tiles. None is designed yet.

The hub (two RP2350B and one ESP32-S3) (hub firmware § flash):

  1. Build with firmware/hub/build.sh.
  2. RP2350 A: short TPABOOT to GND, pulse TPARUN low, release; the chip appears as a USB drive on its test pads (TPAUSBP/TPAUSBM); copy hub_a.uf2. Or program over SWD (TPASWCLK/TPASWDIO) with OpenOCD. RP2350 B the same with the TPB* pads and hub_b.uf2.
  3. ESP32-S3: hold TPWIO0 low, pulse TPWEN, then flash over TPWTX/TPWRX with esptool.py --chip esp32s3 (the command is in the firmware README).
  4. After this, the ESP32 updates both RP2350s and itself over the air or USB.

Cameras (five ESP32-S3 boards) (camera § firmware notes):

  1. Power through TP1 (3.4-4.4 V) and TP2 (GND), tie TP3 (CAM_EN) to TP1.
  2. Hold TP8 (IO0) low and pulse TP7 (EN) low; flash over TP5/TP6 with esptool.py --chip esp32s3, or use the USB-Serial/JTAG on TP9/TP10 with no strapping.
  3. Later updates go through the hub (firmware target 64 + camera − 1).

4. Fit the cameras to their boards

For each of the five camera boards (camera § assembly):

  1. Open J1's flip lock.
  2. With the board face down, slide the camera's tail into J1 from the left edge, gold fingers towards the board.
  3. Close the lock.
  4. Fold the tail 180° round the left edge, and stick the camera body on the module's shield with 0.2 mm double-sided PI tape, lens out, centred on the lens mark.

5. Assemble

The order below goes from the inside out, so nothing you fit blocks a later screw (unverified).

  1. Tiles. Each tile has its place on the cap (design, the colour map; out/cap_layout.json gives every tile's position and design). Fix each with two M2 × 6 screws from the scalp side into its standoffs (shell § standoffs). Turn the screws until snug; the thread is cut in PETG, so do not over-tighten.
  2. Chain cables. For each of the 16 chains, connect each tile's OUT (J102) to the next tile's IN (J101) with the jumper of the length in out/shell_v1_report.json → fpc. Each cable goes up through the slot behind its connector and lies in its channel on the outer face. Every cable is Type B: a cable of the other type swaps pin 1 and pin 12 and shorts the port's supply (the port's switch then latches off).
  3. The hub. Mount it on its four standoffs in the pod with M2 × 6 screws. Its REF and BIAS pins face the scalp.
  4. Chain heads. Connect each chain's first tile (J101) to its hub port. Port n carries chain n of out/pcb/cap/boards.json; the channel map (protocol/map.json) assumes it (protocol § hub procedures).
  5. Cameras. Click each camera board into its cradle on the cuff, and connect its J2 to the hub's camera port with its cable.
  6. Battery. Connect the battery's JST-PH lead to the hub's battery connector (BAT+, NTC, BAT−). The MaxAmps cell has no thermistor: fit a 10 kΩ resistor on the TS pin, as ordering § things to know says, or the charger will not charge (unverified). Put the cell in its pocket and close the cover (EXO-144) with four M2 × 5 screws.

6. First power-on (on the bench, not on a head)

  1. Plug in USB-C. The hub charges the battery and holds the contacts' supply off while USB power is present: this is the interlock, and it is meant to be there (hub § isolation and faults).
  2. Install and start the app (cd app && npm install && npm run build && npm start, or the desktop app). Under Settings › Sensors, choose USB, auto. The app finds the hub's FT2232H.
  3. Check the hub's STATUS: battery voltage and charge, both RP2350s, the ESP32.
  4. Unplug USB. Now the tiles can be powered. Give the hub your Wi-Fi network (the HUB_WIFI command; the app's sensor settings send it) and connect over Wi-Fi.
  5. Enumerate all 16 ports. Each port must report 2 × its tile count of converters (6, 8 or 10), and only the last converter in each chain reports SENSE high (protocol § hub procedures). If a port fails, see troubleshooting § a chain does not enumerate.
  6. Start a recording with the helmet on the table, then with your hand on a few contacts: the head map should show those contacts change. On the table, every contact should show an open circuit; nothing should read as a perfect contact.
  7. Power the cameras one at a time (CAM_SET), give them your Wi-Fi (CAM_WIFI), start the streams (CAM_STREAM). Each privacy LED is on whenever its sensor has power.

Bench only: removing the 0 Ω link RJP1 lets the helmet measure with USB connected. Do that only with the helmet on a phantom (a saline-soaked sponge head), never on a person, and refit it before anyone wears the helmet. A sold unit will not have RJP1.

You are the builder. A helmet you build from the files is a home-built device under FCC § 15.23: it must not cause interference, and you may not sell it.

7. Put it on (unverified)

  1. Charge it fully. Unplug the cable.
  2. Part or flatten your hair as little as you can; the pins are made to go through it.
  3. Put the helmet on back first, then roll the front down over the forehead, as you put on a helmet with a low back (shell § seams and printing). The pins press at most 1 mm into the hair while it goes on.
  4. Pull the beanie over the shell. Its hem goes at least 4 mm under the shell's rim all round, and the cuff holds the hem against the head (beanie). The camera lenses come through the knit at their grommets.
  5. In the app, look at the contact quality (the 125 Hz tone each contact sees, hub § part choices, REF and bias). Wiggle the helmet gently until most contacts settle. Contacts that stay poor: see troubleshooting.

The retention headband is not designed yet. It will hold the shell against the head with less force from the beanie. Until then, the beanie's cuff does that job.

8. Runtime and heat

With all five cameras streaming, the battery lasts about 32 minutes; with the cameras off, about 1.7 hours (hub § power budget, calculated, not measured). The cameras are 68 % of the power and most of the heat in the cuff. Stream them only when you need them. Take the helmet off if it feels warm.