Real-time Arduino Cloud integration using Next.js (App Router), SSE, and MQTT.
- Node.js 18+
- Arduino Cloud account
- Arduino IoT API credentials with iot:read (and iot:write if needed)
- Install deps
pnpm i- Configure env
Create .env.local in project root:
API_CLIENT_ID=your_client_id_here
API_CLIENT_SECRET=your_client_secret_here
THING_ID=your_thing_id_hereNotes:
- Restart dev server after changes to env
- Run
pnpm dev- Server-side REST fetch for initial properties:
src/app/api/arduino/route.ts - Real-time stream via SSE:
src/app/api/arduino/stream/route.ts - MQTT subscriptions via
arduino-iot-js:src/lib/arduino-mqtt.ts - Client UI that consumes SSE and updates instantly:
src/components/arduino-data.tsx
- On client mount, an
EventSourcesubscribes to/api/arduino/stream - The stream handler:
- Fetches initial properties via REST
- Connects to Arduino IoT Cloud via MQTT using
clientId/clientSecret - Subscribes to each property with
ArduinoIoTCloud.onPropertyValue(thingId, variableName, cb) - Emits updates to the client as SSE messages
- A keep-alive comment is sent every 30s to keep intermediaries from closing the SSE connection
-
401 Unauthorized when fetching token
- Your API credentials are wrong or malformed
-
Disconnects quickly
- Ensure you’re using
ArduinoIoTCloud.connect({ clientId, clientSecret })(not a token) - Ensure the network allows WSS to
wss.iot.arduino.cc:8443
- Ensure you’re using
src/lib/arduino-cloud.ts– REST utilitiessrc/lib/arduino-mqtt.ts– MQTT connect/subscribesrc/app/api/arduino/stream/route.ts– SSE streamsrc/components/arduino-data.tsx– Live UI
For live coding with multiple artists:
- All artists connect to same WiFi network
- Each artist finds their IP (e.g.,
192.168.1.100) - Each artist starts listening on their chosen port (e.g., SuperCollider on 57120)
- You add their IPs as OSC targets in the app
- Click "Start OSC" - data flows to all artists instantly!
See NETWORK_SETUP.md for detailed instructions.
Note: 127.0.0.1 is localhost (your computer only). For other computers, use their actual IP address like 192.168.1.100.
- Don't expose credentials client-side; they're only used server-side
- Consider rotating credentials and adding retry/backoff for robustness
- If you need two-way control, add write endpoints using the REST or MQTT send APIs