Stranger Things Wall Lights Esp

by LashaG in Circuits > LEDs

37 Views, 0 Favorites, 0 Comments

Stranger Things Wall Lights Esp

სტ.png

Remember the iconic scene from Stranger Things where Joyce Byers sets up a wall of Christmas lights and alphabet letters to communicate with Will (and later Eleven) from the Upside Down? The lights flicker on and off, illuminating specific letters one by one to spell out messages. That simple but powerful visual—part mystery, part desperate ingenuity, part pure 80s nostalgia—has stuck with fans ever since.

This project is my Georgian version of that famous wall. Instead of the Latin alphabet, I built it using the Georgian alphabet (ქართული ანბანი), with each letter paired with WS2812B addressable RGB LEDs controlled by an ESP32. The result is a glowing wall that can light up individual Georgian letters to spell words, display messages, or recreate the classic “Will is here” style communication—but in Georgian.

Supplies

fasfaf.png

Electronics

  1. ESP32 development board
  2. WS2812B addressable LED strip (or individual LEDs)
  3. 300 Ω resistors (one per data line / recommended between ESP32 and the first LED)
  4. Hook-up wire / multi-conductor wire

3D Printed Parts

  1. Custom 3D printed letter holders / mounts (designed for the Georgian alphabet)

Tools

  1. Ts101 soldering iron (or any soldering iron)
  2. Solder
  3. Wire cutters / strippers
  4. Computer (for programming the ESP32)

Optional / Recommended

  1. Power supply suitable for the total number of WS2812B LEDs
  2. Hot glue or double-sided tape (for mounting the letters on the wall)
  3. Capacitor (1000 µF) across the LED power rails (good practice with WS2812B)

Q

Screenshot_270.png

Before building the physical wall, I started with a simulation in Tinkercad to test the concept and the code.

You can check out the simulation here:

Stranger Things – Tinkercad

In this first experiment I used the Adafruit NeoPixel library (not FastLED) to control the LEDs. The simulation helped me:

  1. Test how individual letters light up
  2. Try different timing and animation styles
  3. Confirm the basic logic for spelling words with the Georgian alphabet

This was just a proof of concept. In the real build I switched to FastLED for better performance and more control, but the Tinkercad version was a useful starting point to understand the idea and get the first working version of the code.

Make the Wiring Diagram

Screenshot_271.png


Before connecting anything, I made a simple wiring diagram so I wouldn’t get confused later.

The basic connections are:

  1. ESP32 / Arduino → WS2812B
  2. 5V → 5V (or external 5V power supply if you have many LEDs)
  3. GND → GND
  4. Data pin (e.g. GPIO 5) → Data In of the first LED (through a 300 Ω resistor)
  5. or Arduino Uno/nano (pin 9)
  6. Each letter has its own LED (or small group of LEDs)
  7. All grounds are connected together
  8. Power is shared between the ESP32 and the LED strip


Test the LEDs With the FastLED Library


In this step we’ll move from the Tinkercad simulation to the real hardware and use the FastLED library (which we’ll also use later in the full project).

1. Install the FastLED Library

  1. Open the Arduino IDE.
  2. Go to Sketch → Include Library → Manage Libraries…
  3. In the Library Manager search box, type: FastLED
  4. Find FastLED by Daniel Garcia in the results.
  5. Click Install.
  6. Wait until the installation finishes. You should see “INSTALLED” next to the library.

(Optional) You can also install it manually by downloading the library from GitHub and adding it via Sketch → Include Library → Add .ZIP Library…

2. Wiring (Arduino Uno)

  1. WS2812B 5V → Arduino 5V
  2. WS2812B GND → Arduino GND
  3. WS2812B Data In → Arduino Pin 9 (through a 300 Ω resistor)

3. Simple FastLED Test Code

Upload this sketch to check that the LEDs work with FastLED:

#include <FastLED.h>

#define LED_PIN 9
#define NUM_LEDS 10
#define BRIGHTNESS 50

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}

void loop() {
// Red
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.show();
delay(1000);

// Green
fill_solid(leds, NUM_LEDS, CRGB::Green);
FastLED.show();
delay(1000);

// Blue
fill_solid(leds, NUM_LEDS, CRGB::Blue);
FastLED.show();
delay(1000);

// Off
FastLED.clear();
FastLED.show();
delay(500);
}

Test Lighting Each Letter Using Serial Monitor

In this step we test controlling individual letters by typing them in the Arduino Serial Monitor.

I’m using an Arduino Nano, pin 9, and 26 LEDs (A–Z). In my setup LED 26 = A.

Wiring

  1. WS2812B Data In → Pin 9 (through 300 Ω resistor)
  2. 5V and GND connected as usual

Code

#include <FastLED.h>

#define LED_PIN 9
#define NUM_LEDS 26
#define BRIGHTNESS 40

CRGB leds[NUM_LEDS];

// Change these numbers to match your real LED positions
const int letterToLed[26] = {
5, 12, 0, 8, 3, 19, 7, 14, 1, 22,
9, 4, 16, 11, 25, 2, 18, 6, 21, 10,
15, 23, 13, 20, 17, 24
};

