# Web Serial API

The Web Serial API provides a way for websites to read from and write to a serial device. These devices are connected via a serial port, or emulate a serial port over USB or Bluetooth.

## 1. The Concept

It bridges the web and the physical world by allowing communication with microcontrollers (like Arduino, ESP32), 3D printers, and other industrial hardware that uses serial communication (UART).

## 2. The Connection Flow

1.  **Request Port:** Ask the user to select a serial port.
2.  **Open:** Open the connection with specific parameters (baud rate).
3.  **Read/Write:** Use the Streams API (`ReadableStream`, `WritableStream`) to transfer data.

## 3. Requesting a Port

Like other hardware APIs, this requires a user gesture.

```javascript
const button = document.getElementById('connect-serial');

button.addEventListener('click', async () => {
  try {
    // Request a port (filters are optional)
    const port = await navigator.serial.requestPort({
        filters: [{ usbVendorId: 0x2341 }] // Example: Arduino
    });
    
    console.log('Port selected');
    await connectToPort(port);
  } catch (error) {
    console.error('Serial Error:', error);
  }
});
```

## 4. Connecting and Communicating

Opening a port requires a baud rate. Reading and writing use standard Web Streams.

```javascript
async function connectToPort(port) {
  // Open the port
  await port.open({ baudRate: 9600 });
  console.log('Port opened at 9600 baud');

  // Setup Writer
  const textEncoder = new TextEncoderStream();
  const writableStreamClosed = textEncoder.readable.pipeTo(port.writable);
  const writer = textEncoder.writable.getWriter();

  // Write data
  await writer.write("Hello Serial!");
  
  // Setup Reader
  const textDecoder = new TextDecoderStream();
  const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
  const reader = textDecoder.readable.getReader();

  // Read loop
  while (true) {
    const { value, done } = await reader.read();
    if (done) {
      // Allow the serial port to be closed later.
      reader.releaseLock();
      break;
    }
    if (value) {
      console.log('Received:', value);
    }
  }
}
```

## 5. Security and Privacy

*   **HTTPS:** Only works on secure contexts.
*   **User Gesture:** `requestPort` must be triggered by a user interaction.
*   **Permission:** The user must explicitly select the port.

## 6. Events

You can detect when ports are connected or disconnected.

```javascript
navigator.serial.addEventListener('connect', (e) => {
  console.log('Port connected', e.target);
});

navigator.serial.addEventListener('disconnect', (e) => {
  console.log('Port disconnected', e.target);
});
```

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/promises-async-await]]
[[programming/javascript/vanilla/webusb-api]]