Bring your board. Get a simulator for it.
Run your firmware, test failures, and validate your whole system—on your own infrastructure.
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
Run a complete embedded system in your browser.
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.
Turn up the interference. Watch packets stop arriving. See whether your firmware detects the loss and recovers.
More noise. Less room for the signal.
INFO heartbeat receivedIllustrative RF scenario. PCB layouts: Olimex ESP32-DevKit-LiPo and ESP32-PoE · KiCad · Apache 2.0.
Run your controllers together. Follow a command from one firmware to the next, across the whole system.
Test your update across 10,000 simulated devices before rollout.
Try available boards and components, connect them, and run your firmware.
Share your PCB design files, schematics, and usual hardware documentation. We handle the simulation model. Run your firmware, test connected systems, and reproduce failures before deployment.
Connect the model to your existing tools, integrate with your SystemC simulator, or co-simulate with Verilog.
Discuss your systemAvailable on our cloud or your infrastructure.
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.
Bring your board. Get a simulator for it.
Run on your own servers. Work with us under NDA. Test analog behavior and functional logic, improve your HIL setup, and more.