Skip to content

bmp/QRPickle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QRPickle

A lightweight opinionated field friendly HAM Clock

QRPickle is a simple, lightweight dashboard designed for portable, QRP, and field-day amateur radio operations. Built to run on a standard ESP32 Cheap Yellow Display (CYD) with no external PSRAM, it consolidates real-time tracking data and tools into a clean, easy-to-use touchscreen interface.

This project is inspired by cburns42/HamClockCYD and SP3KON/ESP32-HAM-CLOCK, which resulted in a group build at BARC with VU3GWN forking it to(coffeedev/BARC-HAM-CLOCK).


⚠️ DEVELOPED & GENERATED BY A LARGE LANGUAGE MODEL (LLM) ⚠️

This codebase, firmware architecture, network parsing engine, memory management schema, and layout optimization layers were designed, audited, and developed using a Large Language Model (LLM).


Device Interface

Boot & Splash Main Dashboard App Menu
Splash Screen Dashboard Menu
HamAlert & DX Cluster POTA / SOTA Spots Solar Propagation
DX Cluster POTA Propagation
APRS Radar APRS Messaging APRS Beaconing
APRS Radar APRS Messages APRS Beacon
Weather Forecast On-Device Settings Smart Sleep Mode
Forecast Settings Powersave

Web Management Console

When on the same network, navigate to the device's IP address to access the integrated Web UI. The UI interacts with the C++ backend via asynchronous REST API endpoints.

Basic Network & Station Config Advanced Settings
Web UI Basic Advanced Settings
Staged Profile Management Live Hardware Telemetry
Profiles System Info
Over-The-Air (OTA) Firmware Flashing
OTA Updates

Core Features & Architecture

  • Stream-Buffered HamAlert & DX Cluster: Maintains a persistent, asynchronous TCP Telnet socket to background-listen for targeted DX spots. Uses a custom "Smart Parser" to read arbitrary-length streams without overflowing the FreeRTOS stack.
  • Heap-Protected POTA & SOTA Fetching: Standard HTTPS requests require ~40KB of contiguous RAM for RSA encryption (mbedTLS). QRPickle uses element-by-element JSON stream deserialization and task-staggering to prevent BIGNUM Out-Of-Memory kernel panics.
  • APRS-IS Integration: Connects to the global APRS-IS network. Features a tactical Radar view, live spotter tracking, custom macros, and direct bidirectional messaging.
  • Solar & Weather Telemetry: Pulls active K-Index, A-Index, and SFI from solar endpoints, and maps granular, bitmask-driven 24-hour weather forecasts via OpenWeatherMap API.
  • Adaptive Power & Wi-Fi Management: Enforces hardware-level radio power caps (esp_wifi_set_max_tx_power(52)) to prevent LDO voltage brownouts on the CYD board. Falls back to an integrated Setup AP (192.168.4.1) if routing fails.
  • Dynamic Staged Profiles: Save and hot-swap complete configuration layouts (Callsign, Grid, Network, Theme, Settings) via LittleFS for quick transitions between Home, Mobile, and Field ops.
  • Monochrome & Tactical Themes: Driven by LVGL 9, featuring high-contrast modes including Tactical Field Red, GitHub Slate Dark, Terminal Phosphor Green, and pure-binary E-Ink simulations.
  • OTA: Manual firmware update through the web dashboard and ability to pull from Github.
  • Adaptive brightness: Option to enable adaptive brightness or set it manually.
  • LED Status: A ver elementary notificaiton system is implemented through the LED lights on the backside of the ESP32-CYD. Details are documented in the LED Colours file in the docs folder.

Partition System & Memory Map

Because this firmware packs LVGL graphics, web assets, and an OTA system into a standard 4MB flash ESP32 without external PSRAM, we utilize a heavily customized partition table (partitions.csv):

  • nvs (Non-Volatile Storage): 20KB. Stores atomic active configuration variables (Wi-Fi credentials, active callsign, volume/brightness state).
  • app0 (Factory / OTA 1): ~1.5MB. The primary execution partition for the compiled C++ binary.
  • app1 (OTA 2): ~1.5MB. The secondary fallback partition used during wireless Over-The-Air updates.
  • spiffs / littlefs (Data Drive): ~800KB. Formatted as LittleFS. Stores the Web UI (index.html, app.js, style.css), stored JSON profiles, and system log trace dumps.

