Skip to content

Drop the radar frame buffer to RGB332 - #100

Merged
MatixYo merged 1 commit into
MatixYo:mainfrom
pvanbaren:feature/rgb332-frame-buffer
Sep 30, 2026
Merged

MatixYo merged 1 commit into
MatixYo:mainfrom
pvanbaren:feature/rgb332-frame-buffer

Conversation

@pvanbaren

Copy link
Copy Markdown
Contributor

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.

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>
@MatixYo
MatixYo merged commit 139a3ac into MatixYo:main Sep 30, 2026
2 checks passed
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants