MQTT Hub 75 Display With Arduino and Esp 32

by spike318 in Circuits > Arduino

31 Views, 0 Favorites, 0 Comments

MQTT Hub 75 Display With Arduino and Esp 32

2026-03-11 11_55_25-VLC Media Player.png
2026-03-11 11_55_25-VLC Media Player.png

MQTT display with web interface

Supplies

Arduino Uno

ESP32

Hub75 display

Display Onnection 2 Arduino

🔹 Arduino → HUB08

  1. D2 → D0
  2. D3 → CLK
  3. D4 → LAT
  4. OE → GND
  5. D5 → A
  6. D6 → B
  7. D7 → C
  8. D8 → D
  9. 5V → VCC
  10. GND → GND


Setup

🧩 ARCHITECTUUR

WiFi / MQTT

ESP32 Wifi en data voor display ! Settings IP MQTT server en MQTT Topics Helderheid

|

UART (Serial) MQTT Topics / 2 of 4 lijnen / en helderheid van display

|

Arduino UNO Dient enkel voor aansturing van de display.

|

HUB08 16×64 LED Display die je nooit moet kopen alleen aanstuurbaar door Uno


ESP32 ↔ Arduino UNO

ESP32 UNO

TX2 (GPIO17) RX (D0)

RX2 (GPIO16) TX (D1)

GND GND

⚠️ UNO loskoppelen van USB bij upload ESP32

⚠️ Baudrate = 115200

⚡ Voeding (HEEL BELANGRIJK)

Display +5V → externe voeding

Display GND → voeding GND

Arduino GND → zelfde GND


Als GND niet gedeeld is → werkt niks / rare fouten


✅ Nano instellingen (Arduino IDE)

  1. Board: Arduino Nano
  2. Processor: ATmega328P (Old Bootloader) (vaak nodig)
  3. Baudrate: 115200


Arduino Code


#include <SPI.h>

#include "HUB08SPI.h"

#include "TimerOne.h"

#include "Buffer.h"


#define WIDTH 64

#define HEIGHT 16


uint8_t displaybuf[WIDTH * HEIGHT / 8];

Buffer buff(displaybuf, WIDTH, HEIGHT);

HUB08SPI display;


// MOET NA Buffer

#include "ronnAnimation.h"


/* ===== TEKST ===== */

String line1 = "1";

String line2 = "2";

String line3 = "3";

String line4 = "4";

String ipText = "";


/* ===== INSTELLINGEN ===== */

int brightness = 100;

int zoneMode = 4;


/* ===== STATES ===== */

bool showIP = true; // start met Waiting IP

bool needsRedraw = true;


unsigned long ipShownAt = 0;

const unsigned long ipShowTime = 2000;


/* ===== REFRESH ISR ===== */

void refresh() {

display.scan();

}


/* ================================================= */


void setup() {

Serial.begin(115200);


display.begin(displaybuf, WIDTH, HEIGHT);

Timer1.initialize(100);

Timer1.attachInterrupt(refresh);


display.setBrightness(brightness);

buff.clear();


ronn.setFont();

ronn.printText("Arduino Uno", 0, 0);

ronn.printText("Boot OK", 0, 8);

delay(1000);


// Waiting IP

ipText = "Waiting IP";

showIP = true;

needsRedraw = true;

}


/* ================================================= */


