Small plastic project enclosure with a 0.96 inch OLED display showing home status icons, mounted near an entryway

Beginner

Build a Home Status Display

DisplaysIoT

A small screen that always shows the one thing you care about — build your own flexible status board and decide what it tracks.

6 real parts included

Total for this kit: 1,569.00 ฿

Doesn't include any order discount you may get at checkout.

What you'll need

Project Goal

This project builds a small, flexible status display: a screen that always shows the one thing you care about right now. The hardware is intentionally simple — a controller and a screen — because the real design work happens in your own code, in the decision you make about what "status" means and how it should be drawn. Once built, this same physical setup can be repurposed for dozens of different status ideas just by changing the logic that feeds it.

What the Controller Does

The ESP32-C3 is the brain of the build. Its only real job is to take whatever "status" value it currently holds and decide what to draw on the display in response — an icon, a word, a number, or a simple shape. That status value can come from anywhere you choose: a sensor reading left over from another project, a value you toggle manually while testing, or, once you are comfortable with the board, a value fetched over Wi-Fi from a simple web request you write yourself. The controller doesn't care where the value came from — it only cares about the mapping between that value and what appears on screen.

What the Display Does

The 0.96" OLED has no logic of its own — it is a dumb output device that draws exactly what it is told and nothing more. This is an important thing to internalize early: all of the "intelligence" of this project lives in the controller's code, not in the screen. The real design work in a project like this is deciding the mapping between input states and what actually gets shown, since the display will faithfully render whatever that mapping produces, correct or not.

Wiring the OLED Over I2C

This particular OLED communicates over I2C, a two-wire bus (SDA for data, SCL for clock) that lets multiple devices share the same two pins by each responding to their own address. On a breadboard, that means only four connections are needed: power, ground, SDA, and SCL. Because I2C is a shared bus, any future sensor you add later must use a different I2C address than the display, or the two devices will collide when the controller tries to talk to them. Keep power and ground wiring solid on the breadboard rails — a loose ground connection is one of the most common causes of a display that flickers or stops responding intermittently.

Software and Library Concepts

The typical structure for this build is a simple loop: read the current status value, decide what should be shown for that value, clear the display buffer, draw the new content, and push it to the screen — then repeat. A standard OLED display library (such as one built around the SSD1306 driver this class of display commonly uses) handles the low-level pixel and text drawing so your code only has to decide what to draw, not how. The mapping between status values and screen content is best kept as a single, clearly organized lookup rather than scattered across the code, since that mapping is the part you'll most often want to change or extend. The ESP32-C3's built-in Wi-Fi is not used in this base build, but it is what makes this same project a natural starting point for a future upgrade where the status value comes from the network instead of a fixed or manually-set value.

Testing and Troubleshooting

  • Display stays blank — check the same I2C wiring basics as any OLED-based build: power and ground reaching the display, the I2C address in code matching the display's actual address, and no conflict with another device sharing the same I2C bus.
  • The shown status never changes — confirm the code loop actually re-checks the status value and redraws each pass, rather than drawing once when the board boots and then stopping.
  • Wrong icon or text appears for a given state — check the mapping logic between your input value and what gets displayed; a single misordered condition is the most common cause.
  • Display shows garbled or overlapping graphics — make sure the code clears the display buffer before drawing new content each cycle, rather than drawing new content on top of the old.

Optional Future Upgrade: Wi-Fi-Connected Status

The ESP32-C3's built-in Wi-Fi radio is not used by the base build, but it is the natural next step once the display and mapping logic are working reliably. A future version could connect to your Wi-Fi network and periodically fetch a value from a simple web request you write and host yourself, replacing the manually-set or sensor-fed status value with a live one. This keeps the hardware and display logic completely unchanged — only the source of the status value changes.

Wiring

  • OLED VCC → ESP32-C3 SuperMini 3.3V
  • OLED GND → ESP32-C3 SuperMini GND
  • OLED SDA → ESP32-C3 SuperMini GPIO8 — I2C data (default)
  • OLED SCL → ESP32-C3 SuperMini GPIO9 — I2C clock (default)

There's no sensor in this build's parts list, so the code below is a genuine, runnable template: it connects to Wi-Fi using the ESP32-C3's built-in radio and shows real connection status (`WiFi.status()`, SSID, IP address) rather than a fabricated cloud integration, then cycles through an example array of "status" lines you're meant to replace with whatever you actually want displayed (open/closed states, reminders, counters, etc.). Wire your own future data (another sensor, a button, a value pulled from your own server) into the `statusLines` logic once you decide what "home status" means for your setup.

Wiring Diagram

VCC → 3.3V GND SDA → GPIO8 SCL → GPIO9 ESP32-C3 SuperMini OLED

Starter Code

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>

#define SDA_PIN 8
#define SCL_PIN 9

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C

// Replace with your own network credentials
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Example status lines — swap these for whatever you actually want to show
const char* statusLines[] = {
  "All Systems Normal",
  "Front Door: Closed",
  "Last Check: OK"
};
const int NUM_STATUS_LINES = 3;
int currentLine = 0;
unsigned long lastSwitch = 0;
const unsigned long SWITCH_INTERVAL_MS = 3000;

void showConnecting() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Connecting to WiFi...");
  display.display();
}

void showStatusScreen() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);

  if (WiFi.status() == WL_CONNECTED) {
    display.println(WiFi.SSID());
    display.println(WiFi.localIP());
  } else {
    display.println("WiFi: disconnected");
  }

  display.drawLine(0, 18, SCREEN_WIDTH, 18, SSD1306_WHITE);

  display.setTextSize(1);
  display.setCursor(0, 28);
  display.println(statusLines[currentLine]);

  display.display();
}

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA_PIN, SCL_PIN);

  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
    Serial.println("OLED not found — check wiring.");
    while (1) delay(1000);
  }

  showConnecting();
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  unsigned long startAttempt = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - startAttempt < 15000) {
    delay(500);
  }

  showStatusScreen();
}

void loop() {
  if (millis() - lastSwitch > SWITCH_INTERVAL_MS) {
    lastSwitch = millis();
    currentLine = (currentLine + 1) % NUM_STATUS_LINES;
    showStatusScreen();
  }
}

Not sure about a step? Ask us