Simulator86 runs the firmware you already ship on every controller in your product, together, from your scripts, your CI or your editor's AI agent.
Autonomous inspection droneOpen
Components
Suggested Files
No matching files or actions
~/drone $ west build -b nucleo_f767zi flight-controller-- west build: generating a build system-- Board: nucleo_f767zi-- Configuring done[1/142] Preparing syscall dependency handling[97/142] Building C object CMakeFiles/app.dir/src/imu.c.obj[98/142] Building C object CMakeFiles/app.dir/src/main.c.obj[142/142] Linking C executable zephyr/zephyr.elfMemory region Used Size Region Size %age Used FLASH: 38412 B 2 MB 1.83% RAM: 9216 B 512 KB 1.76%Build finished: flight-controller/build/zephyr/zephyr.elf~/drone $
/* Flight controller: attitude loop at 400 Hz on the STM32F767. */
#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include "attitude.h"
#include "imu.h"
#define LOOP_HZ 400
static const struct device *i2c = DEVICE_DT_GET(DT_NODELABEL(i2c1));
int main(void)
{
struct imu_sample s;
if (!device_is_ready(i2c)) {
return -ENODEV;
}
while (1) {
imu_read(i2c, &s);
attitude_update(&s);
k_sleep(K_USEC(1000000 / LOOP_HZ));
}
}#include "imu.h"
#define MPU6050_ADDR 0x68
#define ACCEL_XOUT_H 0x3B
int imu_read(const struct device *i2c, struct imu_sample *s)
{
uint8_t raw[14];
int err = i2c_burst_read(i2c, MPU6050_ADDR, ACCEL_XOUT_H,
raw, sizeof(raw));
if (err) {
return err;
}
s->ax = (int16_t)(raw[0] << 8 | raw[1]);
s->ay = (int16_t)(raw[2] << 8 | raw[3]);
s->az = (int16_t)(raw[4] << 8 | raw[5]);
return 0;
}CONFIG_I2C=y
CONFIG_SPI=y
CONFIG_SERIAL=y
CONFIG_GPIO=y
CONFIG_LOG=y// Safety monitor: raises FAULT if the flight controller goes quiet.
#include "pico/stdlib.h"
#define HEARTBEAT_PIN 15
#define FAULT_PIN 16
#define TIMEOUT_US 10000
int main(void)
{
gpio_init(HEARTBEAT_PIN);
gpio_init(FAULT_PIN);
gpio_set_dir(FAULT_PIN, GPIO_OUT);
uint64_t last = time_us_64();
bool level = gpio_get(HEARTBEAT_PIN);
while (true) {
if (gpio_get(HEARTBEAT_PIN) != level) {
level = !level;
last = time_us_64();
}
gpio_put(FAULT_PIN, time_us_64() - last > TIMEOUT_US);
}
}//! Telemetry: forwards flight state from UART to the ground link.
#![no_std]
#![no_main]
mod link;
use embassy_executor::Spawner;
use esp_hal::uart::{Config, Uart};
#[esp_hal_embassy::main]
async fn main(_spawner: Spawner) {
let p = esp_hal::init(Default::default());
let mut uart = Uart::new(p.UART1, Config::default())
.unwrap()
.with_rx(p.GPIO6)
.with_tx(p.GPIO7)
.into_async();
let mut frame = [0u8; 32];
loop {
let n = uart.read_async(&mut frame).await.unwrap();
link::send(&frame[..n]).await;
}
}# Autonomous inspection drone
Three controllers on one airframe, simulated together:
- flight-controller: STM32F767, Zephyr
- safety-monitor: RP2350, pico-sdk
- telemetry: ESP32-C3, Rust + Embassy/* Flight controller: attitude loop at 400 Hz on the STM32F767. */
#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include "attitude.h"
#include "imu.h"
#define LOOP_HZ 400
static const struct device *i2c = DEVICE_DT_GET(DT_NODELABEL(i2c1));
int main(void)
{
struct imu_sample s;
if (!device_is_ready(i2c)) {
return -ENODEV;
}
int64_t next = k_uptime_ticks();
while (1) {
imu_read(i2c, &s);
attitude_update(&s);
next += k_us_to_ticks_ceil64(1000000 / LOOP_HZ);
k_sleep(K_TIMEOUT_ABS_TICKS(next));
}
}Live signals
Used by engineers at
Supported platforms
Open a complete system in your browser, press run, and watch every controller, sensor and display work together. No account or board needed.
An ESP32-C3 asks an AI model for every move over TLS 1.3 from the chip, with two displays, tilt controls and a buzzer.
Two controllers share sensors, a display and a serial link.
The full game running unmodified on a simulated RP2040, drawn to a colour display.
What engineering teams usually need to establish first.
Simulator86 is a programmable simulation environment for developing, testing, and validating embedded systems before relying on physical hardware.
Yes. Simulator86 runs compiled firmware inside a virtual hardware environment, allowing teams to test the software they intend to ship.
Yes. Simulator86 is framework- and library-agnostic: if your firmware runs on the real supported chip, it runs on Simulator86.
Teams use Simulator86 to develop firmware, reproduce difficult failures, automate testing, and validate system behavior at scale.
Simulator86 supports a growing range of embedded architectures, devices, and connected systems. We evaluate each target system to confirm the right simulation coverage.
Teams can use Simulator86 interactively, integrate it into automated workflows, or connect it to AI engineering tools through the IDE, SDK, and MCP.
Start with a technical evaluation. We’ll review your firmware, target system, and engineering goals to determine how Simulator86 can support your team.

Tell us what's on your board.
Book a call with one of our engineers. Tell us which controllers and parts your product uses, and we'll show you what we already support and tell you plainly what we don't yet.