void loop() {


/* ===== SERIAL ===== */

if (Serial.available()) {

String cmd = Serial.readStringUntil('\n');

cmd.trim();


if (cmd == "CLR") {

buff.clear();

needsRedraw = true;

return;

}


if (cmd.startsWith("BR:")) {

brightness = constrain(cmd.substring(3).toInt(), 0, 255);

display.setBrightness(brightness);

return;

}


if (cmd.startsWith("ZONES:")) {

zoneMode = cmd.substring(6).toInt();

if (zoneMode == 1) zoneMode = 2;

needsRedraw = true;

return;

}


if (cmd.startsWith("IP:")) {

ipText = cmd.substring(3);

showIP = true;

ipShownAt = millis();

needsRedraw = true;

return;

}


if (cmd.startsWith("L1:")) { line1 = cmd.substring(3); needsRedraw = true; }

if (cmd.startsWith("L2:")) { line2 = cmd.substring(3); needsRedraw = true; }

if (cmd.startsWith("L3:")) { line3 = cmd.substring(3); needsRedraw = true; }

if (cmd.startsWith("L4:")) { line4 = cmd.substring(3); needsRedraw = true; }

}


/* ===== IP TIMEOUT ===== */

if (showIP && ipText != "Waiting IP") {

if (millis() - ipShownAt > ipShowTime) {

showIP = false;

needsRedraw = true;

}

}


/* ===== REDRAW ===== */

if (!needsRedraw) return;

needsRedraw = false;


buff.clear();

ronn.setFont();


if (showIP) {

if (ipText == "Waiting IP") {

ronn.printText("Waiting IP", 0, 4);

} else {

ronn.printText("IP:", 0, 0);

ronn.printText(ipText, 0, 8);

}

return;

}


// NORMALE DISPLAY

if (zoneMode == 2) {

ronn.printText(line1, 0, 0);

ronn.printText(line2, 0, 8);

} else {

ronn.printText(line1, 0, 0);

ronn.printText(line2, 32, 0);

ronn.printText(line3, 0, 8);

ronn.printText(line4, 32, 8);

}

}


ESP 32 Code

#include <WiFi.h>

#include <PubSubClient.h>

#include <WebServer.h>

#include <Preferences.h>


/* ========= OBJECTEN ========= */

WiFiClient espClient;

PubSubClient client(espClient);

WebServer server(80);

Preferences prefs;


/* ========= WIFI ========= */

String wifi_ssid;

String wifi_pass;


/* ========= MQTT ========= */

String mqtt_server;

String mqtt_user;

String mqtt_pass;

int mqtt_port = 1883;


/* ========= TOPICS & LABELS ========= */

String topicLine1, topicLine2, topicLine3, topicLine4;

String labelLine1, labelLine2, labelLine3, labelLine4;


/* ========= DISPLAY ========= */

int displayBrightness = 180;

int zoneMode = 4;


/* ========================================================= */

/* ======================= MQTT CALLBACK =================== */

/* ========================================================= */

void callback(char* topic, byte* payload, unsigned int length) {

String msg;

for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];


if (zoneMode == 4) {

if (strcmp(topic, topicLine1.c_str()) == 0)

Serial2.println("L1:" + labelLine1 + " " + msg);

else if (strcmp(topic, topicLine2.c_str()) == 0)

Serial2.println("L2:" + labelLine2 + " " + msg);

else if (strcmp(topic, topicLine3.c_str()) == 0)

Serial2.println("L3:" + labelLine3 + " " + msg);

else if (strcmp(topic, topicLine4.c_str()) == 0)

Serial2.println("L4:" + labelLine4 + " " + msg);

} else {

if (strcmp(topic, topicLine1.c_str()) == 0)

Serial2.println("L1:" + labelLine1 + " " + msg);

else if (strcmp(topic, topicLine2.c_str()) == 0)

Serial2.println("L2:" + labelLine2 + " " + msg);

}

}


/* ========================================================= */

/* ======================= SETTINGS ======================== */

/* ========================================================= */

