Fluxgrid cheat sheet
The short version. Search it, copy a line, get back to the board — the full usage guide has the rest.
Start here4
A complete device is about ten lines. Everything below is the rest of the ten.
The whole sketch
Docs ↗Flash this, and the board appears online on your dashboard.
#define WIFI_SSID "wifi"
#define WIFI_PASS "pass"
#define FG_TOKEN "DEVICE_TOKEN" // one string per device, from the dashboard
#include <Fluxgrid.h>
void setup() {
Fluxgrid.begin(); // server, port and TLS are built in
}
void loop() {
Fluxgrid.run(); // every loop
Fluxgrid.write("temp", analogRead(4) * (50.0 / 4095.0)); // publish a reading
digitalWrite(2, Fluxgrid.read("relay").asBool()); // read a Switch back
}The three `#define`s go ABOVE the include
Docs ↗Arduino compiles your sketch and the library separately, so a value defined
after #include <Fluxgrid.h> is invisible to it — begin() then connects with
nothing. This is the single most common first-flash failure.
#define FG_TOKEN "…" // ✅ above
#include <Fluxgrid.h>
#define FG_TOKEN "…" // ❌ below — ignoredOne token per device
Docs ↗Add a device → Pair device on the dashboard gives you one string. It already bundles the routing token and the device's MQTT user/password, and the library splits it — you never paste three values.
A handle is the widget's name
Docs ↗"temp" in the code is the datastream handle the widget shows on the
canvas. Drop a widget and it creates one for you; use that exact string in the
sketch. If a tile stays blank, these two disagree.
Keep it in one place so the two can't drift:
#define TEMP_HANDLE "temp" // must match the widget's handle
Fluxgrid.write(TEMP_HANDLE, 23.4);Core API9
The calls almost every sketch uses. Everything else is in the full reference.
Fluxgrid.begin()
Docs ↗Connect WiFi + cloud using WIFI_SSID / WIFI_PASS / FG_TOKEN.
Fluxgrid.run()
Docs ↗Keep the link alive + deliver writes.
Fluxgrid.write(handle, value)
Docs ↗Push telemetry to a datastream. Safe to call every loop() — the library paces it for you.
Fluxgrid.read(handle)
Docs ↗Latest value for a datastream, as a FluxValue — convert with .asInt() / .asFloat() / .asBool() / .asString().
Fluxgrid.has(handle)
Docs ↗true once any value has been received for the handle.
Fluxgrid.onReceive(handle, fn)
Docs ↗Fire a callback once per incoming write. The lambda gets a FluxValue: onReceive("relay", [](FluxValue v){ … v.asBool() … }).
Fluxgrid.onConnected(fn)
Docs ↗Runs each time the cloud connection is (re)established.
Fluxgrid.connected()
Docs ↗true when linked to the cloud.
Fluxgrid.region(code)
Docs ↗Point the device at a region's cloud — "com" (default) or "cn". Call before begin().
Everyday patterns8
Publish a value
Docs ↗Call write() straight from loop() — the library paces it: an unchanged value
is not resent (except a 10 s heartbeat), a change goes out at once but never
faster than one per 100 ms per handle. You do not need a millis() timer, and
you do not need to debounce.
void loop() {
Fluxgrid.run();
Fluxgrid.write("button", digitalRead(0) == LOW); // fine, every loop
}React to a control widget
Docs ↗onReceive() fires once per incoming write, with the new value — the board
never polls for it. Register it before begin(), so the state the cloud
replays on connect finds it.
void setup() {
Serial.begin(115200);
Fluxgrid.onReceive("relay", [](FluxValue v) {
if (v.asBool()) Serial.println("Switch: ON");
else Serial.println("Switch: OFF");
});
Fluxgrid.begin();
}
void loop() { Fluxgrid.run(); } // run() is what delivers itGive the callback a name
Docs ↗Same call, a plain function instead of a lambda — easier to read once the
handler is more than a line or two, and one function can serve several handles.
Pass the name, with no ().
void onSwitch(FluxValue v) { // takes a FluxValue, returns void
digitalWrite(2, v.asBool() ? HIGH : LOW);
}
void setup() {
Fluxgrid.onReceive("relay", onSwitch);
Fluxgrid.begin();
}Poll with read() instead of a callback
Docs ↗Right when you want the current state every loop — digitalWrite(2, Fluxgrid.read("relay").asBool()) needs no memory. Wrong for "it just
changed": loop() runs thousands of times a second, so you end up writing the
edge detection onReceive() already did for you.
bool last = false;
void loop() {
Fluxgrid.run();
bool now = Fluxgrid.read("relay").asBool();
if (now != last) { // without this: thousands of lines a second
last = now;
Serial.println(now ? "Switch: ON" : "Switch: OFF");
}
}Convert an incoming value
Docs ↗read() and the onReceive() lambda both hand you a FluxValue. It converts on
demand, and is empty until the first value arrives.
FluxValue v = Fluxgrid.read("speed");
if (!v.isEmpty()) analogWrite(5, v.asInt()); // .asFloat() .asBool() .asString()Do something on a timer
delay() stalls run(), so the link goes quiet and the board can read offline.
Use a millis() gate for anything slow (a DHT read, a WiFi scan, an HTTP call).
unsigned long last = 0;
void loop() {
Fluxgrid.run();
if (millis() - last < 2000) return;
last = millis();
Fluxgrid.write("temp", readSensor());
}Print to the dashboard's serial monitor
Docs ↗Fluxgrid.print() / println() go to the USB Serial Monitor and to a
Terminal widget, so you can watch a board you can't reach.
Fluxgrid.println("pump on");
Fluxgrid.debug(2); // 0 silent · 1 events · 2 events + every valueBlink the board's own LED
Docs ↗No GPIO number, no wiring — the library uses whatever the board declares.
Fluxgrid.led(true); // mono LED on
Fluxgrid.led(0, 40, 0); // RGB LED greenWidget quick reference74
What the firmware sends or receives for each widget, and the handle a freshly dropped one gets. Users rename handles freely — always use the handle the dashboard actually shows.
Gauge
The device publishes. Default handle gauge (number).
Fluxgrid.write("gauge", value);Value
The device publishes. Default handle value (number).
Fluxgrid.write("value", value);Chart
The device publishes. Default handle chart (number).
Fluxgrid.write("chart", value);LED
The device publishes. Default handle led (boolean).
Fluxgrid.write("led", state);Radial
The device publishes. Default handle radial (number).
Fluxgrid.write("radial", value);Stat
The device publishes. Default handle stat (number).
Fluxgrid.write("stat", value);Bar
The device publishes. Default handle bar (number).
Fluxgrid.write("bar", value);Level
The device publishes. Default handle level (number).
Fluxgrid.write("level", value);Battery
The device publishes. Default handle battery (number).
Fluxgrid.write("battery", value);Table
The device publishes. Default handle table (number).
Fluxgrid.write("table", value);7-Segment
The device publishes. Default handle segment (number).
Fluxgrid.write("segment", value);Sensor Group
Binds 3 datastreams — sensor1, sensor2, status. Publishing only the first leaves the rest dark.
Fluxgrid.write("sensor1", state); // Sensor 1
Fluxgrid.write("sensor2", state); // Sensor 2
Fluxgrid.write("status", "OK"); // StatusButton
The dashboard writes, the device reacts. Default handle button (boolean).
Fluxgrid.onReceive("button", [](FluxValue v) {
// v.asBool()
});Switch
The dashboard writes, the device reacts. Default handle switch (boolean).
Fluxgrid.onReceive("switch", [](FluxValue v) {
// v.asBool()
});Slider
The dashboard writes, the device reacts. Default handle slider (number).
Fluxgrid.onReceive("slider", [](FluxValue v) {
// v.asFloat()
});Switch Group
Binds 3 datastreams — light1, light2, light3. Publishing only the first leaves the rest dark.
Fluxgrid.write("light1", state); // Light 1
Fluxgrid.write("light2", state); // Light 2
Fluxgrid.write("light3", state); // Light 3Knob
The dashboard writes, the device reacts. Default handle knob (number).
Fluxgrid.onReceive("knob", [](FluxValue v) {
// v.asFloat()
});Stepper
The dashboard writes, the device reacts. Default handle stepper (number).
Fluxgrid.onReceive("stepper", [](FluxValue v) {
// v.asFloat()
});Segmented
The dashboard writes, the device reacts. Default handle segmented (boolean).
Fluxgrid.onReceive("segmented", [](FluxValue v) {
// v.asBool()
});Joystick
Binds 2 datastreams — x, y. Publishing only the first leaves the rest dark.
Fluxgrid.write("x", value); // Joystick X
Fluxgrid.write("y", value); // Joystick YColor
The dashboard writes, the device reacts. Default handle color (number).
Fluxgrid.onReceive("color", [](FluxValue v) {
// v.asFloat()
});RGB
Binds 3 datastreams — red, green, blue. Publishing only the first leaves the rest dark.
Fluxgrid.write("red", value); // R
Fluxgrid.write("green", value); // G
Fluxgrid.write("blue", value); // BIcon Tile
The dashboard writes, the device reacts. Default handle tile (boolean).
Fluxgrid.onReceive("tile", [](FluxValue v) {
// v.asBool()
});Time Input
The dashboard writes, the device reacts. Default handle time (number).
Fluxgrid.onReceive("time", [](FluxValue v) {
// v.asFloat()
});Keypad
The dashboard writes, the device reacts. Default handle setpoint (number).
Fluxgrid.onReceive("setpoint", [](FluxValue v) {
// v.asFloat()
});Piano
Docs ↗Binds 2 datastreams — note, seq. Publishing only the first leaves the rest dark.
Fluxgrid.write("note", value); // Piano Note
Fluxgrid.write("seq", "OK"); // Piano SeqJukebox
Docs ↗Binds 2 datastreams — song, play. Publishing only the first leaves the rest dark.
Fluxgrid.write("song", "OK"); // Jukebox Song
Fluxgrid.write("play", state); // Jukebox PlayRemote Control
The dashboard writes, the device reacts. Default handle remote (text).
Fluxgrid.onReceive("remote", [](FluxValue v) {
// v.asString()
});Health
Binds 3 datastreams — heartrate, spo2, pi. Publishing only the first leaves the rest dark.
Fluxgrid.write("heartrate", value); // Heart Rate
Fluxgrid.write("spo2", value); // Blood Oxygen
Fluxgrid.write("pi", value); // Perfusion IndexTerminal
The device publishes. Default handle log (text).
Fluxgrid.write("log", "OK");JSON
The device publishes. Default handle data (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("data", payload);LCD 1602
The device publishes. Default handle lcd (text).
Fluxgrid.write("lcd", "OK");Camera
The device publishes. Default handle camera (number).
Fluxgrid.write("camera", value);Map
Docs ↗The device publishes. Default handle map (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("map", payload);Fleet Map
The device publishes. Default handle fleetmap (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("fleetmap", payload);Status Grid
The device publishes. Default handle statusgrid (number).
Fluxgrid.write("statusgrid", value);Alarm Table
The device publishes. Default handle alarmtable (number).
Fluxgrid.write("alarmtable", value);Breathalyzer
The device publishes. Default handle breathalyzer (number).
Fluxgrid.write("breathalyzer", value);Reverse Sensor
The device publishes. Default handle parking (number).
Fluxgrid.write("parking", value);Radar
Binds 2 datastreams — radar, scan. Publishing only the first leaves the rest dark.
Fluxgrid.write("radar", payload); // Radar Data
Fluxgrid.write("scan", state); // Radar ControlCompass
Binds 3 datastreams — heading, field, cal. Publishing only the first leaves the rest dark.
Fluxgrid.write("heading", value); // Heading
Fluxgrid.write("field", value); // Field Strength
Fluxgrid.write("cal", value); // CalibrationAHRS
Binds 1 datastreams — attitude. Publishing only the first leaves the rest dark.
Fluxgrid.write("attitude", payload); // Attitude DataBike Computer
The device publishes. Default handle bike (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("bike", payload);Speedometer
Binds 6 datastreams — speed, dist, sat, hdop, hdg, fix. Publishing only the first leaves the rest dark.
Fluxgrid.write("speed", value); // Speed
Fluxgrid.write("dist", value); // Distance
Fluxgrid.write("sat", value); // Satellites
Fluxgrid.write("hdop", value); // HDOP
Fluxgrid.write("hdg", value); // Track
Fluxgrid.write("fix", value); // Fix TypeDevice Info
Docs ↗Binds a device, not a datastream. It fills in from the board's retained meta message — nothing to publish.
File Explorer
Docs ↗Binds a device. You mount the filesystem; the library exposes it — see File explorer.
LittleFS.begin(true);
Fluxgrid.addVolume("flash", LittleFS, FG_FLASH);
Fluxgrid.enableFiles(); // before begin()Memory
Docs ↗Binds 3 datastreams — free_heap, min_free_heap, max_alloc. Publishing only the first leaves the rest dark.
Fluxgrid.write("free_heap", value); // Free Heap
Fluxgrid.write("min_free_heap", value); // Min Free Heap
Fluxgrid.write("max_alloc", value); // Max Alloc BlockMemory Chart
Docs ↗Binds a device. Call reportMemory() once and the library publishes heap (and PSRAM) on a timer.
Fluxgrid.reportMemory(5000); // in setup(); 0 turns it offPower Monitor
Docs ↗Binds 2 datastreams — voltage, current. Publishing only the first leaves the rest dark.
Fluxgrid.write("voltage", value); // Bus Voltage
Fluxgrid.write("current", value); // Shunt CurrentPower Monitor 3CH
Docs ↗Binds 6 datastreams — ch1_v, ch1_a, ch2_v, ch2_a, ch3_v, ch3_a. Publishing only the first leaves the rest dark.
Fluxgrid.write("ch1_v", value); // CH1 Voltage
Fluxgrid.write("ch1_a", value); // CH1 Current
Fluxgrid.write("ch2_v", value); // CH2 Voltage
Fluxgrid.write("ch2_a", value); // CH2 Current
Fluxgrid.write("ch3_v", value); // CH3 Voltage
Fluxgrid.write("ch3_a", value); // CH3 CurrentMusic Player
Binds 9 datastreams — music, play, prev, next, volume, seek, shuffle, repeat, mute. Publishing only the first leaves the rest dark.
Fluxgrid.write("music", payload); // Music State
Fluxgrid.write("play", state); // Music Play
Fluxgrid.write("prev", value); // Music Prev
Fluxgrid.write("next", value); // Music Next
Fluxgrid.write("volume", value); // Music Volume
Fluxgrid.write("seek", value); // Music SeekWS2812 Panel
The dashboard writes, the device reacts. Default handle matrix (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.onReceive("matrix", [](FluxValue v) {
// v.asString()
});WiFi Scan
Docs ↗The device publishes. Default handle wifi (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("wifi", payload);Network Monitor
The device publishes. Default handle netscan (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("netscan", payload);Text Input
The dashboard writes, the device reacts. Default handle text (text).
Fluxgrid.onReceive("text", [](FluxValue v) {
// v.asString()
});Password
The dashboard writes, the device reacts. Default handle secret (text).
Fluxgrid.onReceive("secret", [](FluxValue v) {
// v.asString()
});Range Slider
Binds 2 datastreams — min, max. Publishing only the first leaves the rest dark.
Fluxgrid.write("min", value); // Range Low
Fluxgrid.write("max", value); // Range HighDropdown
The dashboard writes, the device reacts. Default handle select (number).
Fluxgrid.onReceive("select", [](FluxValue v) {
// v.asFloat()
});Week Selector
The dashboard writes, the device reacts. Default handle days (number).
Fluxgrid.onReceive("days", [](FluxValue v) {
// v.asFloat()
});Time Sync
The dashboard writes, the device reacts. Default handle clock (number).
Fluxgrid.onReceive("clock", [](FluxValue v) {
// v.asFloat()
});File Upload
The dashboard writes, the device reacts. Default handle file (text).
Fluxgrid.onReceive("file", [](FluxValue v) {
// v.asString()
});Time Difference
The device publishes. Default handle since (number).
Fluxgrid.write("since", value);Pie Chart
The device publishes. Default handle pie (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("pie", payload);Doughnut
The device publishes. Default handle donut (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("donut", payload);Bar Chart
The device publishes. Default handle bars (json). The payload is a fixed JSON shape — the editor's Sample Code window has it.
Fluxgrid.write("bars", payload);Feedback
The device publishes. Default handle status (text).
Fluxgrid.write("status", "OK");Temperature
The device publishes. Default handle temp (number).
Fluxgrid.write("temp", value);Humidity
The device publishes. Default handle humidity (number).
Fluxgrid.write("humidity", value);Air Quality
The device publishes. Default handle air (number).
Fluxgrid.write("air", value);Energy
The device publishes. Default handle energy (number).
Fluxgrid.write("energy", value);Card
The device publishes. Default handle card (number).
Fluxgrid.write("card", value);ESP Partition
A browser-side tool: it computes a partitions.csv for your board. No device, no datastream, no firmware.
OTA Update
Binds a device. Shows whether the board is ready for a wireless update — arm it with enableOTA() before begin().
Fluxgrid.enableOTA("ota-password");When it doesn't work6
The device never comes online
Docs ↗In order: the three #defines are above the #include; the token is this
device's (each device has its own); the WiFi is 2.4 GHz; the region matches the
dashboard you are signed in to. Turn on Fluxgrid.debug(1) and watch the USB
serial monitor — it says which step failed.
A tile stays blank
Docs ↗Almost always a handle mismatch: the string in write() is not the handle on the
widget. Open More → Datastreams and compare. For a widget that binds several
datastreams, every slot has its own handle — publishing only the first leaves the
rest dark.
A control widget does nothing
Docs ↗In order: the handle in onReceive() is the widget's; it was registered
before begin(); loop() still calls run() every pass; and nothing in the
callback blocks — it runs inside run(), so a delay() or a wait loop there
stalls the link. Set a flag and do the slow work in loop(). A second
onReceive() on the same handle replaces the first, it does not chain.
You are on the China cloud
Docs ↗A device belongs to exactly one region; its credentials do not exist on the
other. One line, before begin():
Fluxgrid.region("cn");A big payload never arrives
Docs ↗MQTT messages are capped by a buffer that defaults small. Raise it above the include — a WiFi scan or a long JSON object silently exceeds the default.
#define FLUXGRID_MQTT_BUFFER 2048
#include <Fluxgrid.h>Re-flashing over WiFi
Docs ↗Call before begin(), then pick the board's network port in the IDE. The board
needs an OTA-capable partition scheme, or the update has nowhere to land.
Fluxgrid.enableOTA("ota-password");