1. Find the board
Most Arduino-class boards report a recognisable manufacturer string. Match on it with findPorts():
import { SerialPilot } from 'serialpilot'const ports = await SerialPilot.findPorts({ manufacturer: /arduino/i }) if (ports.length === 0) throw new Error(‘no Arduino found’)
const port = new SerialPilot({ path: ports[0].path, baudRate: 115200 })
If you know the exact device, match by vendorId/productId instead — they're stable across hosts and OSes.
2. Pick a baud rate
| Family | Common rates |
|---|---|
| Arduino Uno / Nano / Mega | 9600 or 115200 |
| ESP8266 / ESP32 | 115200 |
| Teensy | baud rate ignored — pick anything |
3. Wait for the boot banner
Many boards reset on serial connect. The first bytes you write may vanish into the bootloader. Pipe through ReadyParser and wait for the device's banner before sending real traffic:
import { SerialPilot, ReadyParser } from 'serialpilot'const port = new SerialPilot({ path: ‘/dev/ttyACM0’, baudRate: 115200 }) const ready = port.pipe(new ReadyParser({ delimiter: ‘READY’ }))
ready.on(‘ready’, () => { console.log(‘Arduino is up’) port.write(‘PING\n’) })
Have your sketch print READY\n in setup(). Anything received before the banner is buffered; everything after flows as normal stream data.
Putting it together
import { SerialPilot, ReadyParser, ReadlineParser } from 'serialpilot'const [info] = await SerialPilot.findPorts({ manufacturer: /arduino/i }) if (!info) throw new Error(‘plug it in’)
const port = new SerialPilot({ path: info.path, baudRate: 115200 }) const ready = port.pipe(new ReadyParser({ delimiter: ‘READY’ })) const lines = ready.pipe(new ReadlineParser({ delimiter: ‘\n’ }))
ready.on(‘ready’, () => port.write(‘PING\n’)) lines.on(‘data’, line => console.log(’<-’, line))
setTimeout(() => port.write('PING\n'), 1500). Crude but reliable for stock Arduino bootloaders.