// ---- Delay settings (change these) ----
int letterDelay = 400; // how long a letter stays on (ms)
int doubleDelay = 250; // extra off time for double letters (ms)
int spaceDelay = 600; // pause for space (ms)

char lastLetter = 0;

void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
FastLED.show();

Serial.println("Type a word and press Enter");
Serial.println("Example: HELLO");
}

void loop() {
if (Serial.available()) {
char letter = Serial.read();
letter = toupper(letter);

// Ignore Enter / new line
if (letter == '\n' || letter == '\r') return;

// Space
if (letter == ' ') {
FastLED.clear();
FastLED.show();
delay(spaceDelay);
lastLetter = ' ';
return;
}

// Only A-Z
if (letter >= 'A' && letter <= 'Z') {
int index = letter - 'A';
int ledNumber = letterToLed[index];

// If same letter as previous one → turn off first
if (letter == lastLetter) {
FastLED.clear();
FastLED.show();
delay(doubleDelay);
}

// Light the letter
FastLED.clear();
leds[ledNumber] = CRGB::White;
FastLED.show();

delay(letterDelay);

lastLetter = letter;
}
}
}

3D Print Lamps

Screenshot_275.png

you can download STL files for lamps from here

Soldering Each Led

Screenshot_273.png
PXL_20261018_153914636.jpg
PXL_20261018_153845142.jpg
PXL_20261004_171916568.jpg
Screenshot_274.png

Cut Out a Letters

Screenshot_276.png

Put Everithing on the Wall

სტ.png

on tinkercad simulations letters and numbers of leds was following number one led Was A and so on, but if you look at the pitures leters are on top of each user but not led strip is changng direction so for example led will not be G and will be N and so on . so in the cao there is an araay where will be asighned each led to number of led


This code is for Georgian letters 33 letters

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

// ---------- Access Point ----------
const char* ap_ssid = "ESP32-LED";

// ---------- LEDs ----------
#define LED_PIN 27
#define NUM_LEDS 33
#define BRIGHTNESS 200
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB

#define LETTER_TIME 500
#define SPACE_TIME 1500
#define REPEAT_GAP 250

CRGB leds[NUM_LEDS];
WebServer server(80);

String message = "";
bool newMessage = false;

// ---------- Mapping: input character -> LED index ----------
// Edit both arrays together. Case-sensitive.
// Georgian order: ა ბ გ დ ე ვ ზ თ ი კ ლ მ ნ ო პ ჟ რ ს ტ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ ჯ ჰ
const char inputChars[] = {
'a','b','g','d','e','v','z','t','i','k','l','m','n','o','p',
'j','r','s','T','u','f','q','G','y','S','c','C','w','W','x','X','h'
};
const int ledForChar[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 31, 32
// note: both 'x' and 'X' map to LED 31 (ჯ)
};
const int MAP_SIZE = sizeof(inputChars) / sizeof(inputChars[0]);

void setup() {
Serial.begin(115200);
delay(1000);

FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear(true);

WiFi.mode(WIFI_AP);
WiFi.softAP(ap_ssid);
Serial.println("AP started");
Serial.print("Connect to: ");
Serial.println(ap_ssid);
Serial.print("Then open: http://");
Serial.println(WiFi.softAPIP());

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

void loop() {
server.handleClient();

if (newMessage) {
showText(message);
message = "";
newMessage = false;
}
}

void handleRoot() {
String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LED Keyboard</title>
<style>
body { font-family: Arial; text-align: center; margin-top: 40px; }
input { font-size: 24px; padding: 10px; width: 80%; max-width: 400px; }
button { font-size: 22px; padding: 10px 30px; margin-top: 15px; }
</style>
</head>
<body>
<h2>Type a word</h2>
<form action="/send" method="GET">
<input type="text" name="text" placeholder="Type here" autofocus>
<br>
<button type="submit">Send</button>
</form>
</body>
</html>
)rawliteral";
server.send(200, "text/html", html);
}

void handleSend() {
if (server.hasArg("text")) {
message = server.arg("text");
message.trim();
newMessage = true;
Serial.print("Received: ");
Serial.println(message);
}
server.sendHeader("Location", "/");
server.send(303);
}

int findLed(char c) {
for (int i = 0; i < MAP_SIZE; i++) {
if (inputChars[i] == c) return ledForChar[i];
}
return -1;
}

void showText(String text) {
char last = 0;

for (unsigned i = 0; i < text.length(); i++) {
char c = text[i];

if (c == ' ') {
FastLED.clear(true);
delay(SPACE_TIME);
last = 0;
continue;
}

int led = findLed(c);
if (led < 0 || led >= NUM_LEDS) continue;

if (c == last) {
FastLED.clear(true);
delay(REPEAT_GAP);
}

FastLED.clear();
leds[led] = CRGB::Green;
FastLED.show();
delay(LETTER_TIME);
FastLED.clear(true);
last = c;
}
}