Libraries & Frameworks

  • LVGL (Light and Versatile Graphics Library) v9.x: Core C-based UI framework handling all screens, layouts, animations, and touch interactions.
  • TFT_eSPI: Highly optimized hardware-specific SPI driver for the ILI9341 display and XPT2046 resistive touch controller.
  • ArduinoJson v7: Zero-allocation stream parsing for OpenWeatherMap, POTA, and SOTA HTTPS payloads.
  • ESP-IDF Native APIs: Utilized directly alongside the Arduino Core wrapper for strict Wi-Fi TX power limits, FreeRTOS task handling, and lwIP socket management.

Production Pipeline & Flashing

The project is built entirely within PlatformIO (VS Code).

1. Pre-Flight Setup

Ensure your platformio.ini is configured for your specific CYD hardware pins. No external hardware modifications are required.

2. Uploading the Filesystem (Web UI & Profiles)

Before the firmware will function fully (especially the Web UI), you must write the data/ folder to the LittleFS partition.

pio run --target uploadfs

3. Compiling and Flashing the Core Firmware

Compile the C++ source and burn the binary to the ESP32 via USB.

pio run --target upload

4. Over-The-Air (OTA) Updates

Once deployed in the field, further updates can be pushed wirelessly. Compile your firmware in PlatformIO to generate firmware.bin or littlefs.bin, open the System Info tab on the Web UI, and push the payload directly over your local network.

Designed for operational reliability out in the field. Keep the signal clean, the power consumption managed, and the heap layout stable. 73!

Partition System & Memory Map

This project utilizes a heavily customized partition table (partitions.csv) to fit a complex FreeRTOS application, LVGL graphics, a Web UI, and an Over-The-Air (OTA) update system into a standard 4MB ESP32 flash chip.

Here is the exact memory map breakdown:

Partition Name Address Offset Hexadecimal Size Human-Readable Size Operational Assignment
nvs 0x009000 0x005000 20 KB Core hardware flags, automated network authorization pairs, calibration registers, and ambient settings profiles.
otadata 0x00E000 0x002000 8 KB Real-time execution targeting registers managed by the ESP32 bootloader tracking loops to determine current stable application selection flags (app0 vs app1).
app0 0x010000 0x1C0000 1.75 MB (1,792 KB) Primary system firmware image block storage. Expanded to resolve memory boundary overhead limitations from growing graphics frameworks.
app1 0x1D0000 0x1C0000 1.75 MB (1,792 KB) Mirror staging architecture slot dedicated to downloading incoming firmware packages directly from the GitHub API CDN pipelines without colliding with current live executions.
spiffs 0x390000 0x070000 448 KB Dedicated LittleFS structural loop containing web console visual layouts (index.html, style.css, app.js), local operator descriptions, and raw static binary user definitions.

Downloading Pre-Compiled Releases

You do not need to install VS Code or PlatformIO to use QRPickle. Pre-compiled binaries for the CYD are available in the repository releases.

Download Latest Release Binaries Here

The release folder contains the following files:

  • firmware.bin (The core C++ application)
  • littlefs.bin (The Web UI and filesystem data)
  • bootloader.bin & partitions.bin (Low-level ESP32 boot structures)

Easy Web Installation (No Software Required)

You can flash QRPickle directly from your Chrome or Edge web browser using the Espressif Web Flasher.

  1. Connect your CYD to your computer via USB.
  2. Open the Espressif Web Flasher Tool.
  3. Set your baud rate to 921600 and click Connect.
  4. Add the release files to the flash tool using their exact partition offsets:
    • 0x1000bootloader.bin
    • 0x8000partitions.bin
    • 0x10000firmware.bin
    • 0x350000littlefs.bin
  5. Click Program and wait for the process to finish. The device will automatically reboot into QRPickle!
  6. And the device should boot up, and create a WiFi access-point called QRPickle-Setup which does not require authentication.