A WiFi-enabled LED matrix message board system for ESP8266 and ESP32 microcontrollers that displays scrolling messages from remote systems or users via HTTP, MQTT, or a built-in web interface. Designed for home automation integration with Home Assistant, NodeRed, Linux/Windows systems, and direct browser access.
- Non-Blocking Operations (ESP32): FreeRTOS background tasks prevent LED scrolling from stuttering during network operations. HTTP page loads, crypto price fetches, weather updates, and buzzer sounds all run on Core 0 while the display loop runs uninterrupted on Core 1.
- Recurrent Alarm Display Indicator: New configurable display mode shows a brief alert indicator (default
"* * *") when the alarm triggers, with option to customize the message. - Crypto Price Ticker (ESP32): Live cryptocurrency prices from CoinPaprika (free, no API key) scrolling on the display between clock updates. Up to 10 coins, 6 currencies, configurable fetch and display intervals.
- Complete Refactor: Migrated to PlatformIO for better dependency management and improved development workflow.
- Modernized UI: Redesigned responsive web interface with AJAX updates and in-page modal confirmations.
- Configuration Management: Export/Import full JSON config backups and set persistent custom message defaults via the web interface.
- Enhanced Integrations: Zero-config Home Assistant Auto-Discovery and secure MQTT (TLS/SSL) for ESP32.
- Expanded Features: Advanced Clock (Any Timezone) & Timer modes, Sleep Mode with weekend schedules, Global Buzzer toggles, and a new 'Chirp' library for musical alerts.
This project transforms an ESP8266 or ESP32 board paired with MAX7219 LED matrix display modules into a versatile, network-connected message board. It provides multiple methods for sending messages: a web-based GUI, HTTP REST API (URL-encoded or JSON), and MQTT messaging with flexible topic subscriptions. The system features persistent configuration storage, OTA firmware updates, UTF-8 character support, and customizable display parameters including scroll speed, brightness, repeat count, and audible alerts.
Originally developed for Aduino IDE at esp8266_max7219_rda_msg_board, this project has been completely refactored to use PlatformIO (with vscode) for better dependency management, multi-environment support, and improved development workflow. The UI has been updated to a more modern look and feel, and the codebase has been significantly cleaned up and optimized.
Note
For a full visual tour of all the settings and configuration pages available in the web interface, please see the UI Overview Guide.
- Web Interface - Full-featured GUI for message control and configuration
- Responsive design with AJAX data updates (XML responses)
- HTTP Basic Authentication and in-page confirmation modals
- HTTP REST API - Send messages via GET (URL-encoded) or POST (JSON) requests
- MQTT Integration - Flexible topic subscriptions with wildcard support, anonymous or authenticated modes
- Secure MQTT (TLS/SSL) - Full TLS encryption support with fingerprint or CA certificate validation (ESP32 only)
- Home Assistant Discovery - Automatic device detection and configuration (Zero-config setup)
- mDNS Support - Access via hostname (e.g.,
RDA-MSG-ABCDEF.local) instead of IP address
- UTF-8 Extended ASCII - Display international characters and symbols (see character list below)
- Configurable Parameters - Control repeat count, scroll speed, brightness, and buzzer alerts
- Persistent Defaults - Save custom default values for message parameters via web interface
- Global Buzzer Control - Master toggle to enable or disable all audible notifications globally
- Advanced Clock Display - Highly configurable LED clock with transition effects and date support
- POSIX Timezone Support - Accurate timekeeping using standard POSIX timezone strings
- Sleep Mode - Scheduled display power-saving/dark (blackout) with specific weekday and weekend time windows
- Chirp Library - Pre-defined musical alerts (fansfare, alarms, chimes, For Elise, Mario Bros) for timer events
- Real-time Updates - Messages display immediately across all input methods
- Timer & Stopwatch - Count down or count up with buzzer alerts and auto-repeat
- Crypto Price Ticker (ESP32 only) - Live prices for up to 10 coins via CoinPaprika (free, no API key). Supports USD, EUR, GBP, JPY, BTC, ETH. Independent fetch and display intervals.
- WiFi Configuration Portal - Easy setup via captive portal on first boot or after reset
- LittleFS Storage - Persistent configuration for credentials, MQTT settings, and defaults
- OTA Firmware Updates - Update firmware directly through web interface
- Config Export/Import - Backup and restore complete device configuration as JSON
- Factory Reset - Reset all settings via web interface or optional physical button
- Custom Hostname - Change device hostname from default
RDA-MSG-XXXXXX
- Microcontroller:
- ESP8266: NodeMCU 1.0, WeMos D1 Mini, or compatible
- ESP32: ESP32 DevKit v1, or compatible
- LED Display: MAX7219 LED Matrix modules (Supports 4, 8, 12+ modules)
- Note: Pre-built binaries are provided for 4 and 8 module configurations for both platforms.
- Buzzer: Optional piezo buzzer for audible notifications (example here QWORK® 8 Pcs Electronic buzzer , 3-24V piezoelectric buzzer 87dB , for physical circuits continuous sound electronic buzzer alarm , cable length 100mm)
- Power Supply: 5V DC (USB or external). Multiple modules require a high-current power source.
Default pin assignments are platform-specific (configurable in include/config.h or via build flags):
| Function | NodeMCU | D1 Mini | GPIO | Description |
|---|---|---|---|---|
| CLK | D5 | D5 | 14 | SPI Clock |
| DIN | D7 | D7 | 13 | SPI MOSI |
| CS | D8 | D4 | 15 / 2 | Chip Select |
| Buzzer | D1 | D1 | 5 | Optional Alert |
| Function | Pin | Description |
|---|---|---|
| CLK | GPIO 18 | VSPI CLK |
| DIN | GPIO 23 | VSPI MOSI |
| CS | GPIO 5 | VSPI CS |
| Buzzer | GPIO 4 | Optional Alert |
Wiring Diagrams:
Note
For ESP32, connect MAX7219 DIN to GPIO 23, CLK to GPIO 18, and CS to GPIO 5. The project uses the ESP32's standard VSPI hardware interface for optimal performance.
The number of LED modules is configured via PlatformIO build environments in platformio.ini:
For GitHub releases (automated builds):
- ESP8266:
esp8266_4m- 4 modulesesp8266_8m- 8 modules
- ESP32:
esp32_4m- 4 modulesesp32_8m- 8 modules
To build for a different module count locally, add -DMAX_DEVICES=8 to your environment's build_flags in platformio.ini:
[env:d1_mini]
board = d1_mini
build_flags =
${env.build_flags}
-DMAX_DEVICES=8 # Change to 4, 8, 12, etc.Certain features of the message board can be configured at compile time to save memory and flash space. This is especially useful for ESP8266 boards, which have limited heap constraints.
In platformio.ini, you can uncomment any of the following definitions under your target environment's build_flags to disable specific functionality:
; --- Modular Features ---
; -DDISABLE_SLEEP_MODE_FEATURE
; -DDISABLE_TIMER_FEATURE
-DDISABLE_WEATHER_FEATURE ; default ON for ESP8266 (heap constraint)
-DDISABLE_CRYPTO_FEATURE ; default ON for ESP8266 (heap constraint)
; -DDISABLE_ALARM_FEATURENote
ESP8266 Users — Weather & Crypto: Both the Weather and Crypto Price Ticker features are disabled by default on all ESP8266 builds (-DDISABLE_WEATHER_FEATURE, -DDISABLE_CRYPTO_FEATURE). Enabling either will make WiFi setup (Captive Portal) unreliable due to heap pressure — you will likely be unable to scan for or enter a WiFi SSID. You can flash a firmware with these features enabled after WiFi is already configured and they will work fine, but if you ever need to factory-reset and reconfigure WiFi you may need to flash a version without them first.
The firmware version is centrally managed in platformio.ini using Semantic Versioning:
[common]
project_name = rda_msg_board
version = v1.4.0 # Update here for new releasesAll build environments automatically use this version. To create a new release, update the version here and use the release script (see Release Management section).
Option 1: Building from Source
- Install Visual Studio Code
- Install the PlatformIO IDE extension
Option 2: Using Precompiled Firmware
No prerequisites required! See Firmware Flashing Guide for tools to upload precompiled .bin files directly to your ESP board.
If you want to use precompiled firmware binaries from GitHub Releases without building from source, follow our comprehensive Firmware Flashing Guide. It covers:
- Windows: ESPHome Flasher, NodeMCU PyFlasher, ESP Flash Download Tool, Thonny
- Linux: esptool.py, NodeMCU PyFlasher, ESP Tool (web-based)
- Cross-platform: Thonny IDE, BrewFlasher
Quick summary:
- Download firmware
.binfile matching your board and module count - Choose a flashing tool (esptool.py for command-line, ESPHome Flasher for GUI on Windows)
- Connect ESP board via USB
- Upload firmware to the board
- Open Project - Open this folder in VS Code
- Install Dependencies - PlatformIO will automatically install required libraries on first build
- Select Environment - Choose your target board:
- ESP8266:
nodemcu_4m/nodemcu_8m- NodeMCU CI/Release builds (4 and 8 module variants)d1_mini_4m/d1_mini_8m- D1 Mini CI/Release builds (4 and 8 module variants)
- ESP32:
esp32_4m/esp32_8m- ESP32 CI/Release builds (4 and 8 module variants)
- ESP8266:
- Build - Click the checkmark icon in PlatformIO toolbar, or use the
/test_buildworkflow - Upload - Click the arrow icon in PlatformIO toolbar
Quick Build Command:
# Using the /test_build workflow (recommended)
# Or manually:
platformio run --target upload --environment d1_mini
### Release Management
Use the provided release scripts to automate version tagging and GitHub releases:
**Bash (Linux/Mac/Git Bash):**
```bash
./release.sh "Your release notes"
./release.sh --force # Recreate existing tag
The script will:
- Extract version from
platformio.ini - Create a git tag (e.g.,
v1.0.1) - Push to GitHub
- Trigger automated builds for both ESP8266 and ESP32 (4m and 8m configurations)
- Create a GitHub Release with downloadable firmware binaries for both platforms
├── .github/workflows/ # Automated build & release CI
├── docs/ # Detailed documentation
│ ├── env_board_variants/ # Hardware wiring diagrams (SVG/PNG)
│ ├── ARCHITECTURE.md # System design & logic flow
│ ├── FIRMWARE_FLASHING_GUIDE.md # Flashing precompiled binaries
│ ├── HARDWARE_REF.md # Pinouts & wiring guides
│ ├── HOME_ASSISTANT.md # Discovery & entity mapping
│ ├── HTTP_API.md # REST endpoint documentation
│ └── MQTT_EXAMPLES.md # Topic patterns & payloads
├── include/ # Header files (*.h)
│ ├── config.h # Struct definitions & compile-time constants
│ ├── globals.h # Shared global variable declarations
│ ├── MatrixLight8_font.h # Matrix Light 8px clock bitmap font (PROGMEM)
│ ├── MatrixLight8X_font.h # Matrix Light 8px X clock bitmap font (PROGMEM)
│ ├── MatrixLight6_font.h # Matrix Light 6px clock bitmap font, centred (PROGMEM)
│ ├── MatrixLight6X_font.h # Matrix Light 6px X clock bitmap font, centred (PROGMEM)
│ ├── MatrixChunky6_font.h # Matrix Chunky 6px clock bitmap font, centred (PROGMEM)
│ ├── MatrixChunky6X_font.h # Matrix Chunky 6px X clock bitmap font, centred (PROGMEM)
│ ├── buzzer_task.h # FreeRTOS buzzer task interface (ESP32)
│ ├── http_task.h # FreeRTOS HTTP task interface (ESP32)
│ └── *.h # Module headers (mqtt, web, timer, weather…)
├── src/ # Source files (*.cpp)
│ ├── main.cpp # Setup/Loop entry point
│ ├── config_manager.cpp # LittleFS JSON persistence
│ ├── globals.cpp # Global variable definitions
│ ├── web_server.cpp # HTTP routing & auth
│ ├── web_pages_main.cpp # Embedded main dashboard HTML/CSS/JS
│ ├── web_pages_config.cpp # Embedded config modal HTML/CSS/JS
│ ├── web_pages_status.cpp # Embedded system/status page HTML/CSS/JS
│ ├── web_data.cpp # XML/JSON response builders for AJAX
│ ├── mqtt.cpp # PubSubClient connection & dispatch
│ ├── mqtt_discovery_core.cpp # HA Discovery — device registry & base topics
│ ├── mqtt_discovery_sensors.cpp # HA Discovery — message, light & switch entities
│ ├── mqtt_discovery_clock.cpp # HA Discovery — clock face & format entities
│ ├── mqtt_discovery_timer.cpp # HA Discovery — timer/stopwatch entities
│ ├── mqtt_discovery_sleep.cpp # HA Discovery — sleep mode entities
│ ├── mqtt_discovery_weather.cpp # HA Discovery — weather entities
│ ├── functions.cpp # Core display control, clock & UTF-8 logic
│ ├── utf8_utils.cpp # UTF-8 → extended ASCII conversion
│ ├── buzzer_utils.cpp # Chirp & alert audio logic
│ ├── buzzer_task.cpp # FreeRTOS buzzer task (ESP32 non-blocking)
│ ├── http_task.cpp # FreeRTOS HTTP server task (ESP32 non-blocking)
│ ├── chirp_library.cpp # Named chirp sound definitions
│ ├── timer.cpp # Countdown timer / stopwatch logic
│ ├── weather.cpp # OpenWeatherMap API integration (background task on ESP32)
│ └── crypto.cpp # CoinPaprika API integration (background task on ESP32)
├── tools/ # Development utilities
│ ├── bdf_to_parola.py # BDF → MD_MAX72XX PROGMEM font converter
│ └── fonts/ # Source BDF font files (github.com/trip5/Matrix-Fonts, CC-BY)
│ ├── MatrixLight8.bdf # 8px Light source
│ ├── MatrixLight8X.bdf # 8px Light X (extended spacing) source
│ ├── MatrixLight6.bdf # 6px Light source
│ ├── MatrixLight6X.bdf # 6px Light X (extended spacing) source
│ ├── MatrixChunky6.bdf # 6px Chunky source
│ └── MatrixChunky6X.bdf # 6px Chunky X (extended spacing) source
├── node_red_flow.json # NodeRed integration example
├── platformio.ini # PIO environments & dependencies
├── release.sh / release.ps1 # Cross-platform release scripts
└── images/ # GUI & case screenshots
All dependencies are automatically managed by PlatformIO and are compatible with both ESP8266 and ESP32:
- MD_MAX72XX (^3.5.1) - LED matrix control
- MD_Parola (^3.7.5) - Scrolling text effects
- WiFiManager (^2.0.17) - WiFi configuration portal (multi-platform)
- EasyButton (^2.0.3) - Button handling (ESP8266 only, ignored on ESP32)
- ArduinoJson (^7.4.2) - JSON parsing and serialization
- PubSubClient (^2.8) - MQTT client
Note
The EasyButton library is explicitly excluded from ESP32 builds via lib_ignore in platformio.ini as the persistent flash button feature is optional and defaults to ESP8266-only. This does not affect core message functionality.
On first boot or after a factory reset, the device creates a WiFi access point for configuration:
-
Connect to AP:
- SSID:
RDA-MSG-XXXXXX(where XXXXXX is a unique device identifier)- ESP8266: Last 6 hex digits of chip ID
- ESP32: Derived from MAC address
- Password:
wifi-setup
- SSID:
-
Configure WiFi:
- Most modern devices will automatically open the captive portal
- If not, manually browse to:
http://192.168.4.1 - Click "Configure WiFi"
- Enter your WiFi network SSID and password
- Click "Save"
-
Connect to Network:
- The device will reboot and connect to your WiFi network
- Look for the assigned IP address displayed on the LED matrix after boot
- Optionally, assign a static IP via your router's DHCP settings for consistent access
Tip
You can also access the device using its mDNS hostname: http://RDA-MSG-XXXXXX.local (replace XXXXXX with your device ID)
Web Interface Login:
- Username:
admin - Password:
msgboard
Important
Change the default credentials immediately after first setup via the Device Config page in the web interface.
Access the web interface at the device's IP address or mDNS hostname (e.g., http://192.168.1.100 or http://RDA-MSG-ABCDEF.local).
Homepage - Send messages and control display parameters:
- Message text input
- Repeat count (how many times to scroll)
- Buzzer chirps (audible notifications)
- Scroll delay (speed)
- Brightness (0-15)
- Set and save custom defaults
General Settings - Global device parameters:
- Global Buzzer Toggle (Master switch for all beeps)
- Global Brightness Override
Device Config - Change credentials and hostname:
- Web interface username/password
- Custom device hostname
- Config export/import for backup/restore
MQTT Config - Configure MQTT integration:
- Enable/disable MQTT
- MQTT server address and port
- Authentication (anonymous or user/password)
- MQTT TLS (ESP32 only)
- Topic prefix configuration
- Connection/disconnection alerts
- Incoming message display toggle
Clock & Display - Configure clock functionality:
- NTP server and timezone (full POSIX TZ string support)
- Clock brightness control
- Transition animations (speed, effect, randomise)
- Time Display Format and Clock Face selection (see below)
- 12-hour AM/PM or 24-hour mode
- Date alternation — rotates through time → day of week → date on a configurable interval
Seven clock faces are available across two series, all sourced from the trip5/Matrix-Fonts project (see Acknowledgments):
| Feature | Default | Light 8px | Light 8px X | Light 6px | Light 6px X | Chunky 6px | Chunky 6px X |
|---|---|---|---|---|---|---|---|
Time only HH:MM |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Seconds HH:MM.SS |
8-module only | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 12-hour AM/PM | 8-module only | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Date & custom formats | 8-module only | 8-module only | 8-module only | 8-module only | 8-module only | 8-module only | 8-module only |
| Date alternation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Day-of-week step | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Default — the built-in MD_Parola proportional font. Widest characters; on 4-module builds only HH:MM fits.
8px series — full 8-row height fonts, best suited for 8-module builds where wider displays give more room for date and seconds:
- Matrix Light 8px (
MATRIX_LIGHT) — narrow 3-pixel-wide digits, compact spacing. FitsHH:MM.SS(27 px) within a 4-module (32 px) display. - Matrix Light 8px X (
MATRIX_LIGHT_8X) — same design with slightly extended inter-character spacing for improved readability.
6px series — 6-row height fonts vertically centred in the 8-row display, ideal for 4-module clocks. Produce a lighter, smaller appearance while retaining full seconds, AM/PM, and alternation support:
- Matrix Light 6px (
MATRIX_LIGHT_6) — the Light 8px design scaled to 6 rows. - Matrix Light 6px X (
MATRIX_LIGHT_6X) — Light 6px with extended inter-character spacing. - Matrix Chunky 6px (
MATRIX_CHUNKY_6) — bolder, blockier digit style at 6 rows. Open-top digit design gives a distinctive retro look. - Matrix Chunky 6px X (
MATRIX_CHUNKY_6X) — Chunky 6px with extended inter-character spacing.
4-module constraint:
TIME_SECONDSandAM/PMcannot be combined on 4-module builds — "12:34.56 PM" would exceed the 32-pixel display width. The interface prevents this combination automatically.
Timer Settings - Configure countdown timer or stopwatch mode:
- Duration and Alert sound configuration
Weather Settings (ESP32 only, disabled on ESP8266 by default) - Configure weather display:
- OpenWeatherMap API key integration
- City/Location configuration (by GPS coordinates)
- Units (Celsius/Fahrenheit)
- Independent fetch interval (how often to call the API) and display interval (how often to interrupt the clock)
Crypto Price Ticker (ESP32 only, disabled on ESP8266 by default) - Configure live cryptocurrency prices:
- Up to 10 coins via CoinPaprika IDs (e.g.
btc-bitcoin,eth-ethereum) — no API key required - Display currency: USD, EUR, GBP, JPY, BTC, ETH
- Independent fetch interval (15 min–4h) and display interval (1 min–4h)
- Configurable scroll repetitions and brightness
- See Crypto Ticker Guide for full details, coin IDs, API key setup, and CoinPaprika API information
Sleep Mode - Configure schedule:
- Scheduled display dimming or blackout windows
- Start/End time configuration
- Optional Weekend Mode
System - System management:
- OTA firmware upload
- Device reboot (resets the board)
- Factory reset (wipe all configuration)
- Current version display
Example 1 - Compact Design:
Example 2 - Portable (battery and main powered) Setup:
The device provides two HTTP endpoints for sending messages programmatically. For a comprehensive testing guide and more examples, see HTTP API Examples.
Send messages via GET request with URL-encoded parameters.
Endpoint: GET /arg
Authentication: HTTP Basic Auth (username:password)
Parameters:
| Parameter | Description | Default | Range/Values |
|---|---|---|---|
MSG |
Message text to display | (required) | UTF-8 string |
REP |
Repeat count (scroll cycles) | 10 | 0 = infinite |
BUZ |
Buzzer chirps | 10 | 0 = silent |
DEL |
Scroll delay (ms per step) | 35 | Lower = faster |
BRI |
Brightness level | 7 | 0 (dim) - 15 (bright) |
ASC |
UTF-8 ASCII conversion | 1 | 0 = off, 1 = on |
ALERTCHIRP |
Alert chirp pattern | Fast Beep | See chirp library below |
Note
Omitting the MSG parameter or sending with empty value will stop the current message scrolling.
Available Chirp Patterns: Silent, Fast Beep, Simple Beep, Gentle Dawn, Cheerful, Urgent, Beep, Quick Tap, Double, Triple, Doorbell, Alarm, Victory, Notify, For Elise, Mario Bros, Imperial March, Nokia Ringtone, Star Wars Theme, Tetris, Pac-Man, Simpsons, Underworld, Indiana Jones, Pink Panther, Game Over, Level Up, Achievement, 24 CTU Ring
Example - Send Message:
curl --user admin:msgboard -X GET -G 'http://192.168.1.100/arg' \
--data-urlencode "MSG=Hello World!" \
--data-urlencode "REP=5" \
--data-urlencode "BUZ=3" \
--data-urlencode "DEL=30" \
--data-urlencode "BRI=10" \
--data-urlencode "ASC=1" \
--data-urlencode "ALERTCHIRP=Gentle Dawn"Example - URL Encoded (for browsers):
http://192.168.1.100/arg?MSG=This+is+a+test+message%21&REP=10&BUZ=10&DEL=35&BRI=7&ASC=1&ALERTCHIRP=Gentle+Dawn
Use URL encoder/decoder for special characters.
Example - Stop Current Message:
curl --user admin:msgboard -X GET 'http://192.168.1.100/arg'Send messages via POST request with JSON payload.
Endpoint: POST /api
Authentication: HTTP Basic Auth (username:password)
Content-Type: application/json
JSON Fields (all optional except MSG for new messages):
{
"MSG": "Message text",
"REP": 10,
"BUZ": 10,
"DEL": 35,
"BRI": 7,
"ASC": 1,
"ALERTCHIRP": "Gentle Dawn"
}Example - Send Message:
curl --user admin:msgboard -X POST http://192.168.1.100/api \
-H 'Content-Type: application/json' \
-d '{"MSG":"This is a test message","REP":1,"BUZ":10,"DEL":2,"BRI":0,"ASC":1}'Example - Minimal (uses defaults):
curl --user admin:msgboard -X POST http://192.168.1.100/api \
-H 'Content-Type: application/json' \
-d '{"MSG":"Quick message"}'Example - Stop Current Message:
curl --user admin:msgboard -X POST http://192.168.1.100/api \
-H 'Content-Type: application/json' \
-d '{"MSG":""}'Export Configuration (GET /exportconfig):
curl --user admin:msgboard http://192.168.1.100/exportconfig > config_backup.jsonReturns complete device configuration including credentials, MQTT settings, defaults, and WiFi credentials.
Import Configuration (POST /importconfig):
curl --user admin:msgboard -X POST http://192.168.1.100/importconfig \
-H 'Content-Type: application/json' \
-d @config_backup.jsonRestores configuration from backup file. Device will apply settings immediately.
The message board supports MQTT with flexible topic subscription patterns, making it easy to integrate with home automation systems. For a comprehensive guide on MQTT commands and clock control, see MQTT Examples.
Configure via web interface (/mqttconfig) or imported configuration:
- MQTT Server: IP address or hostname
- MQTT Port: Default 1883 (Plain) or 8883 (TLS)
- Authentication: Anonymous or username/password
- TLS/SSL: Enable encryption, validate via Fingerprint or CA Certificate (ESP32 only)
- Topic Prefix: Root topic for subscriptions (supports wildcards)
- Alerts: Enable/disable connection/disconnection notifications on display
When you configure a topic prefix like rdadotmatrix/generic, the device automatically subscribes to:
rdadotmatrix # Root topic - plain messages
rdadotmatrix/json # Root topic - JSON messages
rdadotmatrix/generic # Configured prefix - plain messages
rdadotmatrix/generic/json # Configured prefix - JSON messages
RDA-MSG-ABCDEF # Device-specific - plain messages
RDA-MSG-ABCDEF/json # Device-specific - JSON messages
Hash (#) Wildcard - Subscribe to all subtopics:
Topic Prefix: rdadotmatrix/generic/#
Subscribes to:
rdadotmatrix # Root still subscribed
rdadotmatrix/json
rdadotmatrix/generic/# # All subtopics under generic/
RDA-MSG-ABCDEF
RDA-MSG-ABCDEF/json
Messages can be published to:
rdadotmatrix/generic/room1/jsonrdadotmatrix/generic/room2/alerts/json- Any path under
rdadotmatrix/generic/
Plus (+) Wildcard - Single-level wildcard in topic path.
Plain Text Messages (topics NOT ending in /json):
mosquitto_pub -h 192.168.1.100 -t "rdadotmatrix/generic" -m "Hello from MQTT"Uses default parameters (REP=10, BUZ=10, DEL=35, BRI=7, ASC=1).
JSON Messages (topics ending in /json):
mosquitto_pub -h 192.168.1.100 -t "rdadotmatrix/generic/json" \
-m '{"MSG":"Custom message","REP":5,"BUZ":3,"DEL":25,"BRI":10,"ASC":1}'Minimal JSON (omitted parameters use defaults):
mosquitto_pub -h 192.168.1.100 -t "RDA-MSG-ABCDEF/json" \
-m '{"MSG":"Quick alert"}'Stop Message:
mosquitto_pub -h 192.168.1.100 -t "rdadotmatrix/generic/json" \
-m '{"MSG":""}'The device publishes its connection status to:
RDA-MSG-ABCDEF/status: "Connected"
Recommended Method
This firmware supports Home Assistant MQTT Discovery. When enabled, the device will automatically appear in Home Assistant with all controls and sensors.
For detailed setup instructions and a list of available entities, see the Home Assistant Integration Guide.
Caution
This is a legacy method using manual YAML configuration. It is recommended to use the Automatic Integration instead.
If you prefer to manually configure your dashboard, scripts, and automations using YAML, or if you need to integrate via the REST API, please refer to the:
Manual / Legacy Home Assistant Integration Guide
This guide includes:
- Base64 Authentication setup
- Manual Dashboard (Lovelace) configuration
- REST Commands and Scripts
- RSS Feed automations
Import the provided node_red_flow.json file for a complete NodeRed integration example.
Install these packages in NodeRed:
node-red-contrib-simple-message-queue
node-red-node-feedparser
The NodeRed flow includes:
- MQTT message publishing subflows
- RSS feed processing with character escaping (handles backslashes, quotes, etc.)
- Message queue management
- Examples for both plain and JSON MQTT messages
Tip
The flow includes special character escaping functions useful when working with RSS feeds that may contain quotes, backslashes, or other characters that could break message display.
The device supports UTF-8 extended ASCII characters for international and special character display.
!"$'()*,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¢£€¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
These characters require special encoding in URLs or may need escaping in certain contexts:
# % & + ;
Note
In NodeRed, the provided flow includes escape functions for handling special characters like backslashes and double-quotes in RSS feeds.
Reference: UTF-8 Character Table
Reset the device to default settings and clear all configuration.
- Navigate to
/system - Click "Wipe Config"
- Confirm the action
- Device will:
- Clear WiFi configuration
- Reset web credentials to
admin/msgboard - Clear MQTT configuration
- Clear custom defaults
- Reboot into WiFi Setup Mode
If ENABLE_FLASH_BUTTON is enabled in include/config.h (currently disabled by default):
- Press the FLASH button (GPIO0)
- Device will perform factory reset and reboot
- Note: Currently only supported on ESP8266
Browse to:
http://192.168.1.100/factoryreset
- Check SSID: Look for
RDA-MSG-XXXXXXin WiFi networks (X = last 6 chars of MAC) - Password: Ensure you're using
wifi-setup(case-sensitive) - Manual IP: If portal doesn't open automatically, browse to
http://192.168.4.1 - Factory Reset: Hold FLASH button or upload firmware with cleared WiFi settings
- Check IP: Verify IP address shown on LED matrix after boot
- Try mDNS: Use
http://RDA-MSG-XXXXXX.localinstead of IP - Credentials: Default is
admin/msgboard, check if changed - Network: Ensure device and computer are on same network/VLAN
- Check Config: Verify server address, port, and credentials in
/mqttconfig - Enable MQTT: Ensure "MQTT On/Off" is set to "on"
- Topic Prefix: Verify topic prefix doesn't have syntax errors
- Alerts: Enable connection alerts to see status on display
- Server: Confirm MQTT broker is running and accessible
- Parameter Check: Ensure
MSGparameter is not empty - Repeat Count: If REP=0, message scrolls indefinitely; use empty MSG to stop
- Brightness: Check BRI value isn't set to 0 (completely dim but still visible)
- Character Support: Some characters may not display if UTF-8 conversion (ASC=0)
- Serial Monitor: Close serial monitor before uploading
- USB Driver: Install CH340/CP2102 drivers for your board
- Port Selection: Verify correct COM port selected in PlatformIO
- Erase Flash: If persistent issues, erase flash and re-upload
- UTF-8 Conversion: Ensure ASC parameter is set to 1 for international characters
- Escape Issues: Check for unescaped special characters in message text
- Buffer Overflow: Very long messages may cause issues; keep messages reasonable
The device stores configuration in LittleFS flash filesystem:
/web_config.json- Web credentials and hostname/mqtt_config.json- MQTT settings/defaults_config.json- Custom message parameter defaults/general.config- General device parameters (e.g. buzzer toggles, overrides)/clock.config- Clock and timezone settings/timer.config- Timer and stopwatch settings/weather.config- OpenWeatherMap integration settings/crypto_config.json- Crypto price ticker settings (coins, currency, intervals)/sleep_mode.config- Sleep schedule configurations/alarm.config- Schedule recurring daily alarms/recurrent_alarm.config- Fixed interval alerts (Home Assistant discovery is ESP32-only)
These are automatically created on first boot. While stored as individual files in flash memory, they are aggregated and downloaded as a single comprehensive JSON backup file when you use the Export feature on the Device Config page. This single file can later be imported to restore all settings at once.
Current firmware version is defined in platformio.ini and displayed on the web interface. Build artifacts are automatically generated for the following CI environments:
- NodeMCU (ESP8266):
rda_msg_board_nodemcu_4m_v0.9.4.bin/rda_msg_board_nodemcu_8m_v0.9.4.bin - Wemos D1 Mini (ESP8266):
rda_msg_board_d1_mini_4m_v0.9.4.bin/rda_msg_board_d1_mini_8m_v0.9.4.bin - ESP32 DevKit:
rda_msg_board_esp32_4m_v0.9.4.bin/rda_msg_board_esp32_8m_v0.9.4.bin
Data Source: All cryptocurrency price data is fetched from the CoinPaprika API.
Personal Use Only: This is a hobbyist project created for educational and personal purposes. In accordance with CoinPaprika's Terms of Use:
- This software does not support commercial redistribution.
- Users are responsible for adhering to CoinPaprika's applicable rate limits — see the API documentation for current plan details.
- Any individual or entity selling hardware pre-loaded with this software is responsible for securing a commercial/Enterprise license from CoinPaprika.
Liability: The developer of this project is not responsible for any API bans, financial losses, or legal actions taken by third-party data providers against the user.
This project is licensed under the MIT License - see the LICENSE file for details.
- Original project development for Arduino IDE
- Migrated to PlatformIO for improved development workflow
- Uses MD_Parola library for scrolling effects
- WiFiManager for easy WiFi configuration
This project relies on the excellent open-source libraries and tools from the Arduino/ESP community. Special thanks to:
- MajicDesigns/MD_MAX72XX by Marco Colli - The foundational library for controlling MAX7219 LED matrix displays. This project uses MD_MAX72XX for driving LED matrix displays and would not be possible without this excellent work.
- trip5/Matrix-Fonts by Trip5 / Conventional Chaos (CC-BY) - Source BDF bitmap fonts used to derive all six custom clock faces (Matrix Light 8px, Matrix Light 8px X, Matrix Light 6px, Matrix Light 6px X, Matrix Chunky 6px, Matrix Chunky 6px X). The BDF files were converted to the MD_MAX72XX PROGMEM font format using the included
tools/bdf_to_parola.pyconverter with FC16-hardware bit-ordering corrections. - MD_Parola by Marco Colli - Scrolling text animation effects and display management for MAX7219 matrices, built on top of MD_MAX72XX.
- WiFiManager by tzapu - WiFi configuration portal that makes initial device setup painless.
- ArduinoJson by Benoit Blanchon - Efficient JSON parsing and serialization library.
- PubSubClient by Nick O'Leary - MQTT client library for connecting to MQTT brokers.
- CoinPaprika - Free cryptocurrency market data API powering the Crypto Price Ticker feature. No API key required on the free tier.
- The entire PlatformIO team for the excellent build system and development environment.
Detailed documentation for specific features and integrations:
- Installation & Setup - Hardware pinning and resource allocation
- Home Assistant Integration - Guide for integrating with Home Assistant
- MQTT Examples - CLI and script examples for MQTT control
- HTTP API Examples - Comprehensive guide to the REST API
- MQTT TLS Implementation - Technical details of SSL/TLS security on ESP32
- Crypto Price Ticker - Coin IDs, API key setup, build flags, HA integration
- Architecture - System architecture and module documentation
The codebase is modularly organized for maintainability:
- Web Layer:
web_server,config_manager,web_data,web_pages_*- HTTP interface and configuration - MQTT Layer:
mqtt,mqtt_discovery_*- MQTT client and Home Assistant integration - Core Logic:
functions,utf8_utils,buzzer_utils- Display control, character encoding, audio feedback - Feature Modules:
weather,crypto,timer- Optional ESP32 features - Configuration: JSON files in LittleFS (
/web_config.json,/mqtt_config.json,/defaults_config.json,/general.config)
See docs/ARCHITECTURE.md for detailed module documentation.
This project includes an RDA MSG Board skill document that can be used by AI agents or LLMs (such as OpenClaw) to interact with and control the LED matrix display directly.
The skill provides Python scripts and instructions for sending scrolling text messages, playing audible alerts, and managing multiple board connection profiles.
- SKILL For AI Agents / LLMs: Configure your agent (e.g., OpenClaw) to load the skill from
skills/rda-msg-board/SKILL.md. This provides the LLM with the ability to use the providedsend_message.pyandmanage_boards.pyscripts to send messages and alerts via the HTTP JSON API.python3 skills/rda-msg-board/scripts/manage_boards.py add office --ip 192.168.1.50 --user admin --pass msgboard python3 skills/rda-msg-board/scripts/send_message.py "Hello from AI Agent" --profile office - For Manual Use: Users can read
skills/rda-msg-board/SKILL.mddirectly as a comprehensive guide on how to set up device profiles and trigger messages manually from the terminal.python3 skills/rda-msg-board/scripts/send_message.py "Hello World" --ip 192.168.1.100
- PlatformIO Documentation
- MD_Parola Library
- WiFiManager Library
- Home Assistant MQTT Integration
- NodeRed Documentation
- trip5/Matrix-Fonts







