3D-Me
Patent pending · 2026

Automated multi-axis foot scanner

See the whole foot without standing on it.

A two-axis robotic arm swings a phone camera around a resting foot, then rebuilds it as a measured 3D model. Built for spotting diabetic foot ulcers early.

XIAO ESP32-C3 2× TMC2209 Pixel 9 FastAPI + COLMAP
SCAN 312— safe / — skipped
camera waypoint leg no-go zone foot

The problem

The sole is the hard part to see

Diabetic foot ulcers often start on the bottom of the foot, where neither the patient nor a quick clinical glance catches them. Standard foot scanners have the patient stand on a glass plate, which flattens the very tissue you want to inspect.

3D-Me scans the foot non-weight-bearing. The patient sits with the foot resting, and the arm moves the camera around it on a sphere. The result is a full-colour 3D surface of the foot in its natural shape, sole included, that can be measured and compared over time.

System

Three pieces, one job each

Heavy computation stays off the device. The arm only moves, the phone only shoots and coordinates, and a GPU machine does the thinking.

01 · Motion

Firmware

XIAO ESP32-C3 driving two TMC2209 steppers over UART, with a PCF8574 expander for endstops and LEDs. Deliberately minimal.

  • TCP CLI on port 23
  • Web UI · OTA · mDNS
  • AP setup fallback

02 · Capture

Orchestrator

A Pixel 9 runs the scan: it asks the server for a path, commands the arm to each waypoint, takes the photo and uploads it.

  • Locked exposure + WB
  • One photo per waypoint
  • Uploads as it goes

03 · Reconstruction

Processing server

FastAPI service that plans the scan, finds the leg, and turns photos into a textured mesh.

  • /analyze · /plan
  • /reconstruct
  • COLMAP + OpenMVS

Scan workflow

Look first, then scan

The arm must never hit the patient's leg, so every scan runs in two phases.

  1. 1

    Discovery sweep

    A short, safe pass of photos from positions known to be clear of the leg.

    arm + phone
  2. 2

    Find the leg

    The server detects the leg in the sweep images and builds a no-go zone map.

    POST /analyze
  3. 3

    Plan waypoints

    Camera positions are spread evenly over a Fibonacci sphere, then anything inside the no-go zone is dropped. The quality setting picks the count, e.g. Scan 312.

    POST /plan
  4. 4

    Full scan

    The phone walks the arm through every safe waypoint and photographs the foot at each one.

    arm + phone
  5. 5

    Reconstruct

    COLMAP solves geometry using the known arm angles as pose priors, then OpenMVS densifies, meshes and textures it.

    POST /reconstruct
  6. 6

    Deliver

    A single GLB file with a UV texture atlas, viewable in a browser or on Android.

    .glb

Reconstruction

Telling COLMAP where the camera already is

Off-the-shelf photogrammetry guesses each camera position by matching features between photos. Skin is smooth and low-texture, which makes those guesses fragile. But the scanner already knows where the camera is: it put it there.

reconstruct.py is a pose-seeding layer on top of COLMAP. It converts stepper angles into camera poses and injects them as priors, so COLMAP refines known positions instead of solving blind. It also runs in plain unposed mode for hand-shot test sets, and exposes run_pipeline() so the FastAPI server can call it directly.

Finding from testing

Flat test targets fail no matter how much texture they have. A plane gives no parallax, so structure-from-motion has nothing to triangulate new views against. Validation now uses real 3D objects.

Arm protocol

A CLI a phone can drive

Newline-terminated ASCII over TCP port 23 or USB serial at 115200 baud. Every reply starts with OK or ERR, and any command sent mid-move gets ERR BUSY.

motionHOME MOVE MOVR STOP RELEASE configCALIBRATE SET GET statusSTATUS POS PING ENDSTOPS systemOTA REBOOT FACTORY_RESET HELP

Hardware

The 3D-Me board

A custom KiCad PCB carries the controller, both drivers and power. The first schematic review turned up a list of fixes for the next revision.

PartRoleNote
XIAO ESP32-C3Controller, WiFiRuns the motion firmware
TMC2209 ×2Stepper driversUART addresses 0 and 2
PCF8574I²C GPIO expanderEndstops and LEDs
Buck converter24 V → 5 VLogic supply
Next-revision fixStatus
U2 MS1 tied to 3.3 V, giving the wrong microstep settingto fix
LED net mismatches; dead UART_RX netto fix
Floating SPRD and INT pinsto fix
R1 on UART line set to 1 kΩ; add C9/C10 bulk capsto fix
Schematic review completedone