-
-
Notifications
You must be signed in to change notification settings - Fork 5
Bed Level Map
The Bed Level Map tool reads the printer's bilinear compensation grid and renders it as a heatmap, so you can see at a glance which corners are high or low and confirm an auto-leveling cycle improved the bed flatness.
The AnkerMake M5 firmware stores a 7×7 (49-point) bilinear bed compensation grid. Each cell is a Z offset in millimeters, applied during printing to compensate for tilt and warp.
ankerctl queries the grid by sending the Marlin command M420 V, parses the BL-Grid-* lines from the response, and returns:
{
"grid": [[...], [...], ...],
"min": -0.18,
"max": 0.21,
"rows": 7,
"cols": 7
}The web UI renders this as a heatmap: blue = low (negative Z offset), red = high (positive Z offset). You can also keep "before" and "after" snapshots in localStorage to compare the impact of an autolevel cycle.
Setup → Tools → Bed Level Map
Buttons:
-
Read from printer — sends
M420 V, parses the response, renders the heatmap (~15 seconds) - Save snapshot — persists the current grid to localStorage as "before" (or "after" if "before" already exists)
- Compare — side-by-side heatmaps of before vs. after
-
Load last — load the most recent saved grid from disk (
bed_leveling/YYYYMMDD_HHMMSS.bed) without contacting the printer
- Heat up the bed and nozzle (the firmware needs warm temps for accurate probing —
M104 S60,M140 S60) - Run
G29once via the Home page Autolevel button or the touchscreen - Open Setup → Tools → Bed Level Map
- Click Read from printer — wait ~15 seconds for the response
- Inspect the heatmap; click Save snapshot to record this state
- Make a physical adjustment (knob turn, screw twist, mesh re-cal)
- Re-run
G29and Read from printer again - Compare to see whether the change improved or worsened flatness
Important Do not call
Read from printerduring an active print. TheM420 Vcommand sends ~320 bytes back to the printer and triggers a brief pause that can corrupt the live print. The button is disabled while a print is active, but the underlying API endpoint (GET /api/printer/bed-leveling) accepts the call regardless — be careful when scripting.
| Method | Path | Description |
|---|---|---|
GET |
/api/printer/bed-leveling |
Sends M420 V, parses the response, returns the grid (~15 s) |
GET |
/api/printer/bed-leveling/last |
Returns the most recently saved grid from disk |
POST |
/api/printer/autolevel |
Starts G29 (returns immediately; track progress via ct=1007) |
Live progress while G29 is running:
- MQTT
ct=1007valuefield = current probe index (50 total: 1 center + 7×7) - The web UI polls and shows
42/50progress next to the Autolevel button
Each successful M420 V response is saved to ANKERCTL_LOG_DIR/bed_leveling/YYYYMMDD_HHMMSS.bed. The format is plain JSON (the same shape the API returns), so you can diff snapshots manually or visualize them externally:
ls /logs/bed_leveling/
# 20260501_093215.bed 20260507_142003.bed 20260509_181122.bed
cat /logs/bed_leveling/20260509_181122.bed | jq '.grid[0]'GET /api/printer/bed-leveling/last returns the most recent .bed file contents.
| Color | Meaning |
|---|---|
| Deep blue | Bed is low here — printer adds Z to compensate |
| Cyan | Slightly low |
| White / pale | Near zero offset (ideal) |
| Yellow | Slightly high |
| Deep red | Bed is high here — printer reduces Z to compensate |
A perfectly flat bed shows a uniform pale-yellow / white heatmap with min and max values both close to 0. Real-world beds typically span ±0.1 mm to ±0.3 mm.
If you see a pronounced gradient (blue on one side, red on the other), the bed is tilted — adjust the leveling screws under that corner.
If you see a dome or bowl (low or high in the center, opposite at the corners), the bed is warped — bilinear compensation handles it as long as the deflection is below ~0.5 mm. Beyond that, mechanical correction (a glass/PEI replacement, leveling screws) is needed.
-
M420 Vreturns ~320 bytes of data, which exceeds a single MQTT packet — the response is collected viamqtt_gcode_dump()over a window - The default collect window is 3 seconds; very busy MQTT sessions may need 5 s (set in code; not currently exposed as a config flag)
- The full read takes ~15 seconds end-to-end because the firmware itself takes time to format the grid
- The grid is read-only through this tool — it cannot be edited or restored
- Anker has stripped the EEPROM dump command (
M503returns onlyok), so per-cell mesh values can be inspected but not exported in firmware-native format - The autolevel sequence (
G29) cannot be customized — it always probes the 49 grid points
- Confirm MQTT is connected (navbar dot is green)
- Try Read from printer again — Anker firmware occasionally drops a single response
- Bump the collect window in
cli/mqtt.py(mqtt_gcode_dump(..., collect_window=5.0)) if it consistently fails
- The printer has never been auto-leveled — run
G29first - The bed is genuinely flat (uncommon but possible)
- The compensation grid is calculated at print time from the bed sensor — reading it back should be deterministic
- Small variation (≤0.01 mm) is normal — the firmware quantizes Z offsets to 0.005 mm increments
ANKERCTL_LOG_DIR is unset (no on-disk persistence) or no successful read has happened yet. Set the env var and read at least once.