Build embedded projects with less friction
Dexmod combines an Arduino-focused code workspace, AI assistance, project libraries, GitHub export, Web Serial tools, and a live telemetry dashboard in one browser-based workflow.
01
Create
Select a board and write or generate code.
02
Verify
Review problems, libraries, and AI suggestions.
03
Observe
Read serial data and visualize telemetry.
First project
Quick start
- 1
Create an account
Register with email and password, Google, or GitHub.
- 2
Create a project
Open Project Manager, choose New project, name it, and select the target board.
- 3
Write or ask AI
Edit main.ino directly or ask the AI Assistant to explain, diagnose, or generate code.
- 4
Add dependencies
Open Libraries to install a registry library or upload a compatible ZIP library.
- 5
Save and test
Changes are autosaved. Use Problems, Output, and Serial Monitor to inspect the project.
Workspace
Projects and the editor
Each project stores its name, selected board, source files, installed libraries, and project-specific AI conversation history. The editor remembers the active file during navigation and saves file changes automatically.
Project Manager
Create, import, rename, duplicate, delete, and open projects. Plan limits determine the maximum number of stored projects.
Editor workspace
Work with multiple Arduino and header files, select a target board, manage libraries, export code, and open the AI panel.
Assisted coding
AI Assistant
The assistant receives the active file as context. It can answer in the language used by the user, explain code, locate likely issues, and apply generated code to the editor. Review pin assignments, hardware assumptions, and safety-related behavior before uploading.
- Use precise hardware names, board type, pins, libraries, and expected behavior.
- Ask for telemetry output when the project will use Serial Dashboard.
- Use Undo after an applied response if the generated code is not suitable.
- AI output can be incorrect; compilation and hardware validation remain necessary.
Create an ESP32 temperature monitor using a DHT22 on GPIO 4.
Print temperature and humidity as one JSON object every second
so Dexmod Serial Dashboard can visualize both values.Hardware targets
Boards and libraries
Choose the board that matches the physical target before compiling or uploading. The current catalog includes Arduino Uno, Nano, Mega, Leonardo, Nano Every, Uno R4 WiFi, ESP32, ESP32-S3, NodeMCU ESP8266, and Raspberry Pi Pico targets.
Local telemetry
Serial Monitor and Dashboard
Serial Monitor connects directly to an authorized device port. Console displays raw text, while Dashboard recognizes numeric telemetry and generates value cards and live charts automatically.
- Open the Serial Monitor tab below the editor.
- Select the same baud rate used by
Serial.begin(). - Click Connect and choose the correct USB serial device.
- Switch from Console to Dashboard.
- Use Record to capture parsed samples, then Export CSV.
void setup() {
Serial.begin(115200);
}
void loop() {
float temperature = 28.4;
float humidity = 72.0;
Serial.print("{\"temperature\":");
Serial.print(temperature);
Serial.print(",\"humidity\":");
Serial.print(humidity);
Serial.println("}");
delay(1000);
}Dashboard Builder
After telemetry is detected, choose Customize to rename metrics, add units, select Line, Number, Gauge, or Status widgets, hide metrics, and reorder the layout. Select Save layout to store the configuration for the current project in this browser.
Metric and widget count
The Dashboard is not limited to three labels. The demo creates three widgets because it sends only temperature, humidity, and motorRpm. Every new numeric telemetry key automatically creates another configurable widget after its first sample arrives.
{"temperature":28.4,"humidity":72,"pressure":1012,"motorRpm":1250,"voltage":12.3,"current":1.8}This sample creates six metrics. There is currently no fixed widget limit, but keeping approximately 12–20 visible widgets per dashboard is recommended for readability and browser performance. Hide less important metrics or split very large systems into focused dashboards.
Data reference
Supported telemetry formats
Send one complete sample per line. JSON is recommended because metric names remain explicit and values stay synchronized.
JSON — recommended
{"temperature":28.4,"humidity":72,"motor":true}Numbers and numeric strings become chart values. JSON booleans become 1 or 0.
Key-value
temperature=28.4 humidity=72 motorRpm=1280CSV with header
temperature,humidity,motorRpm
28.4,72,1280
28.7,71,1310Cloud telemetry · Phase 2
Remote IoT Monitoring
Remote IoT Monitoring lets an internet-connected device send numeric telemetry to Dexmod without remaining connected to the browser by USB. Open a project and select Monitor, then create a device. Dexmod displays its secret token only once and stores only a cryptographic hash.
- Create a device inside the project's Remote Monitor.
- Copy the one-time token into secure device configuration.
- POST a flat JSON object to
/api/iot/ingestwith the token as a Bearer credential. - Keep the monitor open to receive live updates through its authenticated stream.
- Customize labels, units, ranges, and widget types with Dashboard Builder.
POST /api/iot/ingest HTTP/1.1
Authorization: Bearer dxm_DEVICE_ID.SECRET
Content-Type: application/json
Idempotency-Key: boot-42-sample-1001
{"temperature":28.4,"humidity":72,"pump":true}A sample may contain 1–32 metrics. Metric names must start with a letter and values must be finite numbers or booleans. Each request is limited to 8 KB.
Complete ESP32 example
This local-network example connects an ESP32 to Wi-Fi and sends one JSON sample to Dexmod. Replace the Wi-Fi values, laptop IP address, and one-time device token before uploading it.
#include <WiFi.h>
#include <HTTPClient.h>
const char* WIFI_NAME = "YOUR_WIFI_NAME";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
// Use your laptop's LAN IP, not localhost.
const char* DEXMOD_URL =
"http://192.168.1.10:3000/api/iot/ingest";
const char* DEVICE_TOKEN =
"dxm_DEVICE_ID.SECRET";
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Wi-Fi connected");
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
WiFiClient client;
HTTPClient http;
http.begin(client, DEXMOD_URL);
http.addHeader("Content-Type", "application/json");
http.addHeader(
"Authorization",
String("Bearer ") + DEVICE_TOKEN
);
float temperature = 28.4;
int humidity = 72;
bool pump = true;
String payload =
"{"temperature":" + String(temperature, 1) +
","humidity":" + String(humidity) +
","pump":" + String(pump ? "true" : "false") +
"}";
int statusCode = http.POST(payload);
Serial.print("Dexmod response: ");
Serial.println(statusCode);
Serial.println(http.getString());
http.end();
}
delay(60000); // Free plan: minimum 60 seconds
}Production HTTPS
After publishing Dexmod, change the endpoint to the public HTTPS domain and use WiFiClientSecure. Validate the server certificate with the certificate authority used by the deployed domain.
#include <WiFiClientSecure.h>
const char* DEXMOD_URL =
"https://app.example.com/api/iot/ingest";
WiFiClientSecure secureClient;
HTTPClient http;
// ROOT_CA must contain the trusted CA certificate.
secureClient.setCACert(ROOT_CA);
http.begin(secureClient, DEXMOD_URL);EMQX MQTT over TLS
MQTT devices publish to the project-independent topic below. Replace DEVICE_ID with the ID shown in Remote Monitor. The token inside the message must belong to the same device ID.
Topic:
dexmod/devices/DEVICE_ID/telemetry
Payload:
{"token":"dxm_DEVICE_ID.SECRET","messageId":"boot-42-sample-1001","metrics":{"temperature":28.4,"humidity":72,"pump":true}}Use a new stable messageId for each logical sample. If QoS 1 delivers the same ID and payload again, Dexmod acknowledges it without storing another row. Reusing an ID with different metrics is rejected.
Connect to the EMQX Serverless address with MQTT over TLS on port 8883. Install the downloaded emqxsl-ca.crt on the device, then use the MQTT username and password created in EMQX. The broker credentials open the TLS connection; the Dexmod token authorizes telemetry for a specific device.
Test with MQTTX
- Keep
npm run mqtt:workerrunning in its own terminal. - Create an MQTTX connection using the exact deployment host shown in EMQX Cloud. Do not use the public
broker.emqx.iohost. - Select
mqtts://, port8883, enable SSL/TLS and SSL Secure, then enter credentials from EMQX Access Control → Authentication. - Use a unique Client ID such as
mqttx-dexmod-test. Leave ALPN empty. The system CA option normally works; select the downloadedemqxsl-ca.crtif the connection cannot validate the server. - Publish with QoS 1 and Retain disabled to the device topic shown above.
Protocol: mqtts://
Host: YOUR_DEPLOYMENT.emqxsl.com
Port: 8883
Topic: dexmod/devices/DEVICE_ID/telemetry
QoS: 1
Retain: offWiFiClientSecure tlsClient;
PubSubClient mqtt(tlsClient);
tlsClient.setCACert(EMQX_ROOT_CA);
mqtt.setServer("YOUR_DEPLOYMENT.emqxsl.com", 8883);
mqtt.connect("esp32-device", MQTT_USERNAME, MQTT_PASSWORD);
String topic = "dexmod/devices/" + String(DEVICE_ID) + "/telemetry";
String messageId = "boot-" + String(esp_random(), HEX);
String payload =
"{\"token\":\"" + String(DEVICE_TOKEN) +
"\",\"messageId\":\"" + messageId +
"\",\"metrics\":{\"temperature\":28.4,\"humidity\":72}}";
mqtt.publish(topic.c_str(), payload.c_str());Response codes
| Code | Meaning | What the device should do |
|---|---|---|
| 202 | Sample accepted | Wait for the plan interval, then send the next sample. |
| 401 | Token invalid, rotated, or revoked | Stop retrying and install a new device token. |
| 422 | Telemetry format invalid | Check metric names and ensure values are numbers or booleans. |
| 423 | Device paused by its owner | Stop publishing until the owner resumes the device. |
| 429 | Messages sent too quickly | Read Retry-After or increase the loop delay. |
| 5xx | Temporary server problem | Retry later with increasing delays; do not retry continuously. |
History, fleet, and CSV
The project monitor summarizes its devices and shows total account usage against the current plan. Open Device fleet from Project Manager, Remote Monitor, or the account menu to search and filter every device across all projects, inspect online/offline/paused totals, open its project monitor, or pause and resume ingestion. Use the History buttons to inspect the available time window, then select Export CSV to download the filtered samples.
| Plan | Devices | Retention | Minimum interval |
|---|---|---|---|
| Free | 1 | 24 hours | 60 seconds |
| Maker | 3 | 7 days | 15 seconds |
| Pro | 10 | 90 days | 5 seconds |
| Team | 25 | 1 year | 1 second |
Source control
Upload projects to GitHub
Connect GitHub in Account settings, then use the GitHub button in the editor. Select an existing repository or create a public/private repository, choose a branch and optional folder, and upload all project files as one commit.
Dexmod also includes a .dexmod/project.json metadata file containing the board and library configuration. GitHub access tokens remain on the server and are never returned to the editor.
Physical hardware
Device upload
The upload workspace can select supported board targets and request Web Serial access. The current local build should be treated as a preview workflow: verify the compiled firmware and confirm that the target board reports the expected behavior before relying on it.
Help
Troubleshooting
No serial port appears+
Use desktop Chrome or Edge, reconnect the USB cable, install the board driver if required, and close other software using the port.
Console shows unreadable characters+
Set Dexmod baud rate to exactly the same value passed to Serial.begin().
Console works but Dashboard is empty+
Print numeric data as JSON, key=value, or CSV, and end every sample with a newline.
A metric does not update+
Check that the metric value is numeric. Free-form strings remain visible only in Console.
GitHub requests repository permission+
Open Account settings and reconnect GitHub to grant the repository scope used for commits.
An AI response is incomplete+
Reduce the requested scope, provide the active board and libraries, and split large changes into smaller prompts.
Ready to build?
Create a project, choose your board, and start with a small verified circuit.