Start simulating free

WiFi & Virtual Phone

ESP32 and ESP8266 boards in Circzy connect to a virtual network. Your program can join WiFi, run a web server, fetch data from the internet, send MQTT messages, and use Bluetooth. You can try all of it with the virtual phone, using the same code you would run on a real board.

Opening the virtual phone

With an ESP32/ESP8266 board (or a circuit with an HC-05 module), a green phone button appears next to ▶. The virtual phone also opens automatically when a program that uses WiFi or Bluetooth starts. The phone has several apps:

AppWhat it does
BrowserOpens web pages served by the ESP, for example http://192.168.1.23/
WiFiChooses a network: the Circzy-WiFi router or a hotspot created by the ESP
BluetoothTerminal and control pad for ESP32 BluetoothSerial or an HC-05 module
MQTTPublish and subscribe on the virtual broker
ActivityA log of every network event: WiFi, HTTP requests, MQTT, Bluetooth
Public URLShares the ESP web page over the internet (Pro)

Connecting to WiFi

Use the Circzy-WiFi network with no password:

#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.begin("Circzy-WiFi", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());
}

void loop() {
}

On ESP8266, use ESP8266WiFi.h instead of WiFi.h. The ESP gets IP 192.168.1.23, and the virtual phone joins the same network automatically.

Web server

#include <WiFi.h>
#include <WebServer.h>

WebServer server(80);

void setup() {
  pinMode(2, OUTPUT);
  WiFi.begin("Circzy-WiFi", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
  }
  server.on("/", []() {
    server.send(200, "text/html", "<h1>LED</h1><a href=\"/on\">ON</a> <a href=\"/off\">OFF</a>");
  });
  server.on("/on", []() {
    digitalWrite(2, HIGH);
    server.sendHeader("Location", "/");
    server.send(303);
  });
  server.on("/off", []() {
    digitalWrite(2, LOW);
    server.sendHeader("Location", "/");
    server.send(303);
  });
  server.begin();
}

void loop() {
  server.handleClient();
}

Run it, open the Browser app on the virtual phone, then tap the ESP IP address. Links, forms (GET and POST), fetch(), and XMLHttpRequest on the ESP page are all sent to the ESP. CSS and JavaScript files served by the ESP are loaded too; libraries from a CDN (https://…) load directly from the internet.

Hotspot, captive portal, and mDNS

WiFi.softAP("MyAP", "password") creates a hotspot. Open the WiFi app on the phone, choose the hotspot, enter the password, then open http://192.168.4.1/. If the program runs a DNSServer (captive portal), every address on the phone goes to the ESP. With MDNS.begin("lamp"), the ESP is also reachable at http://lamp.local/.

Internet: HTTPClient and APIs

HTTPClient, WiFiClient, and WiFiClientSecure (HTTP and HTTPS) can reach the real internet, such as weather APIs, ThingSpeak, or Telegram bots. Requests are forwarded through the Circzy server, so setInsecure() or certificates are not needed.

HTTPClient http;
http.begin("https://api.example.com/data");
int code = http.GET();
String body = http.getString();
http.end();
LimitFreePro
Internet requests per day3005000
Response size1 MB1 MB

Local network addresses on the internet (such as 192.168.x.x or 127.0.0.1) cannot be reached. configTime() and NTPClient get the real time from your computer clock.

MQTT

The virtual MQTT broker accepts connections to any host on port 1883 (for example broker.hivemq.com). The PubSubClient library is available. Open the MQTT app on the phone to watch messages from the ESP (subscribe to #) and to send messages to the ESP.

#include <WiFi.h>
#include <PubSubClient.h>

WiFiClient net;
PubSubClient mqtt(net);

void callback(char *topic, byte *payload, unsigned int length) {
  Serial.write(payload, length);
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  WiFi.begin("Circzy-WiFi", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
  }
  mqtt.setServer("broker.hivemq.com", 1883);
  mqtt.setCallback(callback);
}

void loop() {
  if (!mqtt.connected() && mqtt.connect("esp32-circzy")) {
    mqtt.subscribe("home/lamp");
    mqtt.publish("home/status", "online");
  }
  mqtt.loop();
}

Bluetooth

ESP32 uses BluetoothSerial:

#include <BluetoothSerial.h>

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32-Circzy");
}

void loop() {
  if (SerialBT.available()) {
    char c = SerialBT.read();
    Serial.println(c);
  }
}

Open the Bluetooth app on the phone, tap Connect, then send text from the Terminal tab or use the arrow pad on the Control tab (it sends F, B, L, R, S). An HC-05 module on any board (such as an Arduino Uno) also appears in this app while the simulation runs.

Blocks mode

In Blocks mode, the Components → WiFi & Web category has connect WiFi, if a web request arrives, page path =, and reply web page blocks. The ESP32 built-in Bluetooth block in Bluetooth & GPS makes the other Bluetooth blocks use the ESP32 Bluetooth.

Public URL (Pro)

In the Public URL app, tap Turn on public URL to get an address like https://device.circzy.com/@code. You can open it from a real phone or share it with friends while your simulation runs. The ESP must be connected to WiFi and run a web server on port 80.

Not supported yet

BLE, ESP-NOW, WebSocket, raw TCP connections to ports other than HTTP and MQTT, and form file uploads (multipart/form-data) are not simulated yet. See Simulation Limits.

Ready to try it?

Sign in with Google, pick a board and run your first simulation in two minutes. Free during the launch period.

Start simulating free