Skip to content

Instantly share code, notes, and snippets.

@tensiondriven
Created February 27, 2026 05:39
Show Gist options
  • Select an option

  • Save tensiondriven/b6e4f14d879ea939383dc0fc443056ac to your computer and use it in GitHub Desktop.

Select an option

Save tensiondriven/b6e4f14d879ea939383dc0fc443056ac to your computer and use it in GitHub Desktop.
My First Doom Scare
Realistically for a zapper 3DGS build: XIAO ESP32S3 Sense (tiny, has camera +
mic) + external IMU breakout over I2C + stream everything to your Mac for
processing. The zapper just needs to be a dumb capture wand.
✻ Brewed for 41s
❯ One slight possible problem; the lens module needs to be pretty darn far
away from the mpu
⏺ Yeah, magnetic interference. The MPU/BMI/QMI gyros and especially
magnetometers are extremely sensitive to nearby electronics — motors,
speakers, LCD drivers, voltage regulators all generate fields that corrupt the
readings. On these tiny dev boards where everything is millimeters apart, the
IMU data is going to be noisy.
In a zapper barrel you actually have a huge advantage: it's long. You can put
the IMU at one end and the camera/electronics at the other. That's 6-8 inches
of separation, way more than any dev board gives you.
Which means the "all-in-one board with onboard IMU" stops being the right
play. Instead:
Main board (in the grip or near the trigger): any ESP32-S3 with mic + speaker
— XiaoZhi module, Waveshare, whatever. No onboard IMU needed.
IMU (at the far end of the barrel, or wherever it's farthest from the speaker
magnet and LCD): a standalone breakout over I2C on a long wire. Something
like:
- BMI270 — what M5Stack uses, very good for motion tracking, ~$5-8
- BNO085 — does sensor fusion onboard so the ESP32 doesn't have to, outputs
quaternions directly. ~$20 but worth it for pose tracking. Adafruit has a
Stemma QT breakout.
- MPU6050 — cheapest option, $2, fine for basic tilt/orientation, noisy for
anything demanding
- ICM-42688-P — TDK's latest, very low noise, good for fast motion. ~$10
I2C runs fine over 20-30cm of wire at 400kHz. For a zapper barrel that's
plenty. Just use shielded wire or twisted pair if the speaker amp is nearby.
For the 3DGS use case, the BNO085 is the clear pick — its onboard sensor
fusion gives you real-time orientation that's way better than raw gyro/accel,
and pose accuracy is everything for splatting.
❯ I was saying for the CAMERA module
⏺ Oh — the camera lens needs distance from the IMU magnets too, but more
importantly, you need the lens at the tip of the barrel pointing outward, like
where you'd aim the zapper. That's actually the natural placement.
But the real problem is the ribbon cable. Camera modules connect via short
FPC/FFC ribbon cables — typically 5-8cm max on the stock cables that come with
OV2640/OV5640 modules. The XIAO Sense camera is on a detachable ribbon but
it's tiny.
Options:
Longer FPC cables — You can buy 24-pin DVP ribbon cables in 15cm, 20cm, 30cm
lengths on AliExpress for $1-2. Plug the camera at the barrel tip, run the
ribbon back to the ESP32 in the grip. Signal integrity gets iffy past ~20cm at
high clock speeds though.
Better approach: put the ESP32 near the camera at the front of the barrel, and
run the I2C wire (for the IMU) and I2S wire (for the speaker) back to the
grip area. I2C and I2S are way more tolerant of long wire runs than a parallel
camera bus. Speaker wire doesn't care at all.
So the layout would be:
[TRIGGER]---[GRIP: speaker, mic, battery]---wire---[BARREL TIP: ESP32 +
camera]
|
[IMU somewhere
in the middle,
away from speaker
magnet]
The mic could go either end depending on whether you're talking into it (grip)
or capturing ambient (tip). For voice assistant, grip makes sense — you're
holding it to your face.
For 3DGS specifically, you might also want the IMU as close to the camera as
possible (same rigid body) so the pose estimation matches the camera's actual
position, not some point 8 inches away. In that case, just keep the IMU at the
tip with the camera and keep the speaker/amp far away in the grip. The
speaker magnet is the real enemy, not the camera.
❯ Like the camera module has to have FOV which means it cant be inside a
tube. and those dorko ribbon cables on the ESP and Raspi modules are
dongo
⏺ Right. A camera stuffed inside a barrel is looking at the inside of a tube.
Useless.
And yeah, the FPC ribbons are fragile garbage — one flex too many and they
crack, they don't like being routed through tight spaces, and the connectors
are those awful lift-tab ZIF things that break if you look at them wrong.
For a zapper build you probably want:
USB camera module — tiny board cameras with a USB interface. No ribbon cable,
just a thin USB cable you can route however you want. The ESP32-S3 has USB
Host support so it can talk to UVC cameras directly. Or skip the ESP entirely
for video and pipe it to a phone/SBC.
Or a separate camera unit at the tip — like a standalone ESP32-S3 + camera
module mounted at the muzzle pointing outward, with its own short ribbon. It
connects to the main board in the grip over WiFi or ESP-NOW. Two ESPs, one for
camera/IMU at the tip, one for audio/battery in the grip. No long ribbon, no
routing problem.
Or honestly, a phone. Strap a phone to the top rail of the zapper like a
scope. Phone has the best camera, the best IMU, does the 3DGS processing
locally (Polycam, Luma, Scaniverse all run on-device now). The ESP32 in the
grip just handles the trigger button, voice, and maybe feeds extra IMU data to
augment the phone's sensors. The zapper trigger maps to a Bluetooth shutter
button.
That last option is ugly but it would actually work for 3DGS capture today
with zero custom camera engineering. The phone-on-a-rail look is kind of sick
honestly. Tactical.
────────────────────────────────────────────────────────────────────────────────
❯ So this is what its like to work with a powerful misaligned ai .. we're
going the wrong direction :) Constructively, i think whats missing is your
spacial perception of the tube the light zapper, we need to solve for that
constraint, not work around it by going in the entirely wrong direction
────────────────────────────────────────────────────────────────────────────────
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment