Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Compile error · pins

Fix “'D4' was not declared in this scope” (and LED_BUILTIN) on ESP32

D-pin names belong to NodeMCU/Wemos ESP8266 boards. On an ESP32 DevKit use the GPIO number — and define the LED pin yourself, since LED_BUILTIN is missing.

ESP32ESP32-S3ESP32-C3Updated 3 Nov 2026

Community draft — report a mistake

What you see

OutputOutput
Blink.ino: In function 'void setup()':
Blink.ino:2:11: error: 'D4' was not declared in this scope; did you mean 'T4'?
    2 |   pinMode(D4, OUTPUT);
      |           ^~
      |           T4
exit status 1

Compilation error: 'D4' was not declared in this scope; did you mean 'T4'?

D4, D5 and friends are constants defined by the ESP8266 NodeMCU and Wemos board packages to match the labels on those boards. The generic ESP32 board definition doesn’t have them, so code copied from an ESP8266 tutorial fails on its first pin name.

const int LED = 2;      // DevKit V1 blue LED (GPIO2)
const int RELAY = 4;    // pin labelled D4 / G4 on the ESP32 DevKit

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(RELAY, OUTPUT);
}

Quick fix — try in order

  1. 1

    Use the GPIO number

    On an ESP32 DevKit the header labels are GPIO numbers: the pin marked D4 or G4 is 4. Write pinMode(4, OUTPUT).

  2. 2

    Porting NodeMCU code? Translate the pins

    NodeMCU D4 = GPIO2, D1 = GPIO5, D2 = GPIO4. Don’t copy the numbers across blindly — choose ESP32 pins that suit the job (see notes).

  3. 3

    Define the on-board LED

    LED_BUILTIN is not defined for the generic “ESP32 Dev Module” in core 3.x. Most DevKit V1 boards have the blue LED on GPIO2: const int LED = 2;

  4. 4

    Ignore the T4 suggestion

    T4 is touch channel 4 — the compiler is just suggesting a similar name. It isn’t what you want.

Why it happens

Why do some ESP32 boards accept D-names?

Some board definitions (Wemos D1 R32, Arduino Nano ESP32, XIAO) define their own D-names matching their silkscreen. The generic ESP32 Dev Module does not.

Variant: 'A0' works but means GPIO36

On ESP32, A0 is defined as GPIO36 (VP). Prefer the GPIO number so the code reads the same as the pinout.

'LED_BUILTIN' was not declared in this scope

Same cause: the generic module doesn’t know your board’s LED. Define it once at the top.

Board-specific notes

ESP32: Good general GPIOs: 4, 13, 16–19, 21–23, 25–27, 32, 33. Avoid 6–11 (flash), 34–39 for outputs, and strapping pins 0, 2, 12, 15 for things that pull them at boot. Pinout: ESP32 DevKit V1.

ESP8266: D-names are correct there: NodeMCU pinout.

↑↓ to move · Enter to open