ESP32 simulator, the classic one, on an Xtensa core
Mokxi models the thirty-pin DOIT ESP32 DevKit V1: an ESP32-WROOM-32 with its Xtensa LX6 at 240 MHz, the GPIO matrix, IO_MUX, all three UARTs, timer group 0, ADC1 and the LEDC PWM controller, at the real addresses. One core, not two, and no radio (WiFi here is simulated, and says so), and the contract says exactly where every edge is.
- 10peripheral areas modeled
- 24projects ready to run
- Real timeon your own machine
What is modeled
Taken from the board's own contract document and put in plain words, with what is missing beside it.
Modeled
- Core
- Xtensa LX6 in the windowed ABI, sixty-four address registers, the window overflow and underflow handlers, one instruction per cycle at 240 MHz
- Memory
- 128 KB of instruction RAM at 0x4008_0000 and 192 KB of data RAM at 0x3FFB_0000, kept apart the way ESP-IDF keeps them
- GPIO matrix and IO_MUX
- Forty pins with the real two-register split, pulls and input enable per pad, and GPIO 34 to 39 refused as outputs, because the chip has no driver on them
- UART0
- Paced at the configured baud rate, wired to the serial monitor
- UART1 and UART2
- Serial1 and Serial2 on whatever pins begin() names, through the GPIO matrix: real frames on the wire, bit by bit, at the rate the divider really gives, with the core driver’s receive buffer
- Timer group 0
- Timer 0 at a tick a microsecond behind millis() and micros(); delay() parks the core on CCOMPARE0 rather than spinning on it
- ADC1
- Twelve bits on the eight real channels (GPIO 36, 37, 38, 39, 32, 33, 34 and 35) with the four attenuations, and 11 dB following a real part’s curve to 4095 at about 3.1 V
- LEDC
- The high-speed group: four timers and eight channels on any pin with an output driver, behind analogWrite, ledcAttach and ledcWrite
- The interrupt matrix
- Its sources routed the way the hardware routes them, so attachInterrupt is three writes rather than one
- WiFi, simulated
- WiFi.h, HTTPClient.h and WebServer.h over a network written in software: no radio, no 802.11, and real internet only when you sign in and switch it on
Not modeled
- A radio of any kind. There is no 802.11 and no Bluetooth radio in the model. WiFi and Bluetooth are simulated instead (the Arduino API over a network of ours which reaches the real internet only when you sign in and switch it on, and a phone in the editor’s Bluetooth pane), and every page that mentions them says so.
- The second core. A real ESP32 has two LX6 cores; this model runs the PRO core, so anything that starts a task on core 1 will not run.
- The FPU: a hard-float binary built elsewhere faults on its first float instruction. Sketches built here are soft float, so float math works.
- The cache, flash and PSRAM, the RTC and ULP, deep sleep, ADC2, the touch and hall sensors, I2C, SPI, I2S and RMT.
- Several addresses (the IO_MUX pad order, the timer group and LEDC layouts, the SENS offsets, the interrupt matrix numbers and the GPIO matrix signal indices LEDC uses) are this model’s belief rather than something it can stand behind. Section 6 of the contract names every one.
Open one and press Run
Each of these opens in the editor exactly as it is drawn here.
Every built-in project on the ESP32 DevKit V1
Each has its own page with the circuit running, the code and a parts list.
- ESP32 knobBeginner
- ESP-NOW button and LEDIntermediate
- ESP32 PZEM-004T energy monitorIntermediate
- ESP32 ILI9488 touch paintIntermediate
- ESP32 ST7796S touch paintIntermediate
- ESP32 I2S microphone level meterIntermediate
- ESP32 I2S sine playerIntermediate
- ESP32 traffic emergency system with RFIDIntermediate
- ESP32 DHT22 weather web serverIntermediate
- ESP32 web server with two LEDsBeginner
- ESP32 async web server: BME280, slider and relayIntermediate
- ESP32 Telegram doorbell with a PIR sensorIntermediate
- ESP32 NTP clock on a TM1637 displayBeginner
- ESP32 Bluetooth serial lampBeginner
- ESP32 BLE UART lampIntermediate
- MicroPython blink on an ESP32Beginner
- MicroPython button interrupt on an ESP32Beginner
- MicroPython PWM fade on an ESP32Beginner
- DHT22 on an ESP32 with MicroPythonBeginner
- SSD1306 OLED on an ESP32 with MicroPythonBeginner
- MicroPython WiFi weather on an ESP32Intermediate
- Audio spectrum analyzerAdvanced
- Animatronic eyesAdvanced
- An ESP32 and an Arduino Uno talking over serialIntermediate
Parts wired to the ESP32 DevKit V1, step by step
Each page has the wiring with the ESP32 DevKit V1’s own pin names, the code, the common mistakes and the circuit running.
- ESP32 DHT22
- ESP32 SSD1306 OLED
- ESP32 I2C LCD
- ESP32 Servo
- ESP32 HC-SR04
- ESP32 NeoPixel
- ESP32 Button
- ESP32 Potentiometer
- ESP32 Buzzer
- ESP32 Relay
- ESP32 PIR Sensor
- ESP32 MPU6050
- ESP32 BMP280
- ESP32 DS18B20
- ESP32 IR Receiver
- ESP32 Keypad
- ESP32 TM1637 Display
- ESP32 28BYJ-48 Stepper
- ESP32 RC522 RFID
- ESP32 LDR
- ESP32 BME280
- ESP32 Joystick
- ESP32 7-Segment Display
- ESP32 DS3231 RTC
Tutorials that use this board
Each one ends in a running circuit, on this same board.
- The ESP32 DevKit V1 pinout: every pin, and which to avoid
- analogRead on an ESP32: 12 bits, attenuation and ADC2
- Uno vs ESP32 vs Pico: which to start with
- Ten ESP32 projects for beginners, in order
- An ESP32 and an Arduino Uno in one simulation
- An HTTP GET request: fetch the weather as JSON
- MicroPython on the ESP32: blink, a button, PWM, a DHT22, an OLED and WiFi
Questions
Is it free?
Yes. Every board and every part is on the free plan, with no account needed.
Can I compile my own sketch for it?
Yes. Edit the sketch and press Run: it compiles in the tab with clang for Xtensa, and the build panel shows every step. Nothing is uploaded. Floating-point math works: the browser builds it soft float, as on every other board here.
Does it simulate WiFi or Bluetooth?
Both, simulated, and it says plainly that they are. Bluetooth is a phone in the editor’s Bluetooth pane, not a radio. Your sketch uses the real Arduino calls (WiFi.begin, WiFi.status, HTTPClient, WebServer), and the board joins a network, fetches a page and serves one. Underneath there is no radio and no 802.11. Four made-up addresses under .mokxi answer inside this tab. Signed in, you can switch on Real internet in the Cloud panel, and HTTP and HTTPS requests to real hosts go out through Mokxi’s gateway.
Why will pinMode(34, OUTPUT) not work?
Because it does not work on the chip either. GPIO 34 to 39 have an input buffer and no output driver at all. Mokxi refuses the write the way the silicon does, counts it, and puts a small amber mark on the board rather than letting you believe the pin is driving something.
Why does my potentiometer reach 4095 before the end of its travel?
Because at the default 11 dB attenuation a real ESP32’s raw reading saturates at about 3.1 V, short of the 3.3 V rail, and bends on the way there: the middle of the pot reads about 1890, not 2048. Mokxi models that curve, and the knob example prints the raw number so it is not a mystery.
Is this the 30-pin or the 38-pin board?
The thirty-pin DOIT DevKit V1. The 38-pin Espressif DevKitC is a full inch between header rows and brings out six more pins: the GPIO numbers are the same chip’s, the positions are not.
Does it run both cores?
One. The PRO core runs; there is no APP CPU and no FreeRTOS to schedule across them, so a setup()/loop() sketch is fine and xTaskCreatePinnedToCore is not.
The other boards
Every one of these runs today, and every one is free.
Looking for the shorter introduction? See the ESP32 DevKit simulator page.
A RISC-V chip at 160 MHz, on the real memory map.
The classic Arduino, with an ATmega328P running at 16 MHz.
The Uno’s chip on a small board that fits a breadboard.
The big Arduino, with 54 digital pins and four serial ports.
An Uno-shaped board whose chip does its own USB serial.
A second RISC-V board, with 31 pins and simulated WiFi.
The ESP32-S3 at 240 MHz, with USB serial and an RGB LED.
The NodeMCU’s ESP8266 at 80 MHz, with simulated WiFi.
Try it on your own firmware
What you build here runs on the board on your desk, unchanged. Nothing to install and no account needed.