A compact ESP-12F–based controller board designed to drive an 8×8 LED panel with an onboard buzzer, stable power regulation, and reliable programming support.
Click or drag to draw • Shows 32×8 LED panel
This project reached completion thanks to the support of PCBWay, who provided fabrication assistance that transformed the prototype into a clean, reliable PCB. Their contribution directly improved electrical stability, mechanical reliability, assembly clarity, and long-term maintainability.
From fragile prototype to professional PCB — see the dramatic improvement in quality and reliability.
The initial version worked, but the wiring was messy, fragile, and difficult to debug. It served its purpose for early validation, but was not suitable for repeated use.
The final PCB was fabricated by PCBWay, making the design stable, durable, and easy to assemble. The board programs correctly and drives the LED panel exactly as intended.
The ESP-12F can be programmed directly through a USB-to-serial adapter such as an FTDI module. The board includes a dedicated programming header, making the upload process reliable and repeatable.
Click each step to mark as complete
The board integrates an ESP-12F module, 5V to 3.3V regulation, LED panel connector, buzzer with mute control, and a dedicated programming header.
WiFi-enabled microcontroller with 4MB flash, perfect for IoT applications.
Stable 5V to 3.3V conversion with clean power delivery to all components.
Onboard buzzer with physical mute button for audio alerts and notifications.
Click to view full size
Optimized firmware with PROGMEM strings, WiFi reconnection, debounced mute, and configurable intervals.
Click a section to highlight in code →
Timing constants, pin definitions, PROGMEM strings, and state struct.
Lines 1-45BearSSL HTTPS requests, WiFi reconnection handling.
Lines 47-85Pin setup, display init, WiFi connection with timeout.
Lines 87-115Debounced mute toggle, periodic checks, status display.
Lines 117-155 1 // LED-Panel-ESP12F - Optimized Firmware v2.0
2 #include <ESP8266WiFi.h>
3 #include <ESP8266HTTPClient.h>
4 #include <WiFiClientSecureBearSSL.h>
5 #include <MD_Parola.h>
6 #include "config.h"
7
8 // ============== Configuration ==============
9 #define HARDWARE_TYPE MD_MAX72XX::FC16_HW
10 #define MAX_DEVICES 4
11 #define CS_PIN 12
12 #define BUZZ_PIN 4
13 #define MUTE_PIN 5
14
15 // Timing constants (milliseconds)
16 constexpr uint32_t CHECK_INTERVAL = 30000;
17 constexpr uint32_t WIFI_TIMEOUT = 15000;
18 constexpr uint32_t HTTP_TIMEOUT = 5000;
19 constexpr uint32_t DEBOUNCE_DELAY = 200;
20
21 // PROGMEM Strings (saves RAM)
22 const char MSG_WIFI_OK[] PROGMEM = "WiFi OK";
23 const char MSG_WIFI_ERR[] PROGMEM = "WiFi Err";
24 const char MSG_PING[] PROGMEM = "Pinging...";
25 const char MSG_SITE_UP[] PROGMEM = "All Good!";
26 const char MSG_SITE_DOWN[] PROGMEM = "SITE DOWN!";
27 const char MSG_MUTED[] PROGMEM = "Muted";
28 const char MSG_UNMUTED[] PROGMEM = "Sound On";
29
30 MD_Parola display = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
31
32 // State management
33 struct State {
34 bool isMuted = false;
35 bool siteIsUp = true;
36 bool wifiConnected = false;
37 uint32_t lastCheckTime = 0;
38 uint32_t lastButtonPress = 0;
39 } state;
40
41 volatile bool muteToggleRequest = false;
42 char msgBuffer[32];
43
44 void IRAM_ATTR onMuteButtonPress() {
45 muteToggleRequest = true;
46 }
47
48 // ============== Site Check ==============
49 bool checkSiteStatus() {
50 std::unique_ptr<BearSSL::WiFiClientSecure> client(
51 new BearSSL::WiFiClientSecure);
52 client->setInsecure();
53
54 HTTPClient http;
55 http.setTimeout(HTTP_TIMEOUT);
56 http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
57
58 if (!http.begin(*client, SITE_URL))
59 return false;
60
61 http.addHeader("User-Agent", "ESP8266-Monitor/2.0");
62 int httpCode = http.GET();
63 http.end();
64
65 return (httpCode > 0 && httpCode < 500);
66 }
67
68 // ============== WiFi Management ==============
69 bool connectWiFi() {
70 WiFi.begin(SECRET_SSID, SECRET_PASS);
71 uint32_t start = millis();
72
73 while (WiFi.status() != WL_CONNECTED) {
74 if (millis() - start >= WIFI_TIMEOUT)
75 return false;
76 delay(100);
77 display.displayAnimate();
78 }
79 return true;
80 }
81
82 void updateDisplay(const char* msg) {
83 strcpy_P(msgBuffer, msg);
84 display.displayText(msgBuffer, PA_CENTER, 40, 0,
85 PA_SCROLL_LEFT, PA_SCROLL_LEFT);
86 }
87
88 // ============== Setup ==============
89 void setup() {
90 pinMode(BUZZ_PIN, OUTPUT);
91 pinMode(MUTE_PIN, INPUT_PULLUP);
92 attachInterrupt(digitalPinToInterrupt(MUTE_PIN),
93 onMuteButtonPress, FALLING);
94
95 display.begin();
96 display.setIntensity(2);
97 display.displayClear();
98
99 WiFi.mode(WIFI_STA);
100 WiFi.setAutoReconnect(true);
101 WiFi.persistent(false); // Reduce flash wear
102
103 updateDisplay(MSG_WIFI_CONNECTING);
104 state.wifiConnected = connectWiFi();
105
106 if (state.wifiConnected) {
107 updateDisplay(MSG_WIFI_OK);
108 } else {
109 updateDisplay(MSG_WIFI_ERR);
110 tone(BUZZ_PIN, 2000);
111 delay(1000);
112 noTone(BUZZ_PIN);
113 }
114 state.lastCheckTime = millis() - CHECK_INTERVAL + 5000;
115 }
116
117 // ============== Main Loop ==============
118 void loop() {
119 display.displayAnimate();
120
121 // Debounced mute toggle
122 if (muteToggleRequest) {
123 uint32_t now = millis();
124 if (now - state.lastButtonPress >= DEBOUNCE_DELAY) {
125 state.lastButtonPress = now;
126 state.isMuted = !state.isMuted;
127 if (state.isMuted) {
128 noTone(BUZZ_PIN);
129 updateDisplay(MSG_MUTED);
130 } else {
131 updateDisplay(MSG_UNMUTED);
132 tone(BUZZ_PIN, 1000, 100); // Confirm beep
133 }
134 }
135 muteToggleRequest = false;
136 }
137
138 // Periodic site check
139 uint32_t now = millis();
140 if (state.wifiConnected &&
141 (now - state.lastCheckTime >= CHECK_INTERVAL)) {
142 state.lastCheckTime = now;
143
144 updateDisplay(MSG_PING);
145 bool isUp = checkSiteStatus();
146 state.siteIsUp = isUp;
147
148 updateDisplay(isUp ? MSG_SITE_UP : MSG_SITE_DOWN);
149
150 if (!isUp && !state.isMuted)
151 tone(BUZZ_PIN, 2000);
152 else
153 noTone(BUZZ_PIN);
154 }
155 }
Complete list of components needed to build the LED-Panel-ESP12F.
| Reference | Qty | Value | Footprint |
|---|---|---|---|
| U1 | 1 | ESP-12F | RF_Module:ESP-12E |
| U2 | 1 | AMS1117-3.3 | SOT-223-3 |
| BZ1 | 1 | Buzzer | MagneticBuzzer |
| C1, C2 | 2 | 100µF | Radial D7.5mm |
| C3 | 1 | 0.1µF | Disc D7.0mm |
| R1, R2, R6 | 3 | 10kΩ | SMD 1206 |
| R3, R4 | 2 | 5.1kΩ | SMD 1206 |
| R5 | 1 | 100Ω | SMD 1206 |
| SW1, SW2, SW3 | 3 | RESET / BOOT / MUTE | SMD Push Button |
| J1 | 1 | USB-C Power | JST XH 4-pin |
| J2 | 1 | LED Panel | JST XH 5-pin |
| J3 | 1 | Programming Header | Pin Header 1x06 |