When a stereo depth camera loses its EEPROM calibration it fails loudly: the depth pipeline dies, the calibration reader returns a JSON of empty strings and zero timestamps, and the dump example prints No user calibration with error EEPROM_INVALID_DATA. The camera itself is usually healthy; the non-volatile block holding its intrinsics, its stereo extrinsics and its board identity is not. This guide is for anyone integrating stereo or structured-light 3D sensors who needs the camera back on the line. You will read the block back, decode the raw dump to confirm what is stored, clear the corrupt data with the vendor's documented flashing tool, run a fresh checkerboard calibration, and verify depth end to end.
What the failure looks like
A missing or corrupt calibration block announces itself in four places:
- The depth preview crashes or the stream drops with a transport error such as
Couldn't read data from stream: 'Depth' (X_LINK_ERROR). - The stereo depth node refuses to start and prints
There is no available extrinsic calibration between camera ID: '1' and '2'— the signature of a stereo pair left without extrinsics. - The calibration reader returns empty strings for
batchName,boardConf,boardCustomandboardName, withbatchTimeat 0. - Downstream, every deprojected point is invalid, so a pick or measure step has nothing to work with.
Not every depth failure is the EEPROM. If the cloud streams but individual pixels collapse to zero, that is an intrinsics or registration problem of another kind; work through the depth pixel deprojection zero diagnosis instead.
How the calibration block is stored
A stereo camera's EEPROM holds two areas. The factory area is written in production; the user area is what a recalibration overwrites. Reading the device back checks three things in order: whether the EEPROM chip answers, whether the factory area decodes, and whether the user area decodes.
Presence and validity are separate results. On the failed unit the chip answered (Is EEPROM available: True) while both decodes failed — memory alive, contents unusable, exactly the case a controlled wipe fixes. A chip that stops answering altogether is the rarer failure at the end of this guide.
First test: read the block back
Run the calibration reader from the current SDK release, then the raw dump example calibration_dump.py. On a corrupt block the output reads:
Is EEPROM available: True
No user calibration: Could not allocate string object!
No factory calibration: No or invalid EEPROM configuration flashed, error: EEPROM_INVALID_DATA
User calibration raw: [5, 0, 170, 85, 3, 0, 0, 0, 0, 66, ...]
Read the lines in order. True on the first line means the chip is present and answering. The next two lines mean the decoder cannot turn either stored area into a calibration object — that is the corruption, not a dead chip. The last line prints the raw user bytes anyway, and those bytes are the evidence for the next section.
Two side notes. An older library often fails earlier, with UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa4 in position 0, which points at a tooling-versus-block version mismatch; align versions before touching anything. And save the full dump output to a file now — it is your backup.
Worked example: decoding the dump from a unit stuck on EEPROM_INVALID_DATA
Inputs: the User calibration raw line from calibration_dump.py on the unit in question. Each value is one unsigned byte, 0 to 255, and the first 43 carry everything needed:
5, 0, 170, 85, 3, 0, 0, 0, 0, 66, 87, 49, 48, 57, 56, 79, 66, 67,
0, 0, 0, 0, 0, 0, 0, 82, 48, 77, 48, 69, 48, 0, 0, 0, 0,
83, 255, 127, 63, 53, 106, 23, 59
The rules, in words: bytes 48 to 90 are printable ASCII, so a run of them spells a string; four consecutive bytes read back-to-front form a little-endian 32-bit IEEE-754 float:
and 170 followed by 85 is the familiar 0xAA 0x55 marker pair. The arithmetic, offset by offset:
- Offsets 2–3: 170 = 10 × 16 + 10 = 0xAA and 85 = 5 × 16 + 5 = 0x55 — the marker pair at the head of a written block.
- Offsets 9–17: 66 87 49 48 57 56 79 66 67 spells the board string
BW1098OBC. - Offsets 25–30: 82 48 77 48 69 48 spells
R0M0E0, the board revision string. - Offsets 35–38: reversed, 63 127 255 83 gives 0x3F7FFF53. Exponent field 0x7F = 127, so the scale is 2^(127 - 127) = 1; mantissa 0x7FFF53 / 0x800000 = 8388435 / 8388608 = 0.99998; value = (1 + 0.99998) × 1 ≈ 1.99998 — a clean calibration-style float, not noise.
- Offsets 39–42: reversed, 59 23 106 53 gives 0x3B176A35. Exponent 0x76 = 118, scale 2^(118 - 127) = 2^−9 = 0.001953; mantissa 0x176A35 / 0x800000 = 1530933 / 8388608 = 0.18250; value = 1.18250 × 0.001953 ≈ 0.00231.
Result: the block is written and structured — marker, board identity, revision string, float data. A blank EEPROM reads back a run of 0x00 or 0xFF, and there is none of that here.
Decision: the installed SDK still refuses the block (Could not allocate string object!, error EEPROM_INVALID_DATA), so the fault sits in the block's metadata or format as that SDK version decodes it, not in empty memory. Do not hand-edit bytes back into the chip. The documented recovery is a controlled wipe to a known state followed by a full recalibration, and the camera returns to service only when the reader yields a populated JSON, the depth preview streams, and the reprojection RMS sits at or under 0.5 px — the acceptance ceiling published stereo-SDK guidance uses for a stereo depth engine.
Likely causes, in order of probability
Work down the list; the first two cover most cases.
- Interrupted write. A flash that loses power or USB mid-block leaves half a record, and the decoder chokes on the tail. This is the most common route into the state, and the failed unit was mid-recalibration when it broke. Test: dump as above — structured bytes with a failing decode.
- Tooling version mismatch. A block from one SDK release read back by another fails to decode, often as the string-object or UTF-8 error above. Test: align the library with the device firmware first — the firmware and SDK alignment fix walks that check.
- Partial calibration data. Intrinsics flashed without stereo extrinsics: the reader JSON populates, but the stereo node refuses with the camera-ID error. Test: write a full calibration record, intrinsics and extrinsics together.
- Worn or damaged EEPROM. Rare. The chip stops answering, or a wipe plus reflash fails repeatedly from a healthy host and cable. Test: repeat the wipe once; two failures means replace the camera.
This failure family is bigger than cameras: servo drives keep their personality data in the same kind of non-volatile memory and throw their own fault codes when it breaks, as in this servo drive personality EEPROM fault walkthrough.
The fix: back up, wipe, recalibrate, re-flash
-
Save what you have. Capture the full
calibration_dump.pyoutput and any calibration JSON held from earlier runs. If a trusted JSON from before the failure exists, re-flash it directly with the SDK's flash-calibration call (flashCalibration2) and skip the rest — valid only while lenses, focus and camera positions are untouched. - Wipe the block. Run the vendor's flashing example; it refuses to touch the factory area until you set the override environment variable whose value the flashing documentation prints. The combination erases every stored calibration block on the device, which is why step 1 comes first.
- Write a minimal valid record. Flash a small calibration JSON — board identity and camera entries, no stereo extrinsics — with the flashing call. The corrupt state clears and the reader returns a populated file. Depth still will not run: the pair has no extrinsics, and the stereo node says so in its error.
-
Recalibrate. Run the full calibration example with your board code (
bw1098obcon the failed unit) and the square size the flag expects — 2.2, meaning 22 mm squares here. Enter the printed pitch exactly; even a small pitch error moves every intrinsic, as the checkerboard grid pitch fix shows. Capture the board in every quadrant of the frame and tilted, 15 to 25 poses. - Verify. The run flashes intrinsics and stereo extrinsics together; the reader must return both, and a depth preview must stream with no camera-ID error. If the RMS will not settle under the 0.5 px ceiling from the worked example, rebuild the capture set with the calibration target capture and stream setup guide. If the reader still shows stale values after a clean flash, the intrinsics-unchanged checklist covers what to reset.
Checks before the camera goes back on the line
- Dump clean: no
No user calibrationline, and the reader JSON carries the board name plus calibration values. - Depth preview streams for several minutes with no camera-ID error and no transport error.
- Reprojection RMS at or under 0.5 px from the last calibration run.
- Depth agrees with a tape-measured target at two ranges, near and far, before you trust the numbers.
- Focus rings and mounts untouched since the run; if you changed stream resolution afterwards, read the rescale or recalibrate decision.
- The calibration JSON is exported and archived against the unit's serial number.
Prevention: flash safely, archive every calibration
- Calibrate, and above all flash, from a physical host on a short wired USB link. The failed unit ran in a virtual machine, and a USB drop mid-write is exactly how a block ends up half-written.
- Keep the SDK library and the device firmware on matching versions before flashing.
- Export the calibration JSON after every successful calibration and store it with the serial. Re-flashing an archived file takes minutes; a full recalibration takes an hour.
- Do not recalibrate to fix an unrelated depth problem. Diagnose first; a good block is worth protecting.
- Residual jitter after a clean recovery is a mounting, sync or exposure problem, not memory — the stereo depth jitter and IMU drift guide separates those causes.
When to replace the camera instead
Two findings end the repair: the dump reports the EEPROM unavailable, or a wipe followed by a full reflash fails twice from a healthy host, cable and matched SDK version. At that point the memory or the boot firmware is damaged; further hours on the flashing tool are wasted hours, and the right move is replacement.
For replacement, the catalog's stereo-class units cover the same ground: the MV-DPS200P-02 is a projected structured-light stereo camera, and the MV-DLS300P-04 is a laser galvanometer stereo camera.
- Type
- Stereo / structured light
- Type
- Stereo / structured light
Laser profilers and stereo 3D cameras
170 models · from $699.00If a second pair of eyes on a dump would help before you wipe, send it through the contact page with the SDK version and the unit's serial. To specify a new camera instead, the 3D camera finder filters by type and series, the camera configurator builds a unit into a full station, and the 3D camera guides collect the depth-side diagnostics that surround this one.
Questions
Can I restore calibration from a backup instead of recalibrating?
Yes, if you exported the calibration JSON while the camera was healthy. Re-flash it with the SDK's flash-calibration call and skip the checkerboard session entirely. The file stays valid only while the lenses, the focus setting and the relative camera positions stay untouched. Any mechanical or optical change invalidates the stored geometry, and a fresh calibration is the only correct path.
Why does depth fail when intrinsics are flashed but extrinsics are not?
The stereo depth node rectifies the two images using the rotation and translation stored between the left and right cameras. A record that carries per-camera intrinsics but no pair extrinsics leaves that link empty, so the node refuses to open the depth stream and reports missing extrinsics between the two camera IDs. Always write intrinsics and extrinsics in one calibration run, then confirm both with the reader.
How many checkerboard captures does a stereo calibration need?
Plan on 15 to 25 good captures. Cover every quadrant of the frame at two or three distances, tilt the board up to about 45 degrees, and keep the square pitch exactly as printed. Watch the reprojection RMS as poses accumulate: when it stops falling and sits under 0.5 px, stop capturing. Blurred or overexposed frames add error without adding information.
Can a virtual machine corrupt the calibration EEPROM?
Rarely by itself, but it is a common contributor. A write that the virtual machine's USB stack interrupts mid-block leaves the memory half-written, and the decoder then fails exactly as in this guide. Run calibration, and above all any flashing operation, on a physical host with a short wired USB connection, and keep the host from sleeping during the procedure.
What does the 0.5 px RMS target actually limit?
It limits rectification quality, not depth noise. RMS is the reprojection error of the calibration in pixels; under 0.5 px the left and right images are aligned well enough that matching error dominates, which is why published stereo SDK guidance treats it as the acceptance ceiling. Above roughly 1 px, expect depth artifacts near object edges. Recheck the printed square pitch and focus before recapturing.

