Simscuit

How to test Arduino code without a board

You can test most of an Arduino sketch before the board arrives, or without one at all. A simulator is very good at some things and blind to others, and knowing which is which saves you from trusting it too much. This guide explains both, lists exactly what Simscuit’s Arduino interpreter supports, and shows how to adapt a sketch that uses something it does not.

Open Circuit Studio free

Two kinds of Arduino simulator

Some simulators compile your sketch with the real compiler and run the machine code on an emulated microcontroller. They match the chip closely, including interrupts, timers and libraries, because they run the same instructions; Wokwi and Proteus work this way.

Others, Simscuit among them, interpret the sketch at the level of Arduino functions and connect those functions to a simulated circuit. They are quicker to start and closer to the circuit, and they show the wiring in detail, but they support a defined set of the language and libraries rather than everything the compiler accepts.

What a simulator shows you well

  • Logic: whether the LED turns on when the button is pressed, whether the state machine reaches each state, whether the loop ends.
  • Wiring: a part on the wrong pin, a missing ground, a button with no pull-up.
  • Values: what analogRead returns as you turn a potentiometer, and what your arithmetic does with it.
  • Serial output: everything the sketch prints, and how it handles text you type into the Serial Monitor.
  • Electrical mistakes, in a simulator that models them: in Simscuit, an LED with no resistor, or a pin asked for more current than it is rated for, shows the numbers and burns out on screen.

What it cannot show you

  • Exact timing. An interpreter does not model instruction cycles, so code that depends on microseconds (bit-banged protocols, tight PWM, measuring short pulses) must be checked on hardware.
  • Real-world noise: switch bounce on a cheap button, a long wire picking up interference, a supply that dips when a motor starts.
  • Component tolerances and drift: real resistors are ±5% or ±1%, sensors need calibration, batteries sag.
  • Libraries it does not implement, and peripherals it does not model, such as Wi-Fi.
  • Mechanical and thermal reality: a servo that stalls under load, a regulator that overheats in a box.

What Simscuit’s interpreter supports

Language: setup() and loop(), global and local variables of the basic types, arrays, functions, if and else, for, while, do and while, switch, and #define.

Arduino functions: pinMode, digitalWrite, digitalRead, analogRead, analogWrite, shiftOut and shiftIn, pulseIn (for ultrasonic sensors), tone and noTone, delay, delayMicroseconds, millis and micros, map, constrain, min, max, abs and the usual maths functions, random and randomSeed, and bitRead. Serial covers begin, print, println and write, and reading what the Serial Monitor sends (available, read, peek, parseInt, parseFloat, readString, readStringUntil, setTimeout).

Libraries include Servo, LiquidCrystal and LiquidCrystal_I2C, Adafruit SSD1306 and SH1106G OLEDs, ST7735, ST7789 and ILI9341 TFTs with the Adafruit GFX drawing calls, Adafruit NeoPixel, LedControl (MAX7219), TM1637Display, DHT, OneWire with DallasTemperature, BH1750, BME280, BMP280, MPU6050, INA219, Wire, RTClib, SD, MFRC522 (RFID), TinyGPSPlus, Keypad and SoftwareSerial (with HC-05 and HC-06 Bluetooth modules). The full list is in Help, Simulation Documentation in Circuit Studio.

Not supported yet: other #include libraries, classes and structs, pointers, interrupts (attachInterrupt) and integer overflow. Two differences to know: a float printed with Serial.print(x, 2) is read as binary, so print with 1 or 3 decimal places; and a whole-number division written directly inside a print or a comparison is not truncated (7 / 2 there gives 3.5), so store it in an int first.

Adapting a sketch: interrupts to polling

A common reason a sketch will not run in an interpreter is attachInterrupt. For a button, polling for the moment the input changes does the same job. This version counts presses with no interrupt and runs in Simscuit and on a real board.

const int buttonPin = 2;
int lastState = HIGH;
int presses = 0;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  int state = digitalRead(buttonPin);
  // A press is the moment the pin goes from HIGH to LOW.
  if (lastState == HIGH && state == LOW) {
    presses = presses + 1;
    Serial.print("Presses: ");
    Serial.println(presses);
    delay(20);   // simple debounce: ignore the contact bounce
  }
  lastState = state;
}

Using a supported library: a servo sweep

Libraries on the supported list are used exactly as on a real board. This sweeps an SG90 servo on pin 9 from 0 to 180 degrees and back; in Simscuit the horn turns at the servo’s rated speed.

#include <Servo.h>

Servo arm;

void setup() {
  arm.attach(9);
}

void loop() {
  for (int angle = 0; angle <= 180; angle += 5) {
    arm.write(angle);
    delay(30);
  }
  for (int angle = 180; angle >= 0; angle -= 5) {
    arm.write(angle);
    delay(30);
  }
}

A workflow that uses both

  1. Build the circuit in the simulator and get the logic right: every input, every state, the Serial output you expect.
  2. Check the electrical side there too: currents per pin, resistors on every LED, a shared ground.
  3. Export the sketch (File, Export, Code (.ino)) and the bill of materials.
  4. Upload with the Arduino IDE (uploading from Simscuit is not available yet), and test on the bench one part at a time.
  5. When the real board disagrees with the simulator, suspect timing, noise, a library difference or a wiring slip, in that order, and print values over Serial to find out.

When to move to real hardware

  • The sketch needs a library or feature the simulator does not support: Wi-Fi, interrupts, classes.
  • Timing below a millisecond matters.
  • You are tuning to real sensors, real motors or a real environment.
  • The design is ready to become a product: test the board, the supply and the enclosure together.

Questions

Can I test Arduino code without a board?

Yes. A simulator such as Simscuit, Tinkercad Circuits or Wokwi runs the sketch against a virtual circuit, so you can check the logic, wiring and Serial output before using hardware.

Does Simscuit support every Arduino library?

No. It supports a documented list (Servo, LCDs, OLEDs, NeoPixel, DHT, BME280, MPU6050 and many more); other #include libraries, classes, pointers and interrupts are not supported yet.

Loading Simscuit