ESP32 / Arduino Guide
Push sensor data from an ESP32
This guide walks through connecting an ESP32 (or any Arduino-compatible board with WiFi) to EasyBoard. You'll have live sensor readings on a shared dashboard in about 15 minutes.
What you need
- ✓An ESP32 board (any variant — WROOM, S3, C3, etc.) connected to your computer
- ✓Arduino IDE or PlatformIO
- ✓An EasyBoard account with at least one dashboard and a couple of tiles created
- ✓Your dashboard ID and write token (find them in dashboard Settings)
- ✓The tile IDs you want to update (shown when you call the tiles API — step 2 below)
New to EasyBoard?
Sign up at easyboard.live — you'll get a dashboard and write token immediately. Add a Metric tile and a Text tile to start. You can always change or add more later.
Step 1 — Install libraries
Open the Arduino Library Manager (Sketch → Include Library → Manage Libraries) and install ArduinoJson by Benoit Blanchon. The WiFi and HTTPClient libraries are included with the ESP32 Arduino core and don't need a separate install.
// Required libraries — install via Arduino Library Manager:
// ArduinoJson by Benoit Blanchon (search: "ArduinoJson")
// WiFi built into ESP32 Arduino core
// HTTPClient built into ESP32 Arduino coreStep 2 — Create config.h
Create a file called config.h in your sketch folder. This keeps your credentials out of your main code file — important if you ever share your sketch or push it to GitHub.
// config.h ← add this filename to your .gitignore
#pragma once
#define WIFI_SSID "your-wifi-network-name"
#define WIFI_PASSWORD "your-wifi-password"
// Find these in your EasyBoard dashboard settings
#define DASHBOARD_ID "abc123xyz456"
#define WRITE_TOKEN "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
// Get tile IDs from: GET https://easyboard.live/api/d/<DASHBOARD_ID>/tiles
#define TILE_TEMP "your-temperature-tile-id"
#define TILE_HUMIDITY "your-humidity-tile-id"Keep config.h out of version control
Add config.h to your .gitignore. If you accidentally commit a write token and push it to a public repo, anyone can modify your dashboard. If that happens, regenerate the token immediately from your dashboard settings.
To find your tile IDs, open your browser and visit:
https://easyboard.live/api/d/<your-dashboard-id>/tilesThis returns a JSON array of all your tiles. Each tile has an id field — copy the IDs for the tiles you want to update and paste them into config.h.
Step 3 — The main sketch
The updateTile() function does all the work. Call it with a tile ID and any string value — numbers, status text, percentages, whatever the tile should show. Replace readTemperature() and readHumidity() with your actual sensor library calls.
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "config.h"
// ── EasyBoard update helper ───────────────────────────────────────────────────
// Call this from anywhere in your sketch to push a new value to a tile.
// value can be any string: "24.3", "Online", "87"
void updateTile(const char* tileId, const String& value) {
if (WiFi.status() != WL_CONNECTED) return; // skip if no WiFi
HTTPClient http;
String url = "https://easyboard.live/api/d/" DASHBOARD_ID "/tiles/" + String(tileId);
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " WRITE_TOKEN);
// Build request body: {"value": "24.3"}
StaticJsonDocument<64> doc;
doc["value"] = value;
String body;
serializeJson(doc, body);
int status = http.PATCH(body);
http.end();
if (status != 200) {
Serial.printf("[EasyBoard] Update failed: HTTP %d\n", status);
}
}
// ── WiFi connection ───────────────────────────────────────────────────────────
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi");
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println(" connected");
} else {
Serial.println(" failed — will retry");
}
}
// ── Your sensor read (replace with your actual sensor library) ───────────────
float readTemperature() { return 23.4; } // °C
float readHumidity() { return 58.2; } // %
// ── Main sketch ───────────────────────────────────────────────────────────────
void setup() {
Serial.begin(115200);
connectWiFi();
}
void loop() {
// Reconnect if WiFi dropped
if (WiFi.status() != WL_CONNECTED) connectWiFi();
float temp = readTemperature();
float humidity = readHumidity();
// Push to EasyBoard — values are always strings
updateTile(TILE_TEMP, String(temp, 1)); // "23.4"
updateTile(TILE_HUMIDITY, String(humidity, 0)); // "58"
delay(60000); // update every 60 seconds
}First time uploading?
Open the Serial Monitor (115200 baud) after uploading. You'll see the WiFi connection status and any update errors. Once it says "connected", check your EasyBoard dashboard — the tiles should show your first readings within a few seconds.
Counting events
If you have a Counter tile and want to increment it on each button press or trigger, use delta instead of value. This adds to the current count server-side, so rapid updates from multiple devices don't overwrite each other.
// Increment a counter tile by 1 (e.g. a visitor count)
// Use delta instead of value so rapid updates don't race each other
void incrementCounter(const char* tileId) {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
String url = "https://easyboard.live/api/d/" DASHBOARD_ID "/tiles/" + String(tileId);
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " WRITE_TOKEN);
http.PATCH("{\"delta\": 1}"); // add 1 to current count server-side
http.end();
}Updating multiple tiles at once
Calling updateTile() for each reading makes one HTTP request per tile. That works fine but uses more bandwidth and counts as multiple API calls. A batch PATCH sends them all in one request — one API call, one network round-trip.
// Update multiple tiles in one request — more efficient than calling
// updateTile() for each one separately.
void updateBatch() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
String url = "https://easyboard.live/api/d/" DASHBOARD_ID "/tiles";
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " WRITE_TOKEN);
// Build the batch payload
float temp = readTemperature();
float hum = readHumidity();
String body = "{\"updates\":[";
body += "{\"target\":{\"id\":\"" + String(TILE_TEMP) + "\"},";
body += "\"patch\":{\"value\":\"" + String(temp, 1) + "\"}},";
body += "{\"target\":{\"id\":\"" + String(TILE_HUMIDITY) + "\"},";
body += "\"patch\":{\"value\":\"" + String(hum, 0) + "\"}}";
body += "]}";
http.PATCH(body);
http.end();
}Update frequency
Free
60 updates / hour
About 1 per minute
Pro
1,000 updates / hour
About 1 every 3.6 seconds
A batch PATCH counts as one update regardless of how many tiles it touches. For sensors that update every few seconds, use batch requests to stay within limits. If you exceed your limit, the API returns HTTP 429 — check the Serial Monitor.
delay() blocks everything
The example uses delay(60000) for simplicity, but this blocks your entire sketch — button presses, sensor reads, and serial output all pause. For production use, replace it with a non-blocking timer using millis().