Guide no. 27
From installation to the first blinking LED: the ESP32 package, the right driver, choosing board and port, and what to do when the upload won't start. With the same steps in PlatformIO.
By Ada Intelisano · informaticait.it technical team
- In Arduino IDE 2 you add Espressif's esp32 package from the Boards Manager, after pasting its address in Preferences.
- The board to choose for the DevKitC is ESP32 Dev Module; the Serial Monitor runs at 115200.
- The DevKitC has no LED on a pin: the classic Blink doesn't compile. You need an external LED, for example on GPIO 23.
- If the upload won't start: data cable, right port, monitor closed, and as a last resort hold down BOOT.
Arduino IDE 2
Open File › Preferences (on Mac Arduino IDE › Settings) and paste the address of the Espressif package into “Additional boards manager URLs”:
https://espressif.github.io/arduino-esp32/package_esp32_index.json
Then open the Boards Manager, search for “esp32” and install the package by Espressif Systems: the current version is 3.3.12. Connect the board, choose ESP32 Dev Module and the port from the menu at the top: when the connection is there, the board name appears in bold. The default upload speed is 921600.
The USB driver
Between the USB socket and the ESP32 there is a chip that acts as a serial port. Espressif says the driver is usually already in the operating system and installs itself. If the port doesn't show up, look at the marking on the chip next to the USB socket:
| Chip | On which boards | Driver |
|---|---|---|
| CP2102N (Silicon Labs) | original Espressif DevKitC V4 | CP210x USB to UART Bridge VCP, from the Silicon Labs website |
| CH340 | many Arduino and ESP32 clones | CH341SER by WCH |
| CH9102 | some ESP32 boards from other makers | CH343SER by WCH |
To find the port on Windows open Device Manager, then unplug and plug the board back in: the COM port that disappears and comes back is the board's. On Linux add your user to the dialout group and log in again; on Mac the port is called /dev/cu.…
EN restarts the board. BOOT is for when automatic upload doesn't work: hold BOOT down, press and release EN, then release BOOT; the board waits for the sketch. You usually don't need it: the DevKitC circuit does this by itself.
The first sketch
LED with a 220 Ω resistor between GPIO 23 and the GND next to it. The long leg of the LED (anode) goes toward the resistor. GPIO 23 is a free pin: it doesn't interfere with booting (see guide no. 26).
// First sketch for the ESP32-DevKitC: blinks an LED on GPIO 23 and writes to the Serial Monitor. // The DevKitC has no LED connected to a pin: LED with a 220 ohm resistor between GPIO 23 and GND. #include <Arduino.h> const int PIN_LED = 23; int conta = 0; void setup() { Serial.begin(115200); // open the Serial Monitor at the same speed pinMode(PIN_LED, OUTPUT); Serial.println("Hello, I'm the ESP32!"); } void loop() { digitalWrite(PIN_LED, HIGH); delay(500); digitalWrite(PIN_LED, LOW); delay(500); conta++; Serial.print("Blinks: "); Serial.println(conta); }
Open the Serial Monitor at 115200: after each reset you will also see the ROM lines, such as rst:0x1 (POWERON_RESET),boot:0x13; boot:0x13 means a normal boot.
The same steps in PlatformIO
Install Visual Studio Code, then from the extensions list the official PlatformIO IDE extension (it already contains everything you need). From PlatformIO Home create a New Project with the board “Espressif ESP32 Dev Module” (esp32dev) and the Arduino framework. The sketch goes in src/main.cpp and must begin with #include <Arduino.h>. This is the configuration file:
[env:esp32dev] platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200
| Arduino IDE 2 | PlatformIO | |
|---|---|---|
| Libraries | in the IDE's shared folder | per project, in lib_deps: they install themselves |
| Default upload speed | 921600 | 460800 |
| Default Serial Monitor speed | chosen in the window | 9600: set monitor_speed = 115200 |
| Compile, upload, monitor | buttons at the top | bar at the bottom or Ctrl+Alt+B, Ctrl+Alt+U, Ctrl+Alt+S |
| Arduino-ESP32 core version | the one chosen in the Boards Manager | depends on the espressif32 platform: 7.1.3 uses 3.3.12 |
Many examples out there are written for core 2.x, which has some different functions (for example the PWM ones): if an old sketch doesn't compile, check which version it was written for.
What about the Arduino UNO?
There is nothing to add: the “Arduino AVR Boards” package is already there. Choose Arduino Uno and the port. The UNO does have an LED on pin 13, so the Blink example works as it is (LED_BUILTIN). Many clones use the CH340 chip: if the upload gives the error “can't set com-state”, Arduino recommends installing version 3.7.2022.01 of the driver and blocking automatic updates.
Common mistakes
| Message or symptom | Why | Fix |
|---|---|---|
| “No serial data received” or “Timed out waiting for packet header” | no response: charge-only cable, wrong port or automatic reset failed | data cable, right port, monitor closed elsewhere, then hold BOOT |
| “Wrong boot mode detected (0x13)” | the board communicates but doesn't enter upload mode | hold BOOT down, press EN, try again |
| The port doesn't show up | missing driver or cable without data wires | USB chip driver; try another cable and another socket, no hub |
| Garbled characters in the monitor | speed different from the sketch's | 115200 on both |
'LED_BUILTIN' was not declared | the DevKitC has no LED on a pin | write the pin number of your LED |
| Linux: “Permission denied” | user not in the dialout group | sudo usermod -a -G dialout $USER and log in again |
| Upload fails only with the circuit connected | something on TX/RX, on GPIO 0 or 2 | disconnect and try again |
Useful products
Other guides
- Resistor colour code and tolerances
- N-channel and P-channel MOSFETs
- Bipolar transistor (BJT) or MOSFET?
- Relays: how to drive them and how much current they draw
- THT and SMD/SMT components
- XIAO board pinouts
- LEDs: forward voltage and series resistor
- The multimeter: measuring voltage and current
- Wemos D1 mini: first steps
- MOSFET module with Arduino and ESP32
- Relay module with Arduino and ESP32
- 3D printing filaments: PLA, PETG and fibre-filled versions
- Analog and digital: the differences
- ADS1115: 16-bit converter with Arduino and ESP32
- From bits to real values: converting sensor readings
- DS3231 RTC clock with Arduino and ESP32
- Linear or switching regulator: which one to choose
- Step-down, step-up and buck-boost: choosing the right module
- Voltage divider: reading voltages higher than 5 V or 3.3 V
- Pull-up, pull-down and bounce: wiring a button properly
- 3.3 V and 5 V logic levels: getting an ESP32 and an Arduino to talk
- The I²C bus: addresses, pull-ups and the scanner
- Lithium batteries: voltages, charging and protection
- ESP32 power consumption and deep sleep: how long the battery lasts
- Temperature sensors compared
- ESP32: which pins to use and which to avoid
- SSD1306 OLED display and 16×2 I²C LCD with Arduino and ESP32
- PIR motion sensor and HC-SR04 ultrasonic sensor
- Date and time from the Internet with the ESP32: NTP, Italian time zone and daylight saving time
- MicroSD data logger: saving measurements to CSV
- Solar-powered ESP32: panel, charger and the numbers for Italy
- Web server on the ESP32: control a relay from your phone
- Your first LED: wire it up and make it blink
- The button: let Arduino decide
- The potentiometer: turn a knob and read its value
- Soft light: adjusting the brightness of an LED
- The buzzer: playing notes and melodies
- The traffic light: three LEDs in sequence
- The thermometer: reading the temperature with the TMP36
- The servo motor: moving an arm with Arduino
- The night light: the photoresistor and your first decision
- The relay: switching on a light bulb with Arduino
- The LCD display: making Arduino write
- The electronic dice: your first complete project
- The RGB LED: every color from three lights
- The joystick: two-axis control with a shield
- The LED ring: twelve colors from a single pin
- The DC motor: driving it with a MOSFET
- Soil moisture: the plant that asks for water
- The stepper motor: turn exactly as far as you want
- The parking sensor: faster and faster beeps
- The 7-segment display: big, bright numbers
- Automatic watering: the plant that waters itself
- The keypad: a lock with a secret code
- Networked weather station: values and chart on your phone
- A Telegram bot on the ESP32: your home from your phone
- MQTT with the ESP32: the language of connected devices
- Updating the ESP32 over Wi-Fi (OTA)
- ESP-NOW: two ESP32 boards talking without a router
- WebSocket with the ESP32: the LED that follows the slider
- Readings on a Google sheet, with deep sleep
- WiFiManager: choose the Wi-Fi from your phone
- Bluetooth LE with the ESP32: the phone without a network
- The camera in your browser with the ESP32-S3
- A portable Bluetooth speaker you build yourself
- Bluetooth desktop speakers, 2 × 20 W
- Stereo MP3 player with two buttons
- The shelf that plays music: a Visaton exciter
- How to solder well
- How much does it draw? Current and power with the INA219
- Load-cell scale with the HX711
- CO2 traffic light: when to open the windows
- RFID card door opener
- GPS: track logger on microSD
- LoRa: how far does it go? A range test with two boards
- Battery weather sign with an e-paper display
- Web radio with an ESP32 and an I2S amplifier
- Getting started with the Raspberry Pi Pico 2 in MicroPython
- Your first amplifier: the LM386 and a speaker
- Talking Arduino: the DFR0760 speech synthesis module
- The spectrum of your music on an LED matrix
- Drawing with 64 LEDs: the 8×8 matrix with the MAX7219
- A real voltage: the 12-bit MCP4725 DAC
- The heartbeat on Arduino: an ECG with the AD8232