AVERYJPARKER.COM · FREE LEAD MAGNET

ESP32 Starter Kit

5 beginner projects — wiring, full sketches, expected output, and troubleshooting so your first weekend actually finishes.

Version 1.0 · 2026 · Print to PDF: Ctrl/Cmd+P

Contents

  1. Setup checklist (do this once)
  2. Parts list (BOM)
  3. Project 1 — Blink + Serial hello
  4. Project 2 — Button with pull-up
  5. Project 3 — External LED + resistor
  6. Project 4 — Temperature / humidity
  7. Project 5 — Relay (low-voltage only)
  8. Troubleshooting cheat sheet
  9. What to build next

1. Setup checklist (do this once)

Safety: Projects 1–4 are low-voltage only. Project 5 uses a relay — stay on 5–12 V DC loads while learning. Mains voltage requires proper enclosures, isolation, and local electrical code — skip mains until you’re ready.

Board notes

2. Parts list (BOM)

ItemQtyNotes
ESP32 DevKit (WROOM or S3)1Any reputable DevKit with USB
USB data cable1Not charge-only
Breadboard1Half-size is fine
Jumper wires~10M-M / M-F as needed
LED (any color)2Long leg = anode (+)
220 Ω resistor2330 Ω also fine
Momentary button1Or use onboard BOOT button for Project 2
DHT22 or BME2801Project 4 — pick one
4.7k–10k resistor1Pull-up if your DHT module lacks one
5 V opto-isolated relay module1Project 5
Optional 5 V supply1If USB browns out with relay

Shopping shortlist on the site: averyjparker.com/gear (affiliate disclosure on that page).

3. Project 1 — Blink + Serial “hello”

Goal: Prove flash + USB serial work before sensors or Wi‑Fi.

Wiring

None required if you use LED_BUILTIN. USB powers the board.

Sketch

// Project 1 — Blink + Serial
// If LED_BUILTIN does nothing on your clone, try: const int LED = 2;

void setup() {
  Serial.begin(115200);
  delay(500);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("ESP32 starter kit — Project 1 ready");
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println("LED on");
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("LED off");
  delay(500);
}

Expected result

Troubleshooting

Done when

You can reflash freely and see serial output without fighting the port.

4. Project 2 — Button with pull-up

Goal: Read a digital input with debounce (foundation for every “if button then…” project).

Wiring

Use INPUT_PULLUP: idle = HIGH, pressed = LOW. No external pull-up resistor required.

ESP32 with button to GND and LED via resistor

Sketch

// Project 2 — Button + LED feedback
const int BTN = 0;          // BOOT on many DevKits
const int LED = LED_BUILTIN;

void setup() {
  Serial.begin(115200);
  pinMode(BTN, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  Serial.println("Project 2 — press button (BOOT or wired to GND)");
}

void loop() {
  static bool lastPressed = false;
  bool pressed = digitalRead(BTN) == LOW;

  digitalWrite(LED, pressed ? HIGH : LOW);

  if (pressed != lastPressed) {
    Serial.println(pressed ? "pressed" : "released");
    lastPressed = pressed;
    delay(40); // crude debounce
  }
}

Expected result

Troubleshooting

Done when

One clean edge per physical press/release.

5. Project 3 — External LED + resistor

Goal: Drive an external load correctly (current limiting) — the habit that prevents dead pins.

Wiring

  1. GPIO 4 → 220 Ω resistor → LED anode (long leg)
  2. LED cathode (short leg) → GND
Never wire an LED from GPIO to GND without a resistor. Keep pin current well under ~12 mA for comfort.

Sketch

// Project 3 — External LED on GPIO 4
const int LED = 4;

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  Serial.println("Project 3 — external LED on GPIO 4");
}

void loop() {
  for (int i = 0; i < 3; i++) {
    digitalWrite(LED, HIGH);
    delay(150);
    digitalWrite(LED, LOW);
    delay(150);
  }
  delay(800);
  Serial.println("blink burst");
}

Expected result

External LED does a triple-blink, pause, repeat. Serial prints blink burst.

Troubleshooting

Done when

You can move the LED to another GPIO by changing one constant.

6. Project 4 — Temperature / humidity read

Goal: Read a real sensor on a schedule (basis for automation and logging).

Pick one path below.

Option A — DHT22 (simpler wiring for beginners)

  1. DHT22 VCC → 3.3 V (some modules want 5 V — check yours)
  2. DHT22 GND → GND
  3. DHT22 DATA → GPIO 15
  4. If module has no onboard pull-up: 4.7k–10k from DATA to 3.3 V

