One line of code · 10 of 20

First light

Install one library, change one constant, and the board runs its own self-test: solid colours, a backlight sweep and its identity printed to serial. What each stage of that proves is the part worth knowing, and what a clean serial log does not.

Four things happen before a picture

Power to picture
4 stages
Stage
—
Pad in use
—
Pads needed
7 of 8
A dark screen is not one fault, it is four possible ones. The board writes to the panel and never reads back, so no stage can report that it failed. A screen that stays dark has most likely never had its lamp driven; one that is lit and white or noisy has power and a lamp and lost a reset, DC or the data; one that is lit and shows what you drew has passed all four.

Run it. The screen is dark for as long as the lamp is off, and on these boards the lamp is off until the sketch drives BL. The library does that as the last step of begin().

Knowing that order is what turns a dead screen into a question you can answer. A screen that was never lit has not told you anything about the other three stages. One that is lit and white or noisy has power, ground and a lamp, and lost a reset, DC or the data.

The sketch

Install Lonely Binary Display from the Arduino Library Manager. It pulls in Lonely Binary GFX, the drawing library, as a dependency. Then pick your board in Tools ▸ Board and upload.

The panel constant is the only line to change between boards. The pins are not in the sketch at all; the library takes them from the board you selected, and you draw on display itself.

Read the serial log before you touch anything

Two calls in that sketch are there for the moment it does not work.

begin() returns false if the SPI bus cannot be set up. It cannot return false for a wiring fault, because the board is only ever written to and there is no reply to check. A true is not evidence that the panel heard anything.

printInfo() prints what the library thinks it is driving: the panel, the driver chip, the colour order, the backlight polarity, and the GPIO each signal is actually on, marked as custom if you overrode them. A wiring mistake that would otherwise be a blank screen becomes a line of text that is obviously wrong.

What the self-test proves

selfTest() fills the screen with red, green and blue in turn with the name printed on each, sweeps the backlight down and up over a white screen, and finishes on a page of colour bars with the panel's name and size.

The names on the solid screens are the point. An unlabelled bar cannot tell you whether red is coming out red, which is how a colour-order mistake survived in this library's own panel table for a long time, and why the colour article is in this book.

If the sweep dims and brightens, the backlight is wired the way the table thinks it is. If it runs backwards, you have found something worth reporting. If it does not move at all, the library has no backlight pin to write: check printInfo() for "not driven".

The code

tft_self_test.ino

The library's own self-test, with the panel constant on the line it belongs on. Change that one token to run the same sketch on any of the six boards.

// First light: bring a Lonely Binary SPI display board up and run its self-test.
//
// Wiring, using the cable: one 15-way, 1.0 mm FPC cable from U31 on the
// board to a socket of the same kind on your breakout. Contacts down: the
// board prints PINS FACE DOWN beside U31. Nothing else to connect.
//
// Wiring, using the row of holes instead (8 wires, ESP32-S3 defaults shown):
//   display 3V3  -> ESP32-S3 3V3       (3.3 V only, never 5V)
//   display GND  -> ESP32-S3 GND
//   display SCL  -> ESP32-S3 GPIO12    (SPI clock; the hole says SCL)
//   display MOSI -> ESP32-S3 GPIO11
//   display DC   -> ESP32-S3 GPIO2
//   display RST  -> ESP32-S3 GPIO42
//   display CS   -> ESP32-S3 GPIO10
//   display BL   -> ESP32-S3 GPIO41    (the lamp stays off until BL is driven)
//
// On a classic ESP32 the same eight wires go to GPIO 18, 23, 2, 4, 15 and
// 32 for SCL, MOSI, DC, RST, CS and BL, and the library picks that set for
// you from the board you choose below. You do not edit anything.
//
// Arduino IDE: Tools > Board > esp32 > "ESP32S3 Dev Module" for an
// ESP32-S3, or "ESP32 Dev Module" for a classic ESP32. Tools > Port, pick
// the port. On an S3, Tools > USB CDC On Boot > Enabled so Serial reaches
// the monitor. Library: "Lonely Binary Display" from Tools > Manage
// Libraries, which pulls in "Lonely Binary GFX" with it.

#include <LonelyBinaryDisplay.h>

// The only line that changes between the six boards:
//   LB_TFT_096  LB_TFT_18  LB_TFT_20  LB_TFT_24  LB_TFT_28  LB_TFT_35
LB_Display display(LB_TFT_24);

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

  if (!display.begin()) {
    Serial.println("The SPI bus did not start.");
    return;
  }

  // Pins actually in use, panel identity, colour order, backlight polarity.
  display.printInfo();

  // Solid colours, a backlight sweep, and a colour-bar page with the name.
  display.selfTest();

  // Anything after this is yours. Draw on `display`, then flush().
  display.fillScreen(LB_BLACK);
  display.setTextColor(LB_WHITE);
  display.setTextSize(2);
  display.drawString("Hello", 10, 10);
  display.flush();
}

void loop() {
  delay(1000);
}

begin() brings up the SPI bus, resets and initialises the panel and switches the lamp on at full. It returns false only if the bus cannot start, because nothing is read back from the panel. printInfo() then names the pins actually in use, including any you overrode, so a mis-wired board shows up as a line of text rather than as a blank screen.

When it does not work

The sketch will not compile: no LonelyBinaryDisplay.h

The library is not installed. Tools > Manage Libraries, search for Lonely Binary Display, install it, and accept the prompt to install Lonely Binary GFX with it, which is the drawing library it depends on. The Examples menu only picks the new entry up after the install finishes.

It compiles, uploads, and the screen stays dark

Open the serial monitor at 115200 and read printInfo() first. A dark screen with a clean log is nearly always the backlight: the board holds the lamp off until BL is driven, so check BL is wired to the pin the log lists, or bridge the BL solder jumper and set the backlight pin to -1. Tilt the screen under a lamp: if the picture is there, that was it.

begin() returned true and nothing is drawn

That is expected for a wiring fault. The board only writes to the panel and never reads back, so begin() cannot tell whether the controller heard anything. It returns false only if the SPI bus itself would not start. Use printInfo() to confirm the pins, then check DC, RST and CS.

Serial prints nothing at all

Either the monitor is at the wrong baud rate (the sketch opens at 115200) or the board is not the one you selected. On an ESP32-S3 with native USB you may also need Tools > USB CDC On Boot enabled before anything the sketch prints reaches the monitor.

The colours in the self-test look wrong

That is what the self-test is for. The solid screens print their own names, so you can see whether RED is coming out red. If it is not, the fix is one call and the symptom tells you which: see the article on colours in this book rather than rewiring anything.

Where this goes next

Two bytes a pixel at a known clock is a number, and on the 3.5 inch it is a number you can see.

How long a redraw takes →

Edit this page — content/books/lcd/first-light.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

This page covers several products. Choose yours to see the right discussions.

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum →