Focusing the P3: the ring reports nothing, so read focus from the image

The P3's focus ring is a purely mechanical twist ring. Nothing inside the camera senses it and nothing in its data reports it. What does work: a live sharpness score computed from the camera's own frames, a fixed working distance, and a witness mark on the ring.

Thu . Checked by 72 research agents, each key claim attacked by two skeptics, plus a live test on the P3 streaming from the Realme. Tool: tools/p3_focus_meter.py in ~/git/thermal-android.

0
focus fields
in 290-odd camera commands and 512 metadata words
49%
score drop at a 0.5 px blur
on the live stream; noise is 0.4%
±2–4 mm
in focus at 60 mm
±2.2 mm for under 1 px of blur, ±4 mm for 2 px
0
marks on the ring
no scale, no index: add your own

No sensor: five places that would show a focus reading show none

Where we lookedWhat was checkedFocus reading
Thermal Master's manualSpec table says "Manual Focusing Lens"; the word focus appears nowhere else, and there are no focusing instructionsnone
USB descriptorsEvery interface is vendor-specific (0xFF), with no USB Video Class camera terminal, so the standard focus controls cannot existnone
InfiRay's command librarylibircmd020.so from the official app and two published copies of libircmd.h: no focus, lens, motor, encoder or Hall command; the only zoom is digitalnone
The official appAll its native libraries and both dex files: no focus assist or sharpness indicator; its "focus" code drives the phone's own camera on dual-camera modelsnone
Per-frame metadata, liveThe SDK's 35 metadata fields have no focus field; 491 of 512 words stayed byte-identical across captures 20 minutes apartnone

This is evidence from absence: nobody has turned the ring while logging. The focus meter's exit report does exactly that check (below).

Read focus from the image: a half-pixel blur halves the score

Blur of 0.5 px
Laplacian
−49%
Brenner
−13%
Blur of 1 px
Laplacian
−85%
Brenner
−40%
Blur of 2 px
Laplacian
−97%
Brenner
−71%

Drop in each score when a live P3 frame is blurred on the computer; the score's own wobble over 8 s was 0.4%.

Run it from any Mac that can reach the phone (Wi-Fi, Tailscale or an adb forward), then turn the ring slowly:

python3 ~/git/thermal-android/tools/p3_focus_meter.py --url http://<phone>:8080

   9.7s      6549.3  ##############################  99.9% of peak  norm 0.0258
Peak smoothed score 6556.7 over 248 frames.
No unexplained metadata word changed during the run.

At 45–70 mm the sharp zone is 4–12 mm deep, so fix the distance first

Lens to boardBoard per pixelSmallest featureDepth in focusLens travel from ∞
45 mm0.11 mm0.23 mm4.3–4.8 mm0.45 mm
60 mm0.16 mm0.31 mm7.9–8.8 mm0.33 mm
70 mm0.18 mm0.37 mm10.8–12.1 mm0.28 mm

4.3 mm lens (the serial's lens code), 12 µm pixels, f/1.0–1.1, 2-pixel blur with diffraction included; feature = 2 pixels. The focus simulator uses 1 pixel: ±2.2 mm at 60 mm.

Focus warm: a hot camera focuses closer

If the lens is germanium
≈3 mm closer

About 0.7 µm of focus shift per kelvin. If the gap runs 20–25 K warmer than the bench, best focus moves about 3 mm toward the camera, most of the sharp zone at 45 mm.

If it is chalcogenide glass
≈1 mm closer

About 3.4 times less shift, small next to the depth in focus. No source says which material the P3 uses.

Optics constants from Riedl via the University of Arizona OPTI 521 report. Rule: set or check focus after the camera has warmed up where it will work.

The mechanical check: a fixed distance and a witness mark

The ring carries no scale or index mark, so out of the box there is nothing to read. But reviewers find it smooth, damped and free of backlash, so a mark you add stays meaningful.

  1. Pick one datum and gauge it, not by eyeThe ring's front rim is the only surface you can touch; the lens sits recessed behind it. Set lens-to-board distance with the printed spacer or bracket, not a ruler.
  2. Mark the ring and the body togetherOnce focused, draw a paint-pen line across the joint. Any slip later shows as a broken line.
  3. Optional: make your own distance scaleFocus on targets at 45, 55 and 65 mm and mark each on the ring: an empirical scale for this unit.
  4. Lock it reversiblyA split collar over ring and body, as the hub's mount plan has. Never glue or thread-lock an optical helicoid.

The procedure: focus on the bench at the real distance, then confirm in place

  1. Warm up for about 10 minutesThe shutter clicks space out once the camera reaches balance. Warm it near its working temperature if you can.
  2. Freeze the image pipelineFixed noise reduction (both at 0 is best), auto-FFC off for the sweep, one manual shutter just before. In the official app, X³ off: it fakes edges.
  3. Put a contrast target at the exact distanceSquares of aluminium tape on something warm and matte, such as a mug of hot water or a powered board, tilted a few degrees. The foil mirrors the cool room while the surface around it glows: a sharp step in one plane.
  4. Sweep through the peak, then come back to itTurn slowly until the score falls, back off, and return from the same side. Let the ring settle a moment before reading.
  5. Mark, lock, mount, checkWitness mark, collar, into the gap. If the board shows texture, the score in place should match the bench.
Safety

The P3's shell and ring are bare metal. Near a powered card, insulate the front face with Kapton, never over the lens. Gough Lui warns of shorting a live board this way.

Two bugs this research found in our own code
  • P3Protocol.kt reads metadata words 176, 174 and 168 as FPA, lens and shutter temperatures, but they are the scene's mean, maximum and minimum. The same file's decodeInfoLine says so. So fpaTempC in /api/status is the scene mean, and there is no lens-temperature reading.
  • The README says the raw stream's header magic is P3R1; the stream actually sends P3FR.
Sources

Part of the thermal camera hub. See also the focus simulator (where to put the camera), Friday thermal measurements and Remote camera setup.