perf: non-blocking serial output of the datalog - #172
Merged
Merged
Conversation
At 9600 baud a datalog line takes ~130 ms to send and the UART buffer holds 64 characters, so printing it kept the main loop waiting: RF commands to remote loads were delayed, which made a second remote unit switch on for two mains cycles about every 10 s (seen in grid_sim with two remote units). The output is now cut into steps of at most 32 characters (serial_output.h), run from the main loop only when the transmit buffer has room: printing never waits. The IoT frame is drained from its existing buffer, the text and JSON lines are printed field by field. Debug messages first complete a pending output, so they never land inside a line or frame. The JSON line is written directly, without ArduinoJson (-1.7 KB of flash, up to -3.9 KB with all options), in the same format; temperatures no longer show float noise (-9.97 instead of -9.969999). ArduinoJson remains only as the reference of the new embedded test. The RF scenarios now require refresh frames at most 0.15 s apart (was 0.25 s). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FredM67
added a commit
that referenced
this pull request
Sep 30, 2026
…nits Brings in the non-blocking serial output (#172). The two-unit RF scenarios now require refresh frames at most 0.15 s apart for both nodes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
At 9600 baud a datalog line takes ~130 ms to send, and the UART's transmit buffer holds 64 characters. Printing it with
Serial.print()kept the main loop waiting for most of that time, so everything else the main loop does was delayed.The RF mock (#171) showed the effect with two remote units (#160):
Change
serial_output.h(new): a step printer. Each step writes at most 32 characters.SerialOutput::poll()is called on every pass of the main loop and only runs a step when the transmit buffer has room for it, so printing never waits.TeleInfo::writeNext()). No extra RAM is needed.DBUG/DBUGLNfirst complete any output in progress, so they never land inside a line or frame. In that rare case they block, like before.Output format
The format is unchanged for HumanReadable, IoT and JSON. This was checked in
grid_simagainstdev:One deliberate difference: in JSON, temperatures no longer show float noise. For example −9.97 is now written
-9.97instead of ArduinoJson's-9.969999, which affected about 2 % of values.Results
On #160's firmware with two remote units:
The RF scenarios on
devnow require frames at most 0.15 s apart (was 0.25 s). The old firmware fails this limit (0.164 s) and the new one passes (0.101 s).Size
About 230 bytes come from the debug hook at each of the 57
DBUGcall sites.Tests
test_serial_output(6 cases):poll()waits for room and never overfills the buffer;ArduinoJson is removed from the firmware's dependencies. It stays in the
uno_simenvironment only, as the reference for the format test. The READMEs andCLAUDE.mdare updated accordingly.🤖 Generated with Claude Code