ArduinoNative allows you to run Arduino code without Arduino. ArduinoNative does not attempt to emulate or simulate an Arduino, it is a simple header-only implementation of the Arduino library in order to test and debug Arduino code. Not only do you have the ability to use your favorite IDE with fancy code suggestions, you can even use a debugger to step through your code.
- Download and install required tools to build C++ on your machine
- Create a new C++ project and place ArduinoNative.hpp in that directory
- Define AN_IMPL in one and only one of your source files
- Include ArduinoNative.hpp
#define AN_DEBUG_ALL
#define AN_IMPL
#include "ArduinoNative.hpp"
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
- Arduino Uno
- Arduino Pro or Pro Mini
- Arduino Nano
Choose board by defining a macro
#define AN_BOARD_PRO
If no board is defined it will default to Arduino Uno
Arduino Library Reference. Note that less used functions haven’t been tested that much.
- HIGH and LOW interrupt modes don’t work, only CHANGE, RISING and FALLING
- serialEvent() is only supported on GCC and Clang, as it uses a GCC extension.
- PROGMEM, USB and Stream aren’t implemented and likely never will be
It is recommended that you encapsulate these non-Arduino functions with some macro guards. This prevents you from having to remove them when actually compile for an Arduino.
#ifdef ArduinoNative
// this will only be compiled if ArduinoNative is used
#endif
- Set pin voltage
an_set_voltage(pin, voltage)
- Set pin voltage from console input
an_request_voltage(pin)
- Take input from console and put it in Serial buffer
Serial.an_take_input()
- Print timestamp in ms
an_print_timestamp(); // example "1530ms | "
- Attach sine wave to pin
an_attach_sine(pin, hz = 1, amplitude = 2.5, dc_offset = 2.5, abs = false)
- Remove sine wave on pin
an_remove_sine(pin)
- Attach square wave to pin
an_attach_square(pin, hz = 1, duty_cycle = 0.5);
- Remove square wave on pin
an_remove_square(pin)
Debug features can be enabled by defining the following macros
- AN_DEBUG_TIMESTAMP: Prints a timestamp in milliseconds in front of all debug messages
- AN_DEBUG_ALL: Enables everything below
- AN_DEBUG_DIGITALREAD: Prints a message to console when digitalRead is called
- AN_DEBUG_DIGITALWRITE: Prints a message to console when digitalWrite is called
- AN_DEBUG_ANALOGREAD: Prints a message to console when analogRead is called
- AN_DEBUG_ANALOGWRITE: Prints a message to console when analogWrite is called
- [ ] Check for pin type
- [ ] Attach simulated hardware on pins
- [ ] Move examples to their own folder
- [ ] Debug viewer to show pin status instead of Serial
- [ ] Support more boards
- [ ] Implement extra libraries (Servo.h, FastLED, etc)
#define AN_BOARD_NANO
#define AN_IMPL
#include "ArduinoNative.hpp"
int analogpin = A7;
void setup()
{
Serial.begin(9600);
pinMode(analogpin, INPUT);
}
void loop()
{
#ifdef ArduinoNative
an_request_voltage(analogpin);
#endif
unsigned val = analogRead(analogpin);
Serial.print("Read value ");
Serial.println(val);
float voltage = map(val, 0, 1023, 0.0, 5.0);
Serial.print("Voltage on pin is: ");
Serial.println(voltage, 2);
delay(30);
}
Output:
set voltage of pin 21 to: 3.2 Read value 654 Voltage on pin is: 3.20 ...
#define AN_IMPL
#include "ArduinoNative.hpp"
void setup()
{
Serial.begin(9600);
#ifdef ArduinoNative
Serial.an_take_input();
#endif
}
void loop()
{
while(Serial.available())
Serial.println((char)Serial.read());
}
Output:
ArduinoNative is requesting Serial input: hello h e l l o
#define AN_DEBUG_DIGITALWRITE
#define AN_DEBUG_TIMESTAMP
#define AN_IMPL
#include "ArduinoNative.hpp"
#define LED1 5
#define LED2 6
#define LED1_DELAY 1000 // delay in ms
#define LED2_DELAY 2000 // delay in ms
unsigned long previous_LED1_change;
unsigned long previous_LED2_change;
void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
}
void loop()
{
unsigned long t = millis();
// turn on LED1 every second
if (t - previous_LED1_change >= LED1_DELAY) {
digitalWrite(LED1, !digitalRead(LED1));
previous_LED1_change = t;
}
// turn on LED2 every half a second
if (t - previous_LED2_change >= LED2_DELAY) {
digitalWrite(LED2, !digitalRead(LED2));
previous_LED2_change = t;
}
}
Output:
500ms | Pin: 6 is now HIGH 1000ms | Pin: 5 is now HIGH 1000ms | Pin: 6 is now LOW 1500ms | Pin: 6 is now HIGH 2000ms | Pin: 5 is now LOW 2000ms | Pin: 6 is now LOW 2500ms | Pin: 6 is now HIGH 3000ms | Pin: 5 is now HIGH 3000ms | Pin: 6 is now LOW 3500ms | Pin: 6 is now HIGH 4000ms | Pin: 5 is now LOW 4000ms | Pin: 6 is now LOW ...
#define AN_DEBUG_TIMESTAMP
#define AN_IMPL
#include "ArduinoNative.hpp"
unsigned long switchdelay;
unsigned short count;
void interrupt()
{
#ifdef ArduinoNative
an_print_timestamp();
#endif
Serial.print("INTERRUPT");
Serial.println(++count);
if (count >= 5)
detachInterrupt(2);
}
void setup() {
#ifdef ArduinoNative
an_attach_square(2);
#endif
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), interrupt, CHANGE);
}
void loop() {}
Output:
500ms | INTERRUPT1 1001ms | INTERRUPT2 1500ms | INTERRUPT3 2001ms | INTERRUPT4 2500ms | INTERRUPT5
#define AN_IMPL
#include "ArduinoNative.hpp"
void setup()
{
Serial.begin(9600);
analogReference(EXTERNAL);
#ifdef ArduinoNative
an_set_voltage(AREF, 3.3);
an_set_voltage(A2, 1.65);
#endif
Serial.println(analogRead(A2));
}
void loop() {}
Output:
512