Repository navigation
Drop the radar frame buffer to RGB332 - #100
Merged
Merged
Conversation
The 240x240 off-screen frame is the largest single allocation this firmware makes. At 16bpp it takes 115,204 contiguous bytes of internal RAM; at one byte per pixel it takes 57,602, freeing 57,602 bytes. Colour constants stay uint16_t. LovyanGFX type-dispatches those through convert_rgb565() and down-converts to the sprite's depth, so no call site changes; the cost is colour fidelity, 3-3-2 rather than 5-6-5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
vfranchi
added a commit
to vfranchi/ESP32-Plane-Radar
that referenced
this pull request
Sep 30, 2026
The radar publishes itself to Home Assistant over MQTT with auto-discovery: ten entities (range select, miles/runways switches, latitude/longitude numbers, and sensors for aircraft count, nearest aircraft, Wi-Fi RSSI, free heap and device info), so there is no YAML on the HA side. Commands arrive on <base>/cmd/# and are applied to NVS and re-published as state, so HA always shows the value the radar actually accepted. Configuration is eight fields in the existing config portal, stored in NVS. Every field starts empty on purpose: the firmware ships no broker address, user or password, and an empty host keeps MQTT completely inert. Details that were measured, not guessed, on an ESP32-C3 Super Mini: - The broker session is kept (cleanSession=false, commands subscribed at QoS 1). With PubSubClient's default clean session the broker discards the subscription and any command published while the connection is down, which showed up as switch taps in Home Assistant being silently ignored. - Discovery publishes one entity at a time with a 250 ms gap, and the number entities declare step=0.001: Home Assistant drops a discovery message whose step is below that, without logging anything on the broker. - Memory. There is no room for a second TLS stack on this chip, so MQTT runs plain TCP on 1883 only. The ADS-B poll now keeps its TLS session alive between polls (static WiFiClientSecure/HTTPClient + setReuse(true)): the handshake costs ~1 s of CPU here, and paying it every poll is what made mbedtls_ssl_setup() -- two 16 KB record buffers, no CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH on the C3 -- fail once the MQTT client was connected. The MQTT client also stays connected across the fetch (fetchInProgress() keeps the two off the same socket), and the fetch task computes the nearest aircraft while it holds the parsed list instead of the MQTT task copying 3.3 KB of aircraft on every publish. Measured over 120 s with MQTT enabled: 0 TLS allocation failures, 22 ADS-B polls, one MQTT connect, TLS session reused on 21 of 22 polls. The same window before the connection reuse: 799 failures, 5 polls. This relies on the RGB332 frame buffer (MatixYo#100) for headroom: at 16bpp the frame sprite left no contiguous block for those 16 KB buffers. Build flags: -DMQTT_MAX_PACKET_SIZE=768, because PubSubClient's default 256 B truncates discovery payloads silently (the ceiling covers topic + payload + header together), and -DMQTT_KEEPALIVE=60.
vfranchi
added a commit
to vfranchi/ESP32-Plane-Radar
that referenced
this pull request
Sep 30, 2026
The radar publishes itself to Home Assistant over MQTT with auto-discovery: ten entities (range select, miles/runways switches, latitude/longitude numbers, and sensors for aircraft count, nearest aircraft, Wi-Fi RSSI, free heap and device info), so there is no YAML on the HA side. Commands arrive on <base>/cmd/# and are applied to NVS and re-published as state, so HA always shows the value the radar actually accepted. Configuration is eight fields in the existing config portal, stored in NVS. Every field starts empty on purpose: the firmware ships no broker address, user or password, and an empty host keeps MQTT completely inert. Details that were measured, not guessed, on an ESP32-C3 Super Mini: - The broker session is kept (cleanSession=false, commands subscribed at QoS 1). With PubSubClient's default clean session the broker discards the subscription and any command published while the connection is down, which showed up as switch taps in Home Assistant being silently ignored. - Discovery publishes one entity at a time with a 250 ms gap, and the number entities declare step=0.001: Home Assistant drops a discovery message whose step is below that, without logging anything on the broker. - Memory. There is no room for a second TLS stack on this chip, so MQTT runs plain TCP on 1883 only. The ADS-B poll now keeps its TLS session alive between polls (static WiFiClientSecure/HTTPClient + setReuse(true)): the handshake costs ~1 s of CPU here, and paying it every poll is what made mbedtls_ssl_setup() -- two 16 KB record buffers, no CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH on the C3 -- fail once the MQTT client was connected. The MQTT client also stays connected across the fetch (fetchInProgress() keeps the two off the same socket), and the fetch task computes the nearest aircraft while it holds the parsed list instead of the MQTT task copying 3.3 KB of aircraft on every publish. Measured over 120 s with MQTT enabled: 0 TLS allocation failures, 22 ADS-B polls, one MQTT connect, TLS session reused on 21 of 22 polls. The same window before the connection reuse: 799 failures, 5 polls. This relies on the RGB332 frame buffer (MatixYo#100) for headroom: at 16bpp the frame sprite left no contiguous block for those 16 KB buffers. Build flags: -DMQTT_MAX_PACKET_SIZE=768, because PubSubClient's default 256 B truncates discovery payloads silently (the ceiling covers topic + payload + header together), and -DMQTT_KEEPALIVE=60.
lmoiseichuk
added a commit
to lmoiseichuk/ESP32-Plane-Radar
that referenced
this pull request
Oct 7, 2026
Brings in upstream's ADS-B pipeline, dead reckoning at 4 Hz, the TLS fix, the portal re-render and the RGB332 frame buffer. One conflict, in ensureFrameSprite(): this branch tried 16bpp first and fell back to 8bpp; upstream (MatixYo#100) now always uses RGB332 to free the frame's 57 KB at 240x240. Resolved in upstream's favour -- one byte a pixel on every panel, which at 360x360 is 129,600 B instead of 259,200 -- keeping this branch's fallback to drawing straight to the panel when even that does not fit, and its note on why no palette depth is tried. Both supermini and supermini_gc9b72 build. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DL3fMjXoiVk9VGMHmQkfyW
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.
The 240x240 off-screen frame is the largest single allocation this firmware makes. At 16bpp it takes 115,204 contiguous bytes of internal RAM; at one byte per pixel it takes 57,602, freeing 57,602 bytes for use elsewhere in the system. This reduces the potential for the SSL handshake allocations to fail.
Colour constants stay uint16_t. LovyanGFX type-dispatches those through convert_rgb565() and down-converts to the sprite's depth, so no call site changes; the cost is colour fidelity, 3-3-2 rather than 5-6-5.