This project allows you to control the Sure P4 32x8 displays. Though, it is written for this specific version, it should pretty much work for all Holtek HT1632 based matrix displays.
The main goal is to give a generic, pluggable way to interface different kinds of applications with the display, without having to bother with the driver stuff.
This package provides an MQTT client that uses a modern state-based JSON protocol, making it easy to integrate with IoT systems, Home Assistant, and other MQTT-enabled applications.
The main application consists of two basic parts:
curses-client, an interactive client, probably best used to test the hardware setup and display capabilities.
raspberry-display-mqtt (or mock-display-mqtt for testing), the MQTT client that listens for state-based JSON commands and controls the display accordingly.
The mock version works without physical hardware and is perfect for test setups or debugging the API usage.
The display uses a state-based MQTT protocol where you send JSON payloads describing the desired display state to the display/set topic.
The MQTT client connects to your MQTT broker and subscribes to:
display/set- Set the full display sequence statedisplay/add- Add state to the display sequencedisplay/clear- Clear the display sequencedisplay/quit- Quit the application
All commands are JSON objects that can contain multiple state properties:
{
"text": "string", // Text to display (optional)
"show_time": boolean, // Show time (with or without text)
"time_format": "string", // Time format, strftime(3) compatible
"brightness": number, // 0-15
"scroll": "string", // "enabled"/"disabled"/"reset"
"alignment": "string", // "left"/"center" - text alignment (default: "left")
"transition": "string" | { // Transition effect (optional)
"type": "string", // Transition type
"duration": number // Duration in seconds (optional)
}
}
Available transition effects:
"none"- No transition (default)"wipe_left"- Wipe from right to left"wipe_right"- Wipe from left to right"dissolve"- Fade effect"scroll_up"- Scroll content upward"scroll_down"- Scroll content downward"split_center"- Split from center outward"split_sides"- Split from sides inward"random"- Random transition selection
Transitions can be specified as:
- Simple string:
"transition": "dissolve" - Object with duration:
"transition": {"type": "wipe_left", "duration": 1.5}
The display supports three main modes based on the JSON fields:
- Text only:
{"text": "Hello World!"} - Text with time:
{"text": "Meeting soon", "show_time": true} - Time only:
{"show_time": true}(no text field)
Here are practical examples using mosquitto_pub to control the display:
Show simple text:
mosquitto_pub -h localhost -t display/set -m '[{"state": {"text": "Hello World!"}, "time": 5.0}]'Show current time:
mosquitto_pub -h localhost -t display/set -m '[{"state": {"show_time": true}, "time": 10.0}]'Show text with custom time format and dissolve transition:
mosquitto_pub -h localhost -t display/set -m '[{"state": {"text": "Meeting at", "show_time": true, "time_format": "%H:%M", "transition": "dissolve"}, "time": 8.0}]'Centered text with custom brightness and wipe transition:
mosquitto_pub -h localhost -t display/set -m '[{"state": {"text": "WELCOME", "alignment": "center", "brightness": 10, "transition": {"type": "wipe_left", "duration": 1.5}}, "time": 3.0}]'Add a single message to the sequence:
mosquitto_pub -h localhost -t display/add -m '{"state": {"text": "New Message"}, "time": 4.0}'Add with TTL (auto-expire after 30 seconds):
mosquitto_pub -h localhost -t display/add -m '{"state": {"text": "Temporary Alert"}, "time": 2.0, "ttl": 30.0}'Add with sequence ID and split transition:
mosquitto_pub -h localhost -t display/add -m '{"state": {"text": "Meeting Room A", "transition": "split_center"}, "time": 5.0, "id": "meeting_alerts"}'Multi-step sequence with transitions:
mosquitto_pub -h localhost -t display/set -m '[
{"state": {"text": "Step 1", "alignment": "center", "transition": "scroll_down"}, "time": 3.0, "id": "meeting_alerts1"},
{"state": {"text": "Step 2", "brightness": 8, "transition": "wipe_right"}, "time": 3.0, "id": "meeting_alerts2"},
{"state": {"show_time": true, "transition": "dissolve"}, "time": 5.0, "id": "meeting_alerts3"}
]'Scrolling text sequence:
mosquitto_pub -h localhost -t display/set -m '[
{"state": {"text": "This is a very long message that will scroll across the display", "scroll": "enabled"}, "time": 10.0, "id": "meeting_alerts1"},
{"state": {"text": "Normal text", "scroll": "disabled"}, "time": 3.0, "id": "meeting_alerts2"}
]'Clear all sequences:
mosquitto_pub -h localhost -t display/clear -m '{}'Clear specific sequence by ID:
mosquitto_pub -h localhost -t display/clear -m '{"id": "meeting_alerts"}'Gracefully stop the MQTT client:
mosquitto_pub -h localhost -t display/quit -m '{}'Weather display with smooth transitions:
mosquitto_pub -h localhost -t display/set -m '[
{"state": {"text": "Weather", "alignment": "center", "brightness": 12, "transition": {"type": "dissolve", "duration": 2.0}}, "time": 2.0, "id": "weather1"},
{"state": {"text": "22°C Sunny", "show_time": true, "time_format": "%H:%M", "transition": "scroll_up"}, "time": 8.0, "id": "weather2"}
]'Status board rotation with varied transitions:
mosquitto_pub -h localhost -t display/set -m '[
{"state": {"text": "Server: OK", "alignment": "left", "transition": "wipe_left"}, "time": 4.0, "id": "status1"},
{"state": {"text": "DB: OK", "alignment": "left", "transition": "wipe_right"}, "time": 4.0, "id": "status2"},
{"state": {"text": "API: OK", "alignment": "left", "transition": "split_sides"}, "time": 4.0, "id": "status3"},
{"state": {"show_time": true, "transition": "random"}, "time": 6.0, "id": "status4"}
]'The MQTT client provides helpful error messages:
- Invalid JSON shows parse errors with line/column information
- Unsupported topics show usage examples
- Invalid brightness values show acceptable range (0-15)
Currently, only a limited set of ASCII characters are supported. The display expects iso-8859-1 encoding, and any unknown characters will be rendered as a single space.
First install the system pre-requisites and the WiringPi library.
You might want to change the display headers if you have a setup that is different than the reference setup.
If you're on a debian system, like raspbian, this is simply
./install-prereqs-debian.sh
./install-wiringPi.shOnce this is done, you should be able to build the project with
makeInstalling the application will place the binary in a system wide location, and create systemd service files to make sure the process is always running.
NB: The service will be installed as the current running user. For this to work, the user needs access to the SPI-device.
After you have built the application, you can install it with
sudo make installThis will install the raspberry-display-mqtt to /usr/bin/raspberry-display-mqtt and create systemd service files.
The MQTT client also supports configuration via environment variables (useful for systemd service):
# Set environment variables
export MQTT_HOST="localhost"
export MQTT_PORT="1883"
export CLIENT_ID="raspberry-display"
export TOPIC_PREFIX="display"
# Run without arguments
./build/raspberry-display-mqttTo (re)start the systemd service, run
sudo systemctl restart raspberry-displayTo view log files, you can use the systemd journal
sudo journalctl -f -u raspberry-display- Always restart: Service automatically restarts on any failure
- Restart delay: 10-second delay between restart attempts
- Rate limiting: Maximum 5 restarts within 5 minutes to prevent restart loops
- Network dependency: Waits for network connectivity before starting
# Check service status
sudo systemctl status raspberry-display
# View recent logs
sudo journalctl -u raspberry-display --since "1 hour ago"
# Follow logs in real-time
sudo journalctl -f -u raspberry-display
# Check restart history
sudo systemctl show raspberry-display -p NRestartsTo uninstall
sudo make uninstallYou'll need an MQTT broker running. For testing, you can install Mosquitto:
# Install Mosquitto MQTT broker
sudo apt update && sudo apt install -y mosquitto mosquitto-clients
# Start the broker
mosquitto -vThe application is designed to use spi0 on the rasperry pi, and four generic GPIO pins. This can be changed, but for a basic
setup, just follow the reference connection.
All pins referenced are physical pins. The application uses WiringPi-numbering for CS-pins. These will be different from the physical pins (use this guide for WiringPi numbering).
| Pin | Usage |
|---|---|
| 2 | 5V |
| 6 | Ground |
| 3 | CS1 |
| 5 | CS2 |
| 8 | CS3 |
| 10 | CS4 |
| 19 | MOSI/Data |
| 23 | SCLK/WR |
This project is written by Torkild Retvedt, as a rewrite of a similar project for the Arduino UNO
Much of the ht1632 driver is inspired by this repo.
This software is licensed under the MIT license, unless specified.
- Home assistant MQTT