void loadSettings() {

wifi_ssid = prefs.getString("w_ssid", "");

wifi_pass = prefs.getString("w_pass", "");


mqtt_server = prefs.getString("m_host", "");

mqtt_user = prefs.getString("m_user", "");

mqtt_pass = prefs.getString("m_pass", "");

mqtt_port = prefs.getInt("m_port", 1883);


topicLine1 = prefs.getString("t1", "display/line1");

topicLine2 = prefs.getString("t2", "display/line2");

topicLine3 = prefs.getString("t3", "display/line3");

topicLine4 = prefs.getString("t4", "display/line4");


labelLine1 = prefs.getString("l1", "Line1");

labelLine2 = prefs.getString("l2", "Line2");

labelLine3 = prefs.getString("l3", "Line3");

labelLine4 = prefs.getString("l4", "Line4");


displayBrightness = prefs.getInt("br", 180);

zoneMode = prefs.getInt("zones", 4);

if (zoneMode != 2 && zoneMode != 4) zoneMode = 4;

}


/* ========================================================= */

/* ======================= WIFI ============================ */

/* ========================================================= */

bool connectWiFi() {

if (wifi_ssid == "") return false;


WiFi.mode(WIFI_STA);

WiFi.begin(wifi_ssid.c_str(), wifi_pass.c_str());


unsigned long start = millis();

while (WiFi.status() != WL_CONNECTED) {

delay(500);

if (millis() - start > 15000) return false;

}

return true;

Serial2.println("IP:" + WiFi.localIP().toString());

}


void startAP() {

WiFi.mode(WIFI_AP);

WiFi.softAP("ESP32-Setup");

Serial.println("AP IP: " + WiFi.softAPIP().toString());

}


/* ========================================================= */

/* ======================= MQTT ============================ */

/* ========================================================= */

void reconnectMQTT() {

if (mqtt_server == "") return;


while (!client.connected()) {

String id = "ESP32-" + String(random(0xffff), HEX);

if (client.connect(id.c_str(), mqtt_user.c_str(), mqtt_pass.c_str())) {

client.subscribe(topicLine1.c_str());

client.subscribe(topicLine2.c_str());

client.subscribe(topicLine3.c_str());

client.subscribe(topicLine4.c_str());

} else {

delay(2000);

}

}

}


/* ========================================================= */

/* ======================= WEB UI ========================== */

/* ========================================================= */

void handleRoot() {

String html =

"<!DOCTYPE html><html><head><meta charset='UTF-8'>"

"<title>SPIKE TECH – ESP32</title>"

"<style>"

"body{font-family:Arial;background:#f2f3f5}"

".box{width:400px;margin:10px auto;background:#fff;padding:35px;border-radius:10px}"

"h2{text-align:center;color:#e53935;letter-spacing:4px}"

"h3{border-bottom:2px solid #e53935;color:#e53935;margin-top:35px}"

"label{font-weight:bold;margin-top:10px;display:block}"

"input,select{width:100%;padding:8px;margin-top:5px}"

".row{display:flex;gap:20px}"

".col{flex:1}"

"button{margin-top:30px;padding:14px;width:100%;background:#e53935;color:#fff;font-size:18px;border:none;border-radius:6px}"

"</style></head><body><div class='box'>"


"<h2>SPIKE TECH</h2>"


"<form action='/save' method='POST'>"


"<h3>Display</h3>"

"<div class='row'>"

"<div class='col'><label>Brightness</label><input name='br' value='" + String(displayBrightness) + "'></div>"

"<div class='col'><label>Zones</label><select name='zones'>"

"<option value='2'" + String(zoneMode==2?" selected":"") + ">2 Zones</option>"

"<option value='4'" + String(zoneMode==4?" selected":"") + ">4 Zones</option>"

"</select></div></div>"


"<h3>Lines</h3>";


auto lineRow = [&](int n, String lbl, String top) {

return "<div class='row'><div class='col'><label>L"+String(n)+" Label</label>"

"<input name='lbl"+String(n)+"' value='"+lbl+"'></div>"

"<div class='col'><label>L"+String(n)+" Topic</label>"

"<input name='l"+String(n)+"' value='"+top+"'></div></div>";

};


html += lineRow(1,labelLine1,topicLine1);

html += lineRow(2,labelLine2,topicLine2);

html += lineRow(3,labelLine3,topicLine3);

html += lineRow(4,labelLine4,topicLine4);


html +=

"<h3>WiFi</h3>"

"<label>SSID</label><input name='ssid' value='"+wifi_ssid+"'>"

"<label>Password</label><input type='password' name='wpass' value='"+wifi_pass+"'>"


"<h3>MQTT</h3>"

"<div class='row'>"

"<div class='col'><label>Server</label><input name='mhost' value='"+mqtt_server+"'></div>"

"<div class='col'><label>Port</label><input name='mport' value='"+String(mqtt_port)+"'></div>"

"</div>"

"<label>User</label><input name='muser' value='"+mqtt_user+"'>"

"<label>Password</label><input type='password' name='mpass' value='"+mqtt_pass+"'>"


"<button type='submit'>Save (Live)</button></form></div></body></html>";


server.send(200, "text/html", html);

}


