Flash once, then forget it
The firmware never changes again. Every experiment is a script edit and a rerun.
Your circuit board becomes an appliance. Plug it in and drive it from a script, the way you drive a printer.
Flash the firmware once. After that the board just listens, and everything clever stays on your computer, in the language you already use.
The same afternoon of work, before and after.
Not because the board got faster. Because you stopped rebuilding its program every time you had a thought.
A complete program. It runs on your computer. Nothing is compiled, nothing is uploaded.
import { ConduytDevice } from 'conduyt-js' import { SerialTransport } from 'conduyt-js/transports/serial'
Pick how you reach the board. SerialTransport is the USB cable. Swap this line for Bluetooth or WiFi later.
const device = await ConduytDevice.connect( new SerialTransport({ path: '/dev/ttyUSB0' }) )
Connect. The board reports its own pins and features, so your code never guesses.
await device.pin(13).mode('output')
Pin 13 is a metal leg, usually wired to the onboard LED. Output means you drive it, not read it.
await device.pin(13).write(1) // on await device.pin(13).write(0) // off
The LED lights, then goes dark. Ten bytes per line. Loop it and you have a blink.
const temp = await device.pin(0).read('analog') console.log('sensor:', temp)
It reads back too. Sensor values arrive as plain numbers you can log or chart.
npm install conduyt-jsimport { ConduytDevice } from 'conduyt-js' import { SerialTransport } from 'conduyt-js/transports/serial' const device = await ConduytDevice.connect( new SerialTransport({ path: '/dev/ttyUSB0' }) ) await device.pin(13).mode('output') await device.pin(13).write(1) const value = await device.pin(0).read('analog') console.log('sensor:', value)
The firmware never changes again. Every experiment is a script edit and a rerun.
One dashboard drives a 20 pin Arduino and a 34 pin ESP32, unchanged.
USB, Bluetooth, WiFi. Byte for byte identical messages. Swap one line, keep the rest.
Ten checksummed bytes to set a pin. No text to parse, no memory to allocate.
The entire message for turning on an LED.
43 44 spells CD in hex. Every packet starts with it. So does the logo.
The chip has kilobytes of memory. Parsing {"pin":13,"value":1} costs more than the actual work.
Fixed positions mean byte three says everything. The checksum catches a bad cable before it drives a motor wrong.
On connect the board describes itself. Your program builds its interface from that.
const caps = device.capabilities // list the pins this board really has pinSelect.innerHTML = caps.pins .map(p => `<option>${p.pin}</option>`).join('') // hide the servo controls if this board has none servoCard.hidden = !caps.modules.find(m => m.name === 'servo')
Write the page once. A bare Arduino shows 20 pins. A loaded ESP32 grows servo and pixel controls on its own.
| project | year | where it stops | conduyt |
|---|---|---|---|
| Firmata | 2006 | MIDI encoding, USB cable only | binary packets, any transport |
| Johnny-Five | 2012 | Node only, built on Firmata | five SDKs, native protocol |
| Blynk 2.0 | 2021 | needs their cloud | runs on your own machine |
| CircuitPython | 2017 | a language on the chip, not a link to your computer | your computer drives, board obeys |
One firmware library for the board. Five host SDKs for your computer.
#include <Conduyt.h>npm install conduyt-jspip install conduyt-pygo get github.com/virgilvox/conduyt/sdk/gocargo add conduytSwift Package ManagerNo. Flash the prebuilt firmware once, then write only in the language you already use. C++ comes up only if you add a new hardware feature.
The board holds its last state and waits. Anything that must survive alone belongs in the firmware.
Ten bytes, under a millisecond over USB. Fine for dashboards, robots, lighting, test rigs. Microsecond control loops belong on the chip either way.
No account, no server, no telemetry. Over USB it is a cable between two devices. MQTT and WebSocket point at a broker you run.
Eighteen boards ship prebuilt firmware: Uno R3 and R4, Mega, Nano, Leonardo, the ESP32 family, ESP8266, Pico, Teensy 3.6 through 4.1 and the nRF52840 DK. Anything else the Arduino toolchain targets can be built from source. Transport options vary by board.
Flash once. Then drive the board from a browser tab, a Python script or a Go service.