Your Business
Your Business
  • Home
  • Arduino Projects
    • List of projects
    • Traffic lights
    • Ir Car
    • LCD
    • Led remote control
    • Ultrasonic Detector
  • ESP 32 Projects
    • ESP32 & 1.28 display
  • Altro
    • Home
    • Arduino Projects
      • List of projects
      • Traffic lights
      • Ir Car
      • LCD
      • Led remote control
      • Ultrasonic Detector
    • ESP 32 Projects
      • ESP32 & 1.28 display
  • Home
  • Arduino Projects
    • List of projects
    • Traffic lights
    • Ir Car
    • LCD
    • Led remote control
    • Ultrasonic Detector
  • ESP 32 Projects
    • ESP32 & 1.28 display

Wi‑Fi Text Badge with ESP32 & 1.28″ Round GC9A01 TFT

Turn your GC9A01 round display into a wireless, three‑line b

 

  • Build time: ~15 min wiring  |  ~3 min flashed sketch
  • Cost: under €15 (ESP32 DevKit + TFT)  |  no level‑shifters required
  • What you get: an ESP32 hosts its own WPA2 access‑point, serves a simple textarea form, and auto‑wraps up to 96 chars onto the 240 × 240 round screen in yellow text.

Bill of Materials

  •  1 ESP32 DevKit v1Any WROOM‑32, 3 V3 logic. 
  •  1 1.28″ GC9A01 round TFT240 × 240 px, SPI interface. 
  • 7/ 8 Jumper wires F‑F / M‑MColour‑code for filming! 

Wiring (ESP32 ⇄ GC9A01)

     ESP 32                  DISPLAY

       3V                           VCC

     GND                        GND

     P18                           SCL

    P23                           SDA

    P16                            DC

    P22                            CS

     P8                            RST


Firmware

Library & board setup

  1. Open Arduino IDE ≥2.3 → Board Manager → search esp32 → install Espressif 32.
  2. Library Manager → install TFT_eSPI by Bodmer.
  3. Documents/Arduino/libraries/TFT_eSPI/User_Setup_Select.h → un‑comment:#include <User_Setups/Setup200_GC9A01.h>
  4. Edit Setup200_GC9A01.h pin‑map & SPI speed:

 

#include <WiFi.h>
#include <WebServer.h>
#include <TFT_eSPI.h>

/*──────────  Access-Point config  ─────────*/
const char* AP_SSID     = "GC9A01_Display";
const char* AP_PASS     = "GC9A01_2025";
const IPAddress AP_IP (192,168,4,1);
const IPAddress AP_MASK (255,255,255,0);
/*──────────────────────────────────────────*/

TFT_eSPI  tft = TFT_eSPI();
WebServer server(80);

String lastText = "Hello!";

/*──────────── HTML page (PROGMEM) ─────────*/
const char INDEX_HTML[] PROGMEM = R"rawliteral(
<!DOCTYPE html><html lang="it"><meta charset="utf-8">
<title>CircleCast Badge</title>
<style>
 body{background:#111;color:#eee;font-family:sans-serif;text-align:center;padding-top:60px}
 textarea{width:72%;max-width:400px;font-size:1.2rem;padding:10px;border-radius:6px;border:none;resize:vertical}
 button{padding:10px 18px;font-size:1.1rem;border:none;border-radius:6px;color:#fff;background:#03a9f4;margin-top:8px}
 .card{background:#222;padding:30px;border-radius:12px;width:80%;max-width:500px;margin:auto;box-shadow:0 0 20px #000}
</style>
<div class="card">
 <h2>Send your message</h2>
 <form action="/send" method="POST">
  <textarea name="msg" rows="3" maxlength="96" placeholder="Write Here..." autofocus required></textarea><br>
  <button>SEND</button>
 </form>
 <p>Previous Text:</p><pre style="white-space:pre-wrap;">%TEXT%</pre>
</div></html>)rawliteral";

/*──────── Text auto-wrap & draw ───────*/
void drawWrappedText(const String &raw)
{
tft.fillScreen(TFT_BLACK);                     // clear screen
tft.setTextDatum(MC_DATUM);
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
const int16_t lineH = tft.fontHeight(4) + 4;

  String lines[3];
int line = 0;  String word, acc;
for (uint16_t i = 0; i <= raw.length(); ++i) {
char c = (i < raw.length()) ? raw[i] : ' ';
if (c == ' ' || c == '\n') {
if (acc.length()==0 && c==' ') continue;
      word = acc;  acc = "";
if (tft.textWidth(lines[line] + word + ' ', 4) > 220) {
if (++line == 3) break;                 // max 3 lines
}
lines[line] += word + ' ';
} else acc += c;
}

int16_t startY = 120 - (line * lineH) / 2;     // vertical centring
for (int i = 0; i <= line; ++i)
tft.drawString(lines[i], 120, startY + i * lineH, 4);
}

/*──────── HTTP handlers ───────────────*/
void handleRoot() {
static char html[950];
strncpy_P(html, INDEX_HTML, sizeof(html));
html[sizeof(html)-1] = '\0';

char* p = strstr(html, "%TEXT%");
if (p) {
size_t tail = strlen(p + 6);
size_t need = p - html + lastText.length() + tail;
if (need < sizeof(html)-1) {
memmove(p + lastText.length(), p + 6, tail + 1);
memcpy(p, lastText.c_str(), lastText.length());
}
}
server.send(200, "text/html", html);
}

void handleSend() {
if (server.hasArg("msg")) {
    lastText = server.arg("msg").substring(0, 96);
lastText.replace("\r", "");
drawWrappedText(lastText);
}
server.sendHeader("Location", "/");
server.send(303);
}

/*────────────  SETUP  ─────────────*/
void setup() {
Serial.begin(115200);

tft.init();
tft.setRotation(0);
drawWrappedText(lastText);

WiFi.mode(WIFI_AP);
WiFi.softAPConfig(AP_IP, AP_IP, AP_MASK);
WiFi.softAP(AP_SSID, AP_PASS);
Serial.printf("\nAP \"%s\" pronto  →  http://%s/\n",
                AP_SSID, WiFi.softAPIP().toString().c_str());

server.on("/",     HTTP_GET,  handleRoot);
server.on("/send", HTTP_POST, handleSend);
server.begin();
}

/*────────────  LOOP  ──────────────*/
void loop() {
server.handleClient();
}

Using the badge

 

  1. Connect your phone to GC9A01_Display (password GC9A01_2025).
  2. Browse to 192.168.4.1.
  3. Type a message (max 96 chars) → SEND → watch it appear, word‑wrapped, in yellow.

Hardening checklist

 

  • Change the default SSID & password before field‑use.
  • Disable the AP (WiFi.mode(WIFI_STA)) and push text over HTTPS when integrating in a larger project.
  • Consider OTA via arduino‑esp32 v3.0 but always flash over USB first.

Resources

 

  • GitHub repo: https://github.com/Alex3dWorks/gc9a01-wifi-badge
  • TFT_eSPI docs: https://github.com/Bodmer/TFT_eSPI


Copyright © 2025 Alex3dworks - All rights reserved

Gestito da

  • Politica sulla privacy

Questo sito web usa cookie.

Utilizziamo i cookie per analizzare il traffico sul sito web e ottimizzare l'esperienza con il tuo sito. Accettando l'uso dei cookie da parte nostra, i tuoi dati saranno aggregati con i dati di tutti gli altri utenti.

RifiutaAccetta