Signatur
Beschreibung
Die Methode open() der Schnittstelle SerialPort stellt die eigentliche Verbindung zu einem seriellen Gerät her, etwa einem Arduino, einem Mikrocontroller, einem GPS-Empfänger oder einem USB-Seriell-Adapter. Ein SerialPort-Objekt bekommst du vorher über navigator.serial.requestPort() (Auswahl durch den Nutzer) oder über navigator.serial.getPorts() (Ports, für die bereits eine Berechtigung erteilt wurde).
Pflichtangabe ist die Baudrate (baudRate). Optional kannst du Datenbits, Stoppbits, Parität, Puffergröße und Flusssteuerung festlegen. Diese Werte müssen zu den Einstellungen des Geräts passen, sonst kommen nur unlesbare Daten an.
Wenn das zurückgegebene Promise erfüllt ist, stehen die Streams port.readable (ReadableStream) und port.writable (WritableStream) bereit. Über sie liest und schreibst du Rohbytes als Uint8Array. Zum Umwandeln in Text eignen sich TextDecoderStream und TextEncoderStream.
Ein Port kann nur einmal gleichzeitig geöffnet sein. Um die Verbindung zu beenden, gibst du zuerst alle Reader und Writer frei und rufst dann port.close() auf.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options Pflicht | SerialOptions | Objekt mit den Verbindungsparametern. Die folgenden Einträge beschreiben seine Eigenschaften. | |
| $options.baudRate Pflicht | number | Übertragungsrate in Bit pro Sekunde, z. B. 9600 oder 115200. Muss eine positive Ganzzahl sein. |
|
| $options.dataBits | number | 8 | Anzahl der Datenbits pro Zeichen: 7 oder 8. |
| $options.stopBits | number | 1 | Anzahl der Stoppbits am Ende jedes Zeichens: 1 oder 2. |
| $options.parity | "none" | "even" | "odd" | "none" | Paritätsprüfung. |
| $options.bufferSize | number | 255 | Größe der Lese- und Schreibpuffer in Byte. Muss kleiner als 16 MB sein. |
| $options.flowControl | "none" | "hardware" | "none" | Flusssteuerung: "hardware" nutzt die RTS/CTS-Leitungen. |
Rückgabewert
Promise, das mit undefined erfüllt wird, sobald der Port geöffnet ist. Danach sind port.readable und port.writable verfügbar.Beispiele
Port auswählen und öffnen
// Muss durch eine Nutzeraktion ausgelöst werden, z. B. einen Klick
const button = document.querySelector('#verbinden');
button.addEventListener('click', async () => {
try {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
console.log('Port geöffnet:', port.getInfo());
} catch (err) {
console.error('Öffnen fehlgeschlagen:', err.name, err.message);
}
});
Textzeilen von einem Arduino lesen
const leseZeilen = async (port) => {
await port.open({ baudRate: 115200, dataBits: 8, stopBits: 1, parity: 'none' });
// Bytes mit einem TextDecoderStream in Text umwandeln
const decoder = new TextDecoderStream();
const pipeFertig = port.readable.pipeTo(decoder.writable);
const reader = decoder.readable.getReader();
let puffer = '';
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
puffer += value;
const zeilen = puffer.split('\n');
puffer = zeilen.pop();
zeilen.forEach((z) => console.log('Empfangen:', z.trim()));
}
} finally {
reader.releaseLock();
}
};
const [port] = await navigator.serial.getPorts();
if (port) await leseZeilen(port);
Befehl senden und Port sauber schließen
const sendeBefehl = async (port, befehl) => {
await port.open({ baudRate: 9600, flowControl: 'hardware' });
const writer = port.writable.getWriter();
await writer.write(new TextEncoder().encode(`${befehl}\r\n`));
writer.releaseLock(); // Sperre freigeben, sonst schlägt close() fehl
await port.close();
console.log('Befehl gesendet, Port geschlossen');
};
const port = await navigator.serial.requestPort({
filters: [{ usbVendorId: 0x2341 }] // nur Arduino-Geräte anzeigen
});
await sendeBefehl(port, 'LED ON');
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Web Serial API gibt es nur in Chromium-Browsern auf dem Desktop (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Prüfe deshalb vorher mit
'serial' in navigator, ob sie vorhanden ist. - Sicherer Kontext: Die API funktioniert nur über HTTPS oder
localhost. In iframes muss die Permissions Policyserialerlaubt sein. - Fehlerfälle:
InvalidStateErrortritt auf, wenn der Port bereits geöffnet ist.NetworkErrortritt auf, wenn das Öffnen fehlschlägt, etwa weil ein anderes Programm (Arduino-IDE, serieller Monitor) den Port belegt.TypeErrortritt bei ungültigen Optionen auf, z. B. wennbaudRatefehlt oder0ist. - Schließen:
close()schlägt fehl, solangereadableoderwritabledurch einen Reader oder Writer gesperrt ist. Beende eine laufende Leseschleife daher mitreader.cancel()und gib danach die Sperre mitreleaseLock()frei. - Stimmen Baudrate, Parität oder Datenbits nicht mit dem Gerät überein, gibt es keinen Fehler. Es kommen dann einfach unlesbare Daten an.
- Viele Arduino-Boards starten neu, wenn der Port geöffnet wird. Plane deshalb eine kurze Wartezeit ein, bevor du Befehle sendest.