Examples
Three complete sketches. Flash, see them work, adapt to your own project.
1. Hello World — One button, one LED
The minimum viable sketch. A Simple Button on the dashboard toggles the LED on your Arduino. Direct Mode — no router, no server.
[gif] Phone tap toggles the LED on the Arduino
#include <InstantIoTWiFiAP.hpp>
const char* AP_SSID = "InstantIoT-Greenhouse";
const char* AP_PASS = "12345678";
#define LED_PIN 2
InstantIoTWiFiAP instant(AP_SSID, AP_PASS);
ISimpleButton("btn1") {
WHEN_TOGGLED(isOn) {
digitalWrite(LED_PIN, isOn ? HIGH : LOW);
}
};
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
instant.begin();
}
void loop() {
instant.loop();
}
In the app: Add a Simple Button with Widget ID btn1, Mode Toggle.
2. Sensor dashboard — Gauge + Slider + Switch
A typical home setup. Your Arduino reads a temperature sensor and pushes it to a Gauge. The user adjusts the LED brightness from a Slider (live PWM) and switches a fan relay on or off from a Switch. Three widgets, one sketch, Direct Mode.
[gif] Live readings on the gauge as the slider sets the brightness
#include <InstantIoTWiFiAP.hpp>
#include <utils/InstantIoTTimer.hpp>
const char* AP_SSID = "InstantIoT-Greenhouse";
const char* AP_PASS = "12345678";
#define LED_PIN 2
#define FAN_PIN 4
#define TEMP_PIN A0
InstantIoTWiFiAP instant(AP_SSID, AP_PASS);
InstantTimer timers;
auto temp = instant.gauge("temp_gauge");
// User → device
IHorizontalSlider("brightness") {
WHEN_CHANGING(v) {
analogWrite(LED_PIN, (int)(v / 100.0f * 255.0f));
}
};
ISwitch("fan") {
WHEN_SWITCH_SET(isOn) {
digitalWrite(FAN_PIN, isOn ? HIGH : LOW);
}
};
// Device → app
void pushTemperature() {
if (!instant.connected()) return;
// Toy mapping for the example — replace with your real sensor read.
int raw = analogRead(TEMP_PIN);
float c = raw / 1023.0f * 50.0f;
temp.setValue(c);
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
instant.begin();
timers.every(500, pushTemperature);
}
void loop() {
instant.loop();
timers.run();
}
In the app: Add a Gauge with Widget ID temp_gauge (range 0–50, unit °C), a Horizontal Slider with Widget ID brightness (range 0–100), and a Switch with Widget ID fan.
To run in Server Mode: change the #include to <InstantIoTWiFiServer.hpp>, swap the constructor and begin() call as shown in Setup — the rest is identical.
3. Full demo — Five widgets, three timers
The full tour. A button and a slider both drive PWM on the LED pin (button takes priority while pressed). A gauge shows a sine wave. A horizontal level draws a triangle wave. A bar chart animates five bars with five different patterns — sine, triangle, the slider value, the button state, and a staircase pulse. Three timers push the displays at three different rates, all from one sketch in Server Mode.
[gif] All five widgets reacting on the dashboard, smooth and responsive
#include <InstantIoTWiFiServer.hpp>
#include <utils/InstantIoTTimer.hpp>
#include <math.h>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* SERVER_IP = "192.168.1.42";
const uint16_t SERVER_PORT = 9001;
const char* DEVICE_TOKEN = "YOUR_DEVICE_TOKEN";
#define LED_PIN 2
InstantIoTWiFiServer instant(SERVER_IP, SERVER_PORT, DEVICE_TOKEN);
InstantTimer timers;
// State driven by the user
bool buttonOn = false;
float sliderPct = 0.0f;
// Fake signal phases for the displays
float gaugePhase = 0.0f;
float levelPhase = 0.0f;
float barPulse = 0.0f;
// Cached references for the displays
auto g1 = instant.gauge("gauge1");
auto level = instant.hLevel("level1");
auto bars = instant.barChart("bars1");
// Apply effective brightness on LED_PIN.
// Button pressed = 100%, otherwise follow the slider.
void applyPin2() {
float pct = buttonOn ? 100.0f : sliderPct;
analogWrite(LED_PIN, (int)(pct / 100.0f * 255.0f));
}
// User → device
ISimpleButton("btn1") {
WHEN_TOGGLED(isOn) { buttonOn = isOn; applyPin2(); }
WHEN_PRESSED { buttonOn = true; applyPin2(); }
WHEN_RELEASED { buttonOn = false; applyPin2(); }
WHEN_LONG_PRESSED { Serial.println("[btn1] long press"); }
};
IHorizontalSlider("slider1") {
WHEN_CHANGING(v) { sliderPct = v; applyPin2(); }
WHEN_CHANGED(v) { sliderPct = v; applyPin2(); }
};
// Device → app
void pushGauge() {
if (!instant.connected()) return;
gaugePhase += 0.1f;
if (gaugePhase > TWO_PI) gaugePhase -= TWO_PI;
float v = (sinf(gaugePhase) + 1.0f) * 50.0f;
g1.update(v, 0.0f, 100.0f);
}
void pushLevel() {
if (!instant.connected()) return;
levelPhase += 1.5f;
if (levelPhase > 200.0f) levelPhase -= 200.0f;
float v = (levelPhase <= 100.0f) ? levelPhase : (200.0f - levelPhase);
level.update(v, 0.0f, 100.0f);
}
// 5 bars — the value order MUST match the slot order in the app.
void pushBars() {
if (!instant.connected()) return;
barPulse = (barPulse > 95.0f) ? 5.0f : barPulse + 12.0f;
float values[5];
values[0] = (sinf(gaugePhase) + 1.0f) * 50.0f; // Sinus
values[1] = (levelPhase <= 100.0f) ? levelPhase
: (200.0f - levelPhase); // Triangle
values[2] = sliderPct; // Slider
values[3] = buttonOn ? 100.0f : 0.0f; // Button
values[4] = barPulse; // Pulse
bars.setValues(values, 5);
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, 0);
instant.setHeartbeat(1000);
instant.begin(WIFI_SSID, WIFI_PASS);
timers.every(200, pushGauge);
timers.every(150, pushLevel);
timers.every(1500, pushBars);
}
void loop() {
instant.loop();
timers.run();
}
In the app: Add the five widgets with the matching IDs (btn1, slider1, gauge1, level1, bars1). For bars1, configure five slots in the Inspector — Sinus, Triangle, Slider, Button, Pulse — in that order, with the colors you like.
This sketch is also the clearest illustration of the timer pattern: three timers.every(...) lines drive three different displays at three different rates, all in one sketch, without flooding the link.
Next
→ Setup — If you haven’t installed the library yet.
→ Receive command from App and Send data to App — The macros and methods used in these examples.
→ Widget in app / Overview — Browse all 17 widgets.