The XIAO stopped answering on 10-07 ("No response from meshcore
node" for many starts in a row). MeshCore's serial parser reads '<'
and a two-byte length, then waits for that many bytes with no time
limit, so one lost or damaged byte can make it swallow up to 65,535
bytes, and MeshTerm sends only 16 per start. Reproduced on the
PicoCalc: a half frame blocked two APP_STARTs until 600 filler bytes
arrived. meshcore-frame-timeout.patch drops a frame after 200 ms of
silence on the line (bytes queued while the loop was busy still
count), and build-firmware.sh applies it after meshcore-uart1.patch.
Upstream dev and main still have the old parser.
Flashing the XIAO with the new firmware, following the guide as
written, found these problems, now corrected:
- Step 11: `pip install platformio` failed (no pip outside a venv on
this PC), and it fails on externally managed Pythons or lands in an
active venv. The guide now uses the official installer only, and
build-firmware.sh and flash.py find pio in ~/.platformio/penv, so
nobody edits the PATH. uf2conv runs on PlatformIO's Python, because
a bare `python` is missing on many Linux systems.
- Step 12: the script's last line said to double-tap reset first;
flash.py touches the XIAO itself, and a wired XIAO's reset button is
inside the case.
- Step 13: this XIAO's bootloader has only a serial port, and flash.py
printed a pio command for the user to run "from your MeshCore
checkout", with pio not on the PATH. flash.py now does the serial
DFU upload itself (54 s here). Without pyserial, it runs itself
again with PlatformIO's Python instead of skipping the touch.
- A wired XIAO's USB power goes backward into the Lyra through the
3V3 wire (JP confirmed it on the bench). Step 13 now applies only
before wiring, and a new Day-to-day procedure updates the firmware
of a wired radio: poweroff, switch off, open, batteries out, flash.
After the flash, the radio kept its identity, MeshTerm's info command
connected, and an APP_START after a half frame and 0.5 s of silence
got its reply at once.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
scripts/
These are tools for the repository. None of them is in the wheel.
| Script | What it is for |
|---|---|
basemap-doctor.py |
Finds why a user's map has no basemap: certificates, DNS, proxy, or colour depth |
cardputer-zero/ |
build-deb.sh builds the Debian package for M5Stack's app store. Run it on the Cardputer Zero or on another arm64 Debian 13 system. store/ holds the listing for the store (app-builder.json, which czdev publish reads), its icon, and its screenshots. screenshot.py saves the display of a Cardputer as a 320×170 PNG over SSH, as the store wants a screenshot. store-publish.py sends a package to the store with M5Stack's czdev, with two corrections. The release workflow runs it after each release. launcher-entry.sh puts a source checkout in the Cardputer Zero's app launcher. remove takes it out. meshterm.png is the package's icon: the website's logo, at the launcher's 100×100 size. meshterm-dev.png is its negative, for the checkout's entry, so that the two entries look different. type-text.py types a pasted string (an API key, a Wi-Fi password) on the Cardputer's keyboard from another computer, over SSH |
picocalc-lyra/ |
Setup of the Calculinux device: console font, palette, Wi-Fi. xiao-radio/ is the kit for the XIAO radio (firmware build, flashing, UART setup) |
uconsole/ |
The uConsole's always-on SPI bridge service. MeshTerm can also control that radio directly, with no script (refer to docs/devices/uconsole.md) |
basemap-doctor.py
The map is the only part of MeshTerm that uses the network. MeshTerm logs each fetch
failure on this path at DEBUG, and log_level is WARNING by default. Thus a user whose
tiles do not arrive sees a blank ground and no explanation. This script prints the
explanation and the correction.
To use it, tell the user to run this on the machine that has the problem:
curl -fsSL https://raw.githubusercontent.com/jpmartineau/MeshTerm/main/scripts/basemap-doctor.py -o /tmp/basemap-doctor.py
python3 /tmp/basemap-doctor.py
Any python3 is correct. If that python3 does not have MeshTerm, the script reads the
interpreter from the installed meshterm command's shebang, and it runs again with
that interpreter. Thus the answer always comes from the app's own Python. A Mac
often has three Pythons, and only one of them has the trust store that is important. Save
the script to a file, as in the example. Do not pipe it into python3 -. When there is no
file on the disk, the script cannot run again with the other interpreter.
Ask the user to paste all the output back to you. The output names the interpreter, the
certificate store, the tile source, the number of cached tiles, and COLORTERM. Then it
gives one verdict:
- curl reached it, Python did not. The Python's certificate store is empty. A
python.org install on macOS has an empty store until the user runs
Install Certificates.command. - neither reached it. The problem is in the network path: a firewall, a proxy, a DNS filter, or an outage. There is nothing to correct in MeshTerm.
- both reached it. The tiles are correct. The problem is colour. When
COLORTERMis not set, the terminal uses 256 colours, and the greens and blues of the basemap are too similar. Terminal.app cannot do 24-bit colour.
The exit status is 0 when the tiles arrive and 1 when they do not. Thus a script can use it.