/* ========================================================= */

/* ======================= SAVE ============================ */

/* ========================================================= */


void handleSave() {

int oldZone = zoneMode;


wifi_ssid = server.arg("ssid");

wifi_pass = server.arg("wpass");


mqtt_server = server.arg("mhost");

mqtt_user = server.arg("muser");

mqtt_pass = server.arg("mpass");

mqtt_port = server.arg("mport").toInt();


displayBrightness = server.arg("br").toInt();

zoneMode = server.arg("zones").toInt();

if (zoneMode != 2 && zoneMode != 4) zoneMode = oldZone;


topicLine1 = server.arg("l1");

topicLine2 = server.arg("l2");

topicLine3 = server.arg("l3");

topicLine4 = server.arg("l4");


labelLine1 = server.arg("lbl1");

labelLine2 = server.arg("lbl2");

labelLine3 = server.arg("lbl3");

labelLine4 = server.arg("lbl4");


prefs.putString("w_ssid", wifi_ssid);

prefs.putString("w_pass", wifi_pass);

prefs.putString("m_host", mqtt_server);

prefs.putString("m_user", mqtt_user);

prefs.putString("m_pass", mqtt_pass);

prefs.putInt("m_port", mqtt_port);


prefs.putString("t1", topicLine1);

prefs.putString("t2", topicLine2);

prefs.putString("t3", topicLine3);

prefs.putString("t4", topicLine4);


prefs.putString("l1", labelLine1);

prefs.putString("l2", labelLine2);

prefs.putString("l3", labelLine3);

prefs.putString("l4", labelLine4);


prefs.putInt("br", displayBrightness);

prefs.putInt("zones", zoneMode);


Serial2.println("BR:" + String(displayBrightness));

if (oldZone != zoneMode) {

Serial2.println("ZONES:" + String(zoneMode));

// Serial2.println("BR:" + String(displayBrightness));

}


// 🔁 NETTE REDIRECT

server.sendHeader("Location", "/");

server.send(303);


delay(200);


// 🔄 reconnect NA response

WiFi.disconnect();

connectWiFi();


client.disconnect();

reconnectMQTT();

}





/* ========================================================= */

/* ======================= SETUP =========================== */

/* ========================================================= */

void setup() {

Serial.begin(115200);

Serial2.begin(115200, SERIAL_8N1, 16, 17);


prefs.begin("display", false);

loadSettings();


if (!connectWiFi()) startAP();

Serial2.println("IP:" + WiFi.localIP().toString());


Serial2.println("ZONES:" + String(zoneMode));



client.setServer(mqtt_server.c_str(), mqtt_port);

client.setCallback(callback);


server.on("/", handleRoot);

server.on("/save", HTTP_POST, handleSave);

server.begin();

}


/* ========================================================= */

/* ======================= LOOP ============================ */

/* ========================================================= */

void loop() {

if (WiFi.status() == WL_CONNECTED) {

if (!client.connected()) reconnectMQTT();

client.loop();

}

server.handleClient();

}


Check Video on You Tube

https://www.youtube.com/watch?v=XJYoUYmgw88

All the Details