emon
Espilon's universal serial monitor for embedded devices: watch multiple ports at once, detect crashes by pattern, bridge a PTY without resetting the target, and stream JSON for CI.
emon is Espilon's own Universal Serial Monitor for Embedded Devices (github.com/EspilonOrg/emon, Apache-2.0, written in C). It is the serial monitor Espilon recommends: where a plain terminal only echoes bytes, emon watches many ports at once, detects crashes and events by pattern, holds a port open without rebooting the target, and streams structured output for automation.
What it is
emon reads the serial output of embedded devices and makes it usable rather than just visible. In one session it watches multiple ports at once, colour-coding each so two boards never blur together. It detects crashes and events by POSIX-regex patterns, each tagged with a severity, so a panic or a reset stands out instead of scrolling past. Its PTY-bridge mode holds the port open without toggling the hardware reset lines, so attaching a monitor does not reboot the device, the single most common annoyance of a naive terminal on boards that reset on DTR/RTS. It can stream JSON/NDJSON, return CI exit codes on a matched pattern or a timeout, run an event hook (a script) on a match, auto-load pattern sets by USB VID/PID, and run in the background as a daemon (--bg / status / stop). It vendors libserialport, so it has no system dependencies.
Why it matters
A serial console is where an embedded target tells you what it is doing, and a plain terminal wastes most of that. Three emon features change the workflow. First, the PTY bridge with no reset: on an ESP32 or Arduino that resets when the serial lines assert, emon lets you attach mid-run and keep the device alive, so you can observe a crash instead of causing a reboot that hides it. Second, pattern-based crash detection: instead of watching a firehose by eye, you give emon a .pat file and it flags the guru meditation, the backtrace, or your own event string with a severity. Third, CI exit codes and JSON: emon turns the console into a test oracle, a build can fail if a crash pattern appears or if the expected banner never arrives before a timeout. Together these make emon the tool for observing devices, complementing (not replacing) an interactive terminal.
Pattern detection in action: emon tags a matched event (ping, oom, crash) with its severity as the log scrolls.
How to use it
Install on Debian/Ubuntu after adding the Espilon apt repo:
curl -fsSL https://apt.espilon.net/espilon.gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/espilon.gpg
echo "deb https://apt.espilon.net stable main" | sudo tee /etc/apt/sources.list.d/espilon.list
sudo apt update && sudo apt install emon
Or with Homebrew (brew tap EspilonOrg/tap && brew install emon), or from the AUR (yay -S emon).
emon /dev/ttyUSB0 # monitor one port
emon --verbose -p patterns/esp32.pat /dev/ttyUSB0 # load a pattern set
emon --name /dev/ttyUSB0=ESP32 --name /dev/ttyACM0=Arduino \
/dev/ttyUSB0 /dev/ttyACM0 # watch two named ports
emon --quiet --json-events -p patterns/arduino.pat /dev/ttyACM0 | jq . # stream JSON events
emon --bg --logdir ./logs -p patterns/esp32.pat /dev/ttyUSB0 # run as a daemon
emon status # check the daemon
emon stop # stop it
Give ports human names with --name, load a pattern file with -p, and add --json-events to pipe machine-readable events into jq or a CI step. In daemon mode emon logs to --logdir and you manage it with emon status / emon stop.
Watch two named ports in one session, each colour-coded so the ESP32 and the Arduino never blur together.
The same events as an NDJSON stream, piped into jq for a CI step or a dashboard.
Daemon mode: start emon in the background, check it with emon status, and stop it cleanly.
Pitfalls
- emon observes; it is not an interactive terminal. To type into a bootloader prompt or a shell you still want
picocom/screen(or emon's interactive path); emon shines when the job is to watch, log, and detect. - Patterns are POSIX regex, not PCRE. Keep your
.patexpressions to POSIX syntax or a match silently fails. - The PTY bridge avoids asserting reset, but a board still resets if something else (a power cycle, another tool opening the port with DTR) drives those lines. Only emon's own attach is reset-safe.
- Only one process can own a serial port. If emon cannot open the TTY, a
screen,picocom, or a stray emon daemon is probably still holding it (emon status).
What it pairs with
A usb-uart adapter is the hardware that puts the device's console on a /dev/tty*. Use sigrok/PulseView first when you do not yet know the baud rate or which pin is TX. For interactive typing, pair emon with picocom/screen, they type, emon watches. On an ESP32 workflow, emon tails the boot log and crash output while esptool flashes.