Start · Sprachen · JavaScript · Referenz · SerialPort.writable

SerialPort.writable

Eigenschaft

Gibt einen <code>WritableStream</code> zurück, über den Bytes an das an den seriellen Port angeschlossene Gerät gesendet werden. Ist der Port nicht geöffnet, ist der Wert <code>null</code>.

seit JavaScript Web Serial API – Chrome/Edge 89+, Opera 75+; nicht Kategorie: webapi

Signatur

get SerialPort.prototype.writable

Beschreibung

Die schreibgeschützte Eigenschaft writable der Schnittstelle SerialPort liefert einen WritableStream, der Uint8Array-Blöcke (bzw. andere BufferSource-Werte) annimmt und diese an das serielle Gerät weitergibt, z. B. an einen Mikrocontroller, einen 3D-Drucker oder ein Messgerät.

Der Stream existiert erst, wenn der Port mit port.open() geöffnet wurde. Vorher und nach dem Schließen gibt die Eigenschaft null zurück. Zum Schreiben holt man sich mit getWriter() einen WritableStreamDefaultWriter. Dieser sperrt den Stream, bis er mit releaseLock() wieder freigegeben wird.

Wer Text senden möchte, schaltet am besten einen TextEncoderStream davor und verbindet ihn mit pipeTo(). Tritt ein fataler Fehler auf, etwa weil das Gerät abgezogen wurde, wird der Stream fehlerhaft. Ein späterer Zugriff auf writable kann dann einen neuen Stream liefern, sofern der Port noch offen ist.

Rückgabewert

Typ
WritableStream<Uint8Array> | null
Beschreibung
Ein WritableStream für ausgehende Bytes, solange der Port geöffnet ist, sonst null.

Beispiele

Bytes an ein Gerät senden

// Muss durch eine Benutzeraktion (z. B. Klick) ausgelöst werden
const button = document.querySelector('#verbinden');

button.addEventListener('click', async () => {
  const port = await navigator.serial.requestPort();
  await port.open({ baudRate: 9600 });

  const writer = port.writable.getWriter();
  const daten = new Uint8Array([0x48, 0x69, 0x0a]); // "Hi\n"
  await writer.write(daten);

  // Sperre freigeben, damit der Port geschlossen werden kann
  writer.releaseLock();
  await port.close();
  console.log('Gesendet:', daten.length, 'Bytes');
});
Gesendet: 3 Bytes

Text per TextEncoderStream senden (z. B. G-Code)

const sendeBefehle = async (port, befehle) => {
  const encoder = new TextEncoderStream();
  const pipeFertig = encoder.readable.pipeTo(port.writable);
  const writer = encoder.writable.getWriter();

  for (const befehl of befehle) {
    await writer.write(`${befehl}\n`);
  }

  await writer.close(); // beendet auch die Pipe
  await pipeFertig;     // wartet, bis alles übertragen ist
};

// Nutzung mit einem bereits geöffneten Port:
// await sendeBefehle(port, ['G28', 'G1 X10 Y10']);

Status prüfen und sauber schließen

const trennen = async (port) => {
  if (port.writable === null) {
    console.log('Port ist nicht geöffnet');
    return;
  }
  const writer = port.writable.getWriter();
  try {
    await writer.write(new Uint8Array([0x04])); // EOT senden
  } catch (err) {
    console.error('Schreibfehler:', err);
  } finally {
    writer.releaseLock();
  }
  await port.close();
  console.log('Nach close():', port.writable);
};
Nach close(): null

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Web Serial API gibt es nur in Chromium-basierten Desktop-Browsern (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Vor der Nutzung mit 'serial' in navigator prüfen.
  • Nur in sicheren Kontexten: Die API funktioniert nur über HTTPS oder auf localhost. requestPort() muss durch eine Benutzeraktion ausgelöst werden. Mit der Permissions-Policy serial lässt sich die API sperren, etwa in iframes.
  • Sperre beachten: Solange ein Writer aktiv ist oder eine Pipe läuft, ist der Stream gesperrt. port.close() schlägt dann mit einem Fehler fehl. Deshalb vorher immer releaseLock() aufrufen oder den Writer bzw. die Pipe schließen.
  • Nur Binärdaten: writer.write('text') funktioniert nicht direkt. Text muss zuerst mit TextEncoder oder TextEncoderStream in Bytes umgewandelt werden.
  • Puffer: Die Größe des Ausgabepuffers legt die Option bufferSize bei open() fest. Ein erfülltes write()-Promise bedeutet nicht unbedingt, dass das Gerät die Daten schon empfangen hat.
  • Ist der Port nicht geöffnet, ist der Wert null. Ein Aufruf von port.writable.getWriter() wirft dann einen TypeError.