Simscuit

Getting started with the ESP32

The ESP32 from Espressif is a low-cost microcontroller with Wi-Fi and Bluetooth built in, and it can be programmed with the same Arduino functions as an Uno. It is also less forgiving: 3.3 V logic, pins with special jobs and a few that can only be inputs. This guide covers what you need to know before the first sketch, then gets one running.

Open Circuit Studio free

What the ESP32 is

The original ESP32 is a system on a chip with a dual-core 32-bit Xtensa processor running at up to 240 MHz, 520 KB of SRAM, 2.4 GHz Wi-Fi (802.11 b/g/n) and Bluetooth 4.2 (Classic and Low Energy). Most people meet it on a module such as the ESP32-WROOM-32, which adds 4 MB of flash and an antenna, mounted on a development board such as the ESP32-DevKitC or the many DevKit V1 boards with a USB-to-serial chip and a voltage regulator.

The name now covers a family: the ESP32-S3 (with USB and vector instructions for machine learning), the RISC-V based ESP32-C3 and C6, and others. This guide is about the original ESP32 on a WROOM-32 module; the newer chips differ in pins and peripherals.

The pins: what to use and what to avoid

  • Logic is 3.3 V. A HIGH output is about 3.3 V, and inputs should not see more than that: treat the pins as not 5 V tolerant and level-shift 5 V signals.
  • GPIO 34, 35, 36 and 39 (the ones the WROOM-32 brings out from the 34 to 39 group) are inputs only, with no internal pull-up or pull-down. They are good analogue inputs; they cannot drive an LED, and INPUT_PULLUP does nothing on them.
  • GPIO 6 to 11 connect to the module’s flash memory. Do not use them.
  • GPIO 0, 2, 5, 12 and 15 are strapping pins, read at reset to choose the boot mode. They can be used, but a part that pulls one the wrong way can stop the board starting or uploading. GPIO 12 is the one most likely to cause trouble.
  • ADC2 pins (including 0, 2, 4, 12 to 15 and 25 to 27) cannot be read while Wi-Fi is on. For analogue inputs in a Wi-Fi project, use ADC1: GPIO 32 to 39.
  • analogRead returns 0 to 4095 (12 bits). The ESP32’s ADC is not perfectly linear, especially near 0 V and the top of its range, so calibrate if you need accurate volts.

Install the Arduino-ESP32 core

  1. Install the Arduino IDE from arduino.cc.
  2. Open File, Preferences (Arduino IDE, Settings on macOS) and paste https://espressif.github.io/arduino-esp32/package_esp32_index.json into Additional boards manager URLs.
  3. Open Tools, Board, Boards Manager, search for esp32 and install esp32 by Espressif Systems.
  4. Choose your board under Tools, Board, esp32: ESP32 Dev Module works for most WROOM-32 development boards.
  5. Connect the board. If no port appears, install the driver for its USB-to-serial chip (often a Silicon Labs CP210x or a WCH CH340).
  6. Choose the port under Tools, Port. If an upload stalls at Connecting, hold the board’s BOOT button until it starts.

A first sketch: blink

Many DevKit V1 boards have a blue LED on GPIO 2. Espressif’s own ESP32-DevKitC has only a power LED, so on that board wire an LED and a resistor from GPIO 2 to GND. At 3.3 V a red LED with a 220 Ω resistor draws about (3.3 − 2.0) ÷ 220 = 5.9 mA. Note that the ESP32 serial port is usually opened at 115200 baud.

const int ledPin = 2;   // the on-board LED on many ESP32 DevKit V1 boards

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

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

A button and a potentiometer

GPIO 4 has an internal pull-up, so a button from GPIO 4 to GND reads LOW when pressed. GPIO 34 is input-only and on ADC1, which makes it a good place for a potentiometer wiper (ends on 3V3 and GND, never 5 V).

const int buttonPin = 4;  // internal pull-up available
const int ledPin = 2;
const int potPin = 34;    // ADC1, input only

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (digitalRead(buttonPin) == LOW) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
  int raw = analogRead(potPin);   // 0 to 4095
  Serial.print("Potentiometer: ");
  Serial.println(raw);
  delay(200);
}

ESP32 or Arduino Uno?

Start on the Uno if you are new and your parts are 5 V modules; move to the ESP32 when a project needs Wi-Fi, Bluetooth or more memory. The code you learn carries over almost unchanged.

ESP32 (WROOM-32 module) and Arduino Uno R3 compared
Arduino Uno R3ESP32 on a WROOM-32
ProcessorATmega328P, 8-bit AVR, 16 MHzDual-core 32-bit Xtensa, up to 240 MHz
Memory32 KB flash, 2 KB SRAM, 1 KB EEPROM4 MB flash (module), 520 KB SRAM
Logic level5 V3.3 V, not 5 V tolerant
Analogue inputs6, 10-bit (0 to 1023)Up to 18 channels, 12-bit (0 to 4095); ADC2 unavailable with Wi-Fi
PWMPins 3, 5, 6, 9, 10, 11Most output pins, through the LEDC peripheral
WirelessNoneWi-Fi 802.11 b/g/n, Bluetooth 4.2 Classic and LE
Pins to be careful withD0 and D1 (USB serial)Flash pins 6 to 11, strapping pins, input-only 34 to 39
Best forLearning, 5 V sensors and shields, simple timingConnected projects, more memory and speed

Power and wiring tips

  • Power the board from USB or 5 V on its VIN or 5V pin; the on-board regulator makes 3.3 V. Never put 5 V on a 3V3 pin.
  • Wi-Fi transmission draws current in bursts of a few hundred milliamps. A weak USB port or long thin cable can make the board reset (a brown-out); a better supply fixes it.
  • Share ground between the ESP32 and every module it talks to.
  • Check that 5 V sensors are actually 3.3 V compatible, or use a level shifter or a divider on their outputs.

Try it in Simscuit first

Simscuit simulates an ESP32 DevKit V1 with the WROOM-32 pin rules: GPIO 34, 35, 36 and 39 are inputs only, analogRead is 12-bit, the logic level is 3.3 V and the LED is on GPIO 2. Both sketches above run on it, so you can check the wiring and the logic before the board arrives. The ESP32-S3, Nano ESP32, XIAO ESP32C3 and NodeMCU ESP8266 are simulated too, among about 20 boards.

The limits are plain: Simscuit does not simulate Wi-Fi or Bluetooth, and it runs sketches in its own Arduino interpreter rather than on an emulated Xtensa core, so FreeRTOS tasks, interrupts and Wi-Fi libraries need real hardware or a firmware-level simulator.

Sources

Pin rules from Espressif’s documentation, checked 6 November 2026.

Questions

Can I use 5 V sensors with an ESP32?

Power them from 5 V if they need it, but do not feed their 5 V outputs straight into an ESP32 pin. Use a level shifter, a resistor divider, or a 3.3 V version of the sensor.

Why does INPUT_PULLUP not work on GPIO 34?

GPIO 34 to 39 on the ESP32 are input-only and have no internal pull-up or pull-down. Add an external resistor, or use another pin such as GPIO 4.

Loading Simscuit