Install library: DHT sensor library by Adafruit (+ Adafruit Unified Sensor).

// Project 4A — DHT22 on GPIO 15
#include <DHT.h>
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
  Serial.println("Project 4A — DHT22");
}

void loop() {
  delay(2500); // don't hammer the sensor
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // Celsius
  if (isnan(h) || isnan(t)) {
    Serial.println("Read failed — check wiring / pull-up / power");
    return;
  }
  Serial.print("Temp C: ");
  Serial.print(t, 1);
  Serial.print("  RH %: ");
  Serial.println(h, 1);
}

Option B — BME280 over I²C

  1. VCC → 3.3 V · GND → GND
  2. SDA → GPIO 21 · SCL → GPIO 22 (common ESP32 defaults)

Install library: Adafruit BME280 (+ BusIO / Unified Sensor as prompted).

// Project 4B — BME280 I2C
#include <Wire.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;

void setup() {
  Serial.begin(115200);
  if (!bme.begin(0x76) && !bme.begin(0x77)) {
    Serial.println("BME280 not found — run I2C scan / check SDA SCL");
    while (1) delay(10);
  }
  Serial.println("Project 4B — BME280");
}

void loop() {
  Serial.print("T=");
  Serial.print(bme.readTemperature(), 1);
  Serial.print("C  P=");
  Serial.print(bme.readPressure() / 100.0F, 1);
  Serial.print("hPa  H=");
  Serial.print(bme.readHumidity(), 1);
  Serial.println("%");
  delay(3000);
}

Expected result

Stable numbers that change when you breathe on / warm the sensor. Failed reads print a clear error — not silent zeros.

Troubleshooting

Done when

You have a repeating log line you trust enough to graph later.

7. Project 5 — Relay (low-voltage only while learning)

Goal: Drive a relay module from a GPIO with a simple on/off serial control pattern.

ESP32 with sensor and relay module

Wiring (module side)

  1. Relay module VCC → 5 V (if module is 5 V logic) or 3.3 V per module docs
  2. Relay module GND → ESP32 GND (common ground required)
  3. Relay module IN → GPIO 5
  4. Load on the relay COM / NO terminals — low-voltage DC only for this kit (e.g. 5 V fan, LED strip segment with its own supply)
Active-low modules are common: digitalWrite(pin, LOW) = ON. Confirm with the module LED before connecting anything you care about.
Do not switch mains until you use a proper enclosure, rated relay, and know your local electrical code.

Sketch

// Project 5 — Relay on GPIO 5 (active-low friendly)
const int RELAY = 5;
const bool ACTIVE_LOW = true; // set false if your module is active-high

void relayWrite(bool on) {
  if (ACTIVE_LOW) {
    digitalWrite(RELAY, on ? LOW : HIGH);
  } else {
    digitalWrite(RELAY, on ? HIGH : LOW);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(RELAY, OUTPUT);
  relayWrite(false);
  Serial.println("Project 5 — relay demo (3s on / 3s off)");
}

void loop() {
  relayWrite(true);
  Serial.println("relay ON");
  delay(3000);
  relayWrite(false);
  Serial.println("relay OFF");
  delay(3000);
}

Combine with Project 4 (mini automation)

// Pseudo-logic you'll use in the full site guide:
// if (temperatureC > 28.0) relayWrite(true);  // e.g. fan
// else if (temperatureC < 26.0) relayWrite(false);

Full write-up: ESP32 home automation with sensors & relays.

Expected result

Relay clicks (or module LED toggles) on a 3 s cadence; serial confirms state.

Troubleshooting

Done when

You can turn a safe low-voltage load on/off without the ESP brownout-resetting.

8. Troubleshooting cheat sheet

SymptomLikely fix
Port missingData cable; CP210x/CH340 drivers; another USB port
Upload fail / timed outHold BOOT; 115200 upload speed; correct board profile
Random resetsWeak USB power; motors/relays need separate supply
Wi‑Fi later breaks thingsFinish offline logic first; then add Wi‑Fi
Garbled serialWrong baud; multiple monitors open
Sensor NaNWiring, pull-up, power, library type

© 2026 Avery J. Parker · Free for personal learning and classroom use · Please don’t resell this kit as a paid PDF without permission.

Site: averyjparker.com · Print this page for a clean handout (File → Print → Save as PDF).