Firmware for a DIY rotating-lens panoramic film camera controller. It runs on an M5Stack StickS3 and drives a Feetech STS3032 serial bus servo to spin a lens drum; the rotation itself is what exposes the film.
This camera has no shutter mechanism (just a front cap). A slit (1mm wide) cut into the drum passes over the film gate as the servo rotates, exposing the film in a slit-scan fashion. Exposure time is determined by how fast the slit sweeps past the gate, i.e. the servo's angular velocity.
Since there's no way to close the shutter, shots are taken in alternating directions: 1st CW, 2nd CCW, 3rd CW, and so on. By keeping the accel/decel margins symmetric on both sides, the end position of one shot is exactly the correct start position for the next (reversed) shot, so consecutive shots need no return move.
- Body: M5Stack StickS3 (ESP32-S3)
- Servo: Feetech STS3032 (serial bus, half-duplex UART, 1Mbps)
- UART level converter: Bus Servo Driver Board for Seeed Studio XIAO, or similar
- Lens: 28mm, 1mm slit width, 120° exposure angle
- Optional external trigger switch / cable release
| Pin | Signal | Pin | Signal |
|---|---|---|---|
| 1 | GND | 2 | G5 (external trigger) |
| 3 | EXT_5V | 4 | G4 |
| 5 | Boot (do not use) | 6 | G6 |
| 7 | G1 (servo TX) | 8 | G7 (servo RX) |
| 9 | G8 | 10 | G43 |
| 11 | BAT | 12 | G44 |
| 13 | 3V3_L2 | 14 | G2 |
| 15 | 5V_IN | 16 | G3 |
The servo connects to TX=G1 (pin 7) / RX=G7 (pin 8). An external trigger (cable release, etc.) shorting pin 1 (GND) to pin 2 (G5) acts the same as a short press of BtnA.
Warning
Power pins (EXT_5V/BAT/5V_IN) sit right next to these signal pins. Before wiring anything up, visually confirm the actual pin positions against the board silkscreen or the official pinout diagram.
- Add the M5Stack board manager to the Arduino IDE and select StickS3 (ESP32-S3) as the target board
- Install M5Unified from the Library Manager
- Open this repo and flash
PanoramaCamera.ino
- BtnA short press / external trigger short: fire the shutter
- BtnB short press: cycle exposure speed presets (1/256, 1/128, 1/64, 1/32s)
- BtnB long press: enter config mode (for initial setup or re-calibration after disassembly)
- Screen: speed panel on the left; IMU-based spirit level on the right (green when level, red otherwise)
- Torque releases, so hand-turn the drum to its mechanical center mark
- Long-press BtnA to record the center position. The start position (where exposure begins) is computed automatically from the center, and the servo moves there on its own
- Fine-tune if needed with BtnA (-5 ticks) / BtnB (+5 ticks)
- Long-press BtnA to save and return to normal mode
- The servo resolves absolute position commands as a simple subtraction between target and current position, so it cannot move across the 0/4095 wrap point (one full revolution). If the drum's mechanical center mark sits too close to that boundary, firing will swing the drum much further than expected. Re-mount the servo horn so the center mark lands around electrical position 2048 (the middle of the range). Config mode includes a safety check that refuses to save a center position too close to the edge
- Integration with a film-advance mechanism (how to trigger after a shot completes) is not yet designed