DEV Community

Cover image for Complete Introduction to WebSerial API
Malik Bagwala
Malik Bagwala

Posted on

Complete Introduction to WebSerial API

Introduction

Web Serial API is a new paradigm for fetching data from a USB or Serial Interface directly into the Website/Web app via JavaScript!

Compatibility

Image description

Tutorial

  1. Connect your serial device which transmits serial data (eg. ESP8266)

  2. Request access from the user

const port = await navigator.serial.requestPort()
Enter fullscreen mode Exit fullscreen mode

This code will open up a pop-up where the user can give you the permission for the appropriate device.

Note that this only needs to be done once until the user manually removes the access to the port

Image description

  1. Get list of all the available ports
const ports =  await navigator.serial.getPorts()
// returns a list of ports
Enter fullscreen mode Exit fullscreen mode
  1. Read data from the port
async function readSerial(port) {
  while (port.readable) {
    const reader = port.readable.getReader();
    try {
      for await (const { value, done } of reader) {
        if (done) {
          // |reader| has been canceled.
          break;
        }
        // Do something with |value|...
      }
    } catch (error) {
      // Handle |error|...
    } finally {
      reader.releaseLock();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. BONUS Tip

You can also add a LineBreakTransformer since most devices emit line by line data, which can significantly streamline your workflow

// LineBreakTransformer.js
class LineBreakTransformer {
  constructor() {
    // A container for holding stream data until a new line.
    this.container = "";
  }

  transform(chunk, controller) {
    // Handle incoming chunk
    this.container += chunk;
    const lines = this.container.split("\r\n");
    this.container = lines.pop();
    lines.forEach((line) => controller.enqueue(line));
  }

  flush(controller) {
    // Flush the stream.
    controller.enqueue(this.container);
  }
}

export default LineBreakTransformer;
Enter fullscreen mode Exit fullscreen mode

And then use this in your code

const decoder = new TextDecoderStream();
port.readable.pipeTo(decoder.writable);
const inputStream = decoder.readable.pipeThrough(
  new TransformStream(new LineBreakTransformer())
);
console.log(inputStream, "INPUT STREAM");
const reader = inputStream.getReader();

async function readSerial(port) {
  while (port.readable) {
    try {
      for await (const { value, done } of reader) {
        if (done) {
          // |reader| has been canceled.
          break;
        }
        // Do something with |value|...
      }
    } catch (error) {
      // Handle |error|...
    } finally {
      reader.releaseLock();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)