### Full Bidirectional Serial Communication with TransformStream (JavaScript) Source: https://context7.com/wicg/serial/llms.txt Illustrates a complete example of bidirectional serial communication. It sets up encoder and decoder streams, uses a TransformStream for line breaks, and demonstrates sending a command ('AT') and receiving a response. ```javascript // Full bidirectional communication example async function serialTerminal(port) { // Set up encoder/decoder streams const encoder = new TextEncoderStream(); const decoder = new TextDecoderStream(); const writableStreamClosed = encoder.readable.pipeTo(port.writable); const readableStreamClosed = port.readable.pipeTo(decoder.writable); const writer = encoder.writable.getWriter(); const reader = decoder.readable .pipeThrough(new TransformStream(new LineBreakTransformer())) .getReader(); // Send command and wait for response await writer.write('AT\r\n'); const { value } = await reader.read(); console.log('Response:', value); // Expected: OK // Cleanup reader.cancel(); await readableStreamClosed.catch(() => {}); writer.close(); await writableStreamClosed; } ``` -------------------------------- ### Requesting Serial Port Access Source: https://context7.com/wicg/serial/llms.txt This section covers how to request access to a serial port using `navigator.serial.requestPort()`. It includes examples for requesting any available port, filtering by USB Vendor ID, and requesting Bluetooth serial ports. ```APIDOC ## GET /serial/requestPort ### Description Prompts the user to select a serial port from available devices. This method requires user activation and returns a Promise that resolves with the selected SerialPort object. Filters can be provided to limit the devices shown to the user. ### Method GET ### Endpoint `navigator.serial.requestPort()` ### Parameters #### Query Parameters - **filters** (object[]): Optional. An array of filter objects to limit the devices shown to the user. Each filter object can specify `usbVendorId`, `usbProductId`, `usbVendorId`, or `bluetoothServiceClassId`. - **allowedBluetoothServiceClassIds** (string[]): Optional. An array of UUIDs for Bluetooth service classes to allow. ### Request Example ```javascript // Basic port request document.getElementById('connect').addEventListener('click', async () => { try { const port = await navigator.serial.requestPort(); console.log('Port selected:', port); } catch (e) { console.error('User cancelled or error occurred:', e); } }); // Filtered request for Arduino devices const connectArduino = async () => { try { const filter = { usbVendorId: 0x2341 }; const port = await navigator.serial.requestPort({ filters: [filter] }); return port; } catch (e) { throw new Error('No Arduino device selected'); } }; // Request Bluetooth serial port const connectBluetoothDevice = async () => { const port = await navigator.serial.requestPort({ allowedBluetoothServiceClassIds: ['e8e10f95-1a70-4b27-9ccf-02010264e9c8'] }); return port; }; ``` ### Response #### Success Response (200) - **port** (SerialPort): The selected serial port object. #### Response Example ```json { "port": { /* SerialPort object */ } } ``` ``` -------------------------------- ### Closing Serial Port After Writing Data Source: https://github.com/wicg/serial/blob/main/index.html This example demonstrates how to write data to a serial port and then close the port. It ensures that all buffered data is transmitted before closing by awaiting the writer.close() promise. This is a common pattern when sending a final message or command. ```javascript const encoder = new TextEncoder(); const writer = port.writable.getWriter(); writer.write(encoder.encode("A long message that will take...")); await writer.close(); await port.close(); ``` -------------------------------- ### Handle Serial Port Request with Button Click (JavaScript) Source: https://github.com/wicg/serial/blob/main/index.html This example illustrates how to trigger the serial port request upon a user clicking a button, ensuring the transient activation requirement is met. It includes a try-catch block to handle potential errors, such as the user dismissing the device selection prompt. The `navigator.serial.requestPort()` method is called within the event listener. ```javascript const connectButton = document.getElementById("connect"); connectButton.addEventListener('click', () => { try { const port = await navigator.serial.requestPort(); // Continue connecting to the device attached to |port|. } catch (e) { // The prompt has been dismissed without selecting a device. } }); ``` -------------------------------- ### Handle Serial Port Connect/Disconnect Events in JavaScript Source: https://context7.com/wicg/serial/llms.txt Listen for 'connect' and 'disconnect' events on both the navigator.serial object and individual SerialPort instances. These events are crucial for managing device availability and updating the user interface or application state accordingly. The example demonstrates basic logging and outlines optional actions like auto-connecting or UI updates. ```javascript // Listen for device connections on navigator.serial avigator.serial.addEventListener('connect', (event) => { const port = event.target; console.log('Device connected:', port); // Optionally auto-connect or update UI }); avigator.serial.addEventListener('disconnect', (event) => { const port = event.target; console.log('Device disconnected:', port); // Clean up and update UI }); // Listen on specific port // Assuming 'port' is a valid SerialPort object obtained previously // port.addEventListener('connect', () => { // console.log('Port reconnected'); // }); // port.addEventListener('disconnect', () => { // console.log('Port disconnected'); // }); ``` ```javascript // Complete device manager example class SerialDeviceManager { constructor() { this.connectedPorts = new Map(); navigator.serial.addEventListener('connect', this.onConnect.bind(this)); navigator.serial.addEventListener('disconnect', this.onDisconnect.bind(this)); } async initialize() { const ports = await navigator.serial.getPorts(); for (const port of ports) { if (port.connected) { await this.connectPort(port); } } } async onConnect(event) { await this.connectPort(event.target); } onDisconnect(event) { const port = event.target; this.connectedPorts.delete(port); console.log('Device removed'); } async connectPort(port) { // Ensure port is not already open before attempting to open if (!port.opened) { await port.open({ baudRate: 115200 }); this.connectedPorts.set(port, { connected: true }); console.log('Device ready'); } } } ``` -------------------------------- ### Piping Serial Data and Closing Port Source: https://github.com/wicg/serial/blob/main/index.html Shows how to pipe the serial port's readable stream through a TextDecoderStream and a custom LineBreakTransformer, then get a reader for the transformed stream. It also demonstrates canceling the reader and closing the port after the stream is closed. ```javascript const decoder = new TextDecoderStream(); const streamClosed = port.readable.pipeTo(decoder.writable); const lineReader = decoder.readable .pipeThrough(new TransformStream(new LineBreakTransformer())) .getReader(); lineReader.cancel(); await streamClosed; await port.close(); ``` -------------------------------- ### Read Serial Data as Strings with TextDecoderStream (JavaScript) Source: https://context7.com/wicg/serial/llms.txt Shows how to automatically convert incoming serial data chunks into strings using TextDecoderStream. This simplifies processing by piping the readable stream through the decoder before getting a reader. ```javascript async function readStrings(port) { const decoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(decoder.writable); const reader = decoder.readable.getReader(); try { while (true) { const { value, done } = await reader.read(); if (done) break; console.log('Received string:', value); } } finally { reader.releaseLock(); } } ``` -------------------------------- ### Get Available Serial Ports (JavaScript) Source: https://github.com/wicg/serial/blob/main/index.html Retrieves a list of all available serial ports that the user has granted access to. This is typically called when the page loads or when the user initiates an action to connect to a device. It returns a promise that resolves with an array of SerialPort objects. ```javascript document.addEventListener('DOMContentLoaded', async () => { let ports = await navigator.serial.getPorts(); // Populate the UI with options for the user to select or // automatically connect to devices. }); ``` -------------------------------- ### Exiting Read Loop Before Closing Port Source: https://github.com/wicg/serial/blob/main/index.html This example illustrates how to gracefully exit a reading loop before closing the serial port. It uses a flag `keepReading` and calls `reader.cancel()` to break the read loop. The port is then closed after the read loop has finished, ensuring no data is lost and the port is properly released. ```javascript let keepReading = true; let reader; async function readUntilClosed() { while (port.readable && keepReading) { reader = port.readable.getReader(); try { while (true) { const { value, done } = await reader.read(); if (done) { // |reader| has been canceled. break; } // Do something with |value|... } } catch (error) { // Handle |error|... } finally { reader.releaseLock(); } } await port.close(); } const closed = readUntilClosed(); // Sometime later... keepReading = false; reader.cancel(); await closed; ``` -------------------------------- ### GET SerialPort/getSignals() Source: https://github.com/wicg/serial/blob/main/index.html Retrieves the current status of the control signals asserted by the device connected to the serial port. ```APIDOC ## GET SerialPort/getSignals() ### Description Returns a Promise that resolves with a SerialInputSignals dictionary containing the current state of the serial control signals. The port must be in the "opened" state to successfully retrieve signals. ### Method GET ### Endpoint SerialPort.getSignals() ### Parameters None ### Request Example port.getSignals(); ### Response #### Success Response (200) - **dataCarrierDetect** (boolean) - Status of the Data Carrier Detect (DCD) signal. - **clearToSend** (boolean) - Status of the Clear To Send (CTS) signal. - **ringIndicator** (boolean) - Status of the Ring Indicator (RI) signal. - **dataSetReady** (boolean) - Status of the Data Set Ready (DSR) signal. #### Response Example { "dataCarrierDetect": true, "clearToSend": true, "ringIndicator": false, "dataSetReady": true } ``` -------------------------------- ### SerialPort.open Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Opens a connection to the selected serial port with the specified communication parameters. ```APIDOC ## POST SerialPort.open ### Description Initializes the connection to the serial port. The baud rate must be specified as it is required for hardware communication. ### Method POST ### Parameters #### Request Body - **baudRate** (Number) - Required - The speed at which the device communicates. ### Request Example { "baudRate": 9600 } ### Response #### Success Response (200) - **status** (String) - Connection established. ``` -------------------------------- ### Manage Serial Port Connections and Disconnections Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Illustrates how to detect and respond to serial port connection and disconnection events. It includes checking available ports on page load and listening for 'connect' and 'disconnect' events. ```javascript // Check to see what ports are available when the page loads. document.addEventListener('DOMContentLoaded', async () => { let ports = await navigator.serial.getPorts(); // Populate the UI with options for the user to select or automatically // connect to devices. }); navigator.serial.addEventListener('connect', e => { // Add |e.target| to the UI or automatically connect. }); navigator.serial.addEventListener('disconnect', e => { // Remove |e.target| from the UI. If the device was open the disconnection can // also be observed as a stream error. }); ``` -------------------------------- ### Opening a Serial Port Connection Source: https://context7.com/wicg/serial/llms.txt Establishes a connection to the serial port using `SerialPort.open()`. This method requires a baud rate and allows configuration of other serial communication parameters. After opening, `readable` and `writable` streams become available. ```APIDOC ## POST /serial/port/open ### Description Establishes a connection to the serial port with specified communication parameters. The baud rate is required; other parameters have sensible defaults. After opening, the `readable` and `writable` stream attributes become available. ### Method POST ### Endpoint `port.open(options)` ### Parameters #### Path Parameters - **port** (SerialPort) - Required - The SerialPort object obtained from `requestPort()`. #### Request Body - **baudRate** (number) - Required - The baud rate for the serial connection (e.g., 9600, 115200). - **dataBits** (number) - Optional - Number of data bits (7 or 8, default: 8). - **stopBits** (number) - Optional - Number of stop bits (1 or 2, default: 1). - **parity** (string) - Optional - Parity setting ('none', 'even', or 'odd', default: 'none'). - **bufferSize** (number) - Optional - Read/write buffer size (default: 255). - **flowControl** (string) - Optional - Flow control setting ('none' or 'hardware', default: 'none'). ### Request Example ```javascript // Open with baud rate only await port.open({ baudRate: 115200 }); // Open with full configuration await port.open({ baudRate: 9600, dataBits: 8, stopBits: 1, parity: 'none', bufferSize: 255, flowControl: 'none' }); // Complete connection workflow async function connectToDevice() { const port = await navigator.serial.requestPort(); await port.open({ baudRate: 115200 }); console.log('Port opened successfully'); return port; } ``` ### Response #### Success Response (200) - **status** (string): Indicates successful opening of the port. #### Response Example ```json { "status": "Port opened successfully" } ``` ``` -------------------------------- ### Check Serial Port Connection Status Source: https://github.com/wicg/serial/blob/main/EXPLAINER_BLUETOOTH.md Demonstrates how to retrieve authorized serial ports and use the SerialPort.connected attribute to determine if a device is ready for communication before attempting to open it. ```javascript let ports = await navigator.serial.getPorts(); for (let port of ports) { if (port.connected) { await port.open({baudRate: 115200}); } else { // Prompt the user to make sure the Bluetooth device is connectable to the system. // Once the user thinks the device is ready to connect, the user can press a // a button which runs `port.open` to trigger a connection attempt. } } ``` -------------------------------- ### Sending and Receiving Data with TextEncoder/Decoder Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Demonstrates sending commands and receiving responses using TextEncoder and TextDecoder to convert between strings and Uint8Arrays. Assumes a Hayes command set-like protocol. ```javascript const encoder = new TextEncoder(); const writer = port.writable.getWriter(); writer.write(encoder.encode("AT")); const decoder = new TextDecoder(); const reader = port.readable.getReader(); const { value, done } = await reader.read(); console.log(decoder.decode(value)); // Expected output: OK ``` -------------------------------- ### Manage Persistent Port Access Source: https://context7.com/wicg/serial/llms.txt Shows how to retrieve previously granted ports, auto-connect to specific hardware using USB identifiers, and revoke permissions using the forget method. ```javascript // Get all previously granted ports const ports = await navigator.serial.getPorts(); // Auto-connect to known device async function autoConnect() { const ports = await navigator.serial.getPorts(); for (const port of ports) { const info = port.getInfo(); if (info.usbVendorId === 0x2341) { await port.open({ baudRate: 115200 }); return port; } } return await navigator.serial.requestPort({ filters: [{ usbVendorId: 0x2341 }] }); } // Revoke permission for a port await port.forget(); ``` -------------------------------- ### Opening a Serial Port Connection Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Opens a connection to a previously requested serial port. The baud rate is a required parameter, and other parameters are optional. This prepares the port for data transfer. ```javascript await port.open({ baudRate: /* pick your baud rate */ }); ``` -------------------------------- ### Opening a Serial Port Connection (JavaScript) Source: https://context7.com/wicg/serial/llms.txt Establishes a connection to a serial port using specified communication parameters. The baud rate is mandatory, while other settings like data bits, stop bits, parity, buffer size, and flow control have defaults. After opening, `readable` and `writable` streams become available. ```javascript // Open with baud rate only (uses defaults for other parameters) await port.open({ baudRate: 115200 }); // Open with full configuration await port.open({ baudRate: 9600, dataBits: 8, // 7 or 8 (default: 8) stopBits: 1, // 1 or 2 (default: 1) parity: 'none', // 'none', 'even', or 'odd' (default: 'none') bufferSize: 255, // Read/write buffer size (default: 255) flowControl: 'none' // 'none' or 'hardware' (default: 'none') }); // Complete connection workflow async function connectToDevice() { const port = await navigator.serial.requestPort(); await port.open({ baudRate: 115200 }); console.log('Port opened successfully'); console.log('Readable stream:', port.readable); console.log('Writable stream:', port.writable); return port; } ``` -------------------------------- ### Requesting Serial Port Access with Filter Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Requests access to a serial port, optionally filtering by USB vendor ID. This is the initial step before opening a connection. It returns a SerialPort instance or throws an error if access is denied. ```javascript const filter = { usbVendorId: 0x2341 // Arduino SA }; try { const port = await navigator.serial.requestPort({filters: [filter]}); // Continue connecting to |port|. } catch (e) { // Permission to access a device was denied implicitly or explicitly by the user. } ``` -------------------------------- ### Extend Navigator and WorkerNavigator for Serial Access Source: https://github.com/wicg/serial/blob/main/index.html Defines the partial interfaces for Navigator and WorkerNavigator to expose the Serial object. These interfaces are exposed to Window and DedicatedWorker contexts respectively, ensuring secure access to serial hardware. ```WebIDL [Exposed=Window, SecureContext] partial interface Navigator { [SameObject] readonly attribute Serial serial; }; [Exposed=DedicatedWorker, SecureContext] partial interface WorkerNavigator { [SameObject] readonly attribute Serial serial; }; ``` -------------------------------- ### Sending and Receiving Data with Transform Streams Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Utilizes TextEncoderStream and TextDecoderStream to simplify sending and receiving string data over the serial port. `pipeTo()` connects the transforms to the port's streams. ```javascript const encoder = new TextEncoderStream(); const writableStreamClosed = encoder.readable.pipeTo(port.writable); const writer = encoder.writable.getWriter(); writer.write("AT"); const decoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(decoder.writable); const reader = decoder.readable.getReader(); const { value, done } = await reader.read(); console.log(value); // Expected output: OK ``` -------------------------------- ### navigator.serial.requestPort Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Requests permission from the user to access a specific serial device, optionally filtered by hardware properties. ```APIDOC ## POST navigator.serial.requestPort ### Description Prompts the user to select a serial device. If filters are provided, the selection is restricted to devices matching those criteria. ### Method POST ### Parameters #### Request Body - **filters** (Array) - Optional - A list of objects containing USB vendor IDs or product IDs to filter available devices. ### Request Example { "filters": [{ "usbVendorId": 0x2341 }] } ### Response #### Success Response (200) - **port** (SerialPort) - The selected serial port instance. #### Response Example { "port": "SerialPortInstance" } ``` -------------------------------- ### SerialPort getInfo() Method Logic Source: https://github.com/wicg/serial/blob/main/index.html Outlines the process for the getInfo() method, which retrieves information about the serial port. It populates a SerialPortInfo object with relevant details based on the port's type (USB or Bluetooth). ```javascript function getInfo() { let info = {}; // If USB device: // info.usbVendorId = ...; // info.usbProductId = ...; // If Bluetooth device: // info.bluetoothServiceClassId = ...; return info; } ``` -------------------------------- ### Requesting Serial Port Access (JavaScript) Source: https://context7.com/wicg/serial/llms.txt Prompts the user to select a serial port. Supports basic requests, filtered requests by vendor ID, and Bluetooth serial connections with specific service class IDs. Requires user activation and returns a Promise resolving with a SerialPort object. ```javascript // Basic port request - shows all available serial ports document.getElementById('connect').addEventListener('click', async () => { try { const port = await navigator.serial.requestPort(); console.log('Port selected:', port); // Continue connecting to the device } catch (e) { console.error('User cancelled or error occurred:', e); } }); // Filtered request - only show Arduino devices (USB Vendor ID 0x2341) const connectArduino = async () => { try { const filter = { usbVendorId: 0x2341 }; const port = await navigator.serial.requestPort({ filters: [filter] }); return port; } catch (e) { throw new Error('No Arduino device selected'); } }; // Request Bluetooth serial port with non-standard service const connectBluetoothDevice = async () => { const port = await navigator.serial.requestPort({ allowedBluetoothServiceClassIds: ['e8e10f95-1a70-4b27-9ccf-02010264e9c8'] }); return port; }; // Filter for specific Bluetooth service class const connectBluetoothSerial = async () => { const port = await navigator.serial.requestPort({ filters: [{ bluetoothServiceClassId: 0x1101 }] // Standard Serial Port Profile }); return port; }; ``` -------------------------------- ### Handle Transform Stream Closing with Serial Port Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Demonstrates how to properly close a serial port when using transform streams. It involves closing the writer, awaiting the writable stream closure, canceling the reader, and handling potential errors before finally closing the port. ```javascript writer.close(); await writableStreamClosed; reader.cancel(); await readableStreamClosed.catch(reason => {}); await port.close(); ``` -------------------------------- ### Handle Serial Port Connection Events (JavaScript) Source: https://github.com/wicg/serial/blob/main/index.html Listens for 'connect' events, which are fired when a serial device is connected to the system and the browser has permission to access it. The event target is the SerialPort object that has been connected. This allows for dynamic UI updates or automatic connections. ```javascript navigator.serial.addEventListener('connect', e => { // Add |e.target| to the UI or automatically connect. }); ``` -------------------------------- ### SerialPort onconnect Event Handler Logic Source: https://github.com/wicg/serial/blob/main/index.html Describes the steps executed when a serial port becomes logically connected. It updates the port's connection state and fires a 'connect' event. ```javascript // When a serial port becomes logically connected: let port = /* SerialPort instance */; port.connected = true; // Fire a 'connect' event at the port. ``` -------------------------------- ### Control Serial Port Signals (DTR, RTS, Break) Source: https://context7.com/wicg/serial/llms.txt Demonstrates how to set output signals like DTR, RTS, and Break for hardware handshaking or device resets, and how to read input signals such as DCD, CTS, RI, and DSR. ```javascript // Set Data Terminal Ready (DTR) signal await port.setSignals({ dataTerminalReady: true }); await port.setSignals({ dataTerminalReady: false }); // Set Request To Send (RTS) signal await port.setSignals({ requestToSend: true }); // Set multiple signals at once await port.setSignals({ dataTerminalReady: true, requestToSend: true }); // Send break signal await port.setSignals({ break: true }); await new Promise(resolve => setTimeout(resolve, 100)); await port.setSignals({ break: false }); // Read input signals const signals = await port.getSignals(); console.log('Data Carrier Detect (DCD):', signals.dataCarrierDetect); console.log('Clear To Send (CTS):', signals.clearToSend); console.log('Ring Indicator (RI):', signals.ringIndicator); console.log('Data Set Ready (DSR):', signals.dataSetReady); // Arduino reset sequence (toggle DTR to enter bootloader) async function resetArduino(port) { await port.setSignals({ dataTerminalReady: false }); await new Promise(resolve => setTimeout(resolve, 200)); await port.setSignals({ dataTerminalReady: true }); console.log('Arduino reset triggered'); } ``` -------------------------------- ### Read Data from Serial Port with Error Handling (JavaScript) Source: https://context7.com/wicg/serial/llms.txt Demonstrates a robust method for reading data from a serial port, including handling recoverable errors by creating new readers and managing fatal errors that set the readable stream to null. It decodes Uint8Array chunks into text. ```javascript async function readFromPort(port) { while (port.readable) { const reader = port.readable.getReader(); try { while (true) { const { value, done } = await reader.read(); if (done) { console.log('Reader cancelled'); break; } // value is a Uint8Array const text = new TextDecoder().decode(value); console.log('Received:', text); } } catch (error) { console.error('Read error (recoverable):', error); } finally { reader.releaseLock(); } } console.log('Port disconnected or fatal error'); } ``` -------------------------------- ### Validate HTML with Tidy Source: https://github.com/wicg/serial/blob/main/CONTRIBUTING.md Uses HTML5 Tidy to clean and validate the index.html file against a specified configuration file. This is a mandatory step before submitting a Pull Request to ensure document standards are met. ```Bash tidy -config tidyconfig.txt -o index.html index.html ``` -------------------------------- ### SerialPort Readable Stream - Pull Algorithm Source: https://github.com/wicg/serial/blob/main/index.html Describes the steps involved when the readable stream needs to pull data from the SerialPort. This includes checking desired size, reading from the OS, and enqueuing data or handling errors. ```APIDOC ## SerialPort Readable Stream - Pull Algorithm ### Description This algorithm defines how data is read from the serial port and made available to the readable stream. It handles desired buffer sizes, OS reads, and various error conditions. ### Method Internal Algorithm (triggered by stream) ### Endpoint N/A (Internal to SerialPort object) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example (This is an internal process, no direct request example) ### Response #### Success Response (Implicit) - **view** (Uint8Array or BufferSource) - The enqueued data chunk. #### Response Example (Internal data handling, no direct response example) ### Error Handling - **BufferOverrunError** (DOMException) - If a buffer overrun occurs. - **BreakError** (DOMException) - If a break condition is detected. - **FramingError** (DOMException) - If a framing error occurs. - **ParityError** (DOMException) - If a parity error occurs. - **UnknownError** (DOMException) - For general operating system errors. - **NetworkError** (DOMException) - If the port is disconnected. ``` -------------------------------- ### Closing Serial Port After Continuous Reading Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Demonstrates how to close the serial port when reading continuously. It uses `reader.cancel()` to break the read loop and then closes the port. ```javascript await reader.cancel(); await port.close(); ``` -------------------------------- ### SerialOptions Dictionary Definition - Web IDL Source: https://github.com/wicg/serial/blob/main/index.html Defines the SerialOptions dictionary used for configuring serial port communication. It includes parameters like baudRate, dataBits, stopBits, parity, bufferSize, and flowControl. The baudRate is the only mandatory option. ```webidl dictionary SerialOptions { [EnforceRange] required unsigned long baudRate; [EnforceRange] octet dataBits = 8; [EnforceRange] octet stopBits = 1; ParityType parity = "none"; [EnforceRange] unsigned long bufferSize = 255; FlowControlType flowControl = "none"; }; ``` -------------------------------- ### Reading Data from Serial Port Source: https://github.com/wicg/serial/blob/main/index.html Demonstrates a robust pattern for reading data from a serial port using nested loops and error handling. It continuously reads data until an error occurs or the port is closed, with outer loop handling recoverable errors. ```javascript while (port.readable) { const reader = port.readable.getReader(); try { while (true) { const { value, done } = await reader.read(); if (done) { // |reader| has been canceled. break; } // Do something with |value|... } } catch (error) { // Handle |error|... } finally { reader.releaseLock(); } } ``` -------------------------------- ### Continuous Reading from Serial Port Stream Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Implements a loop to continuously read data from the serial port's readable stream. The loop breaks if the reader is canceled or an error occurs. ```javascript const reader = port.readable.getReader(); while (true) { const { value, done } = await reader.read(); if (done) { // |reader| has been canceled. break; } // Do something with |value|... } reader.releaseLock(); ``` -------------------------------- ### Retrieve Serial Port Signals using getSignals() Source: https://github.com/wicg/serial/blob/main/index.html The getSignals() method returns a promise that resolves to a SerialInputSignals object containing the current state of hardware control signals. It requires the port to be in an 'opened' state and performs the query in parallel, potentially throwing an InvalidStateError or NetworkError. ```javascript async function checkSignals(port) { try { const signals = await port.getSignals(); console.log("DCD:", signals.dataCarrierDetect); console.log("CTS:", signals.clearToSend); console.log("RI:", signals.ringIndicator); console.log("DSR:", signals.dataSetReady); } catch (error) { console.error("Failed to get signals:", error); } } ``` -------------------------------- ### Request Serial Port Without Filter (JavaScript) Source: https://github.com/wicg/serial/blob/main/index.html This snippet shows how to request a serial port without any specific filters, allowing the user to choose from all available serial devices. It relies on the user's selection through a browser prompt. The `navigator.serial.requestPort()` method is used, and the returned Promise resolves with a SerialPort object or rejects on cancellation or error. ```javascript const port = await navigator.serial.requestPort(); ``` -------------------------------- ### Control Serial Port DTR Signal Source: https://github.com/wicg/serial/blob/main/EXPLAINER.md Shows how to explicitly set serial port signals, specifically the Data Terminal Ready (DTR) signal. This is useful for interacting with devices like Arduino that enter programming mode when DTR is toggled. ```javascript await port.setSignal({ dataTerminalReady: false }); await new Promise(resolve => setTimeout(200, resolve)); await port.setSignal({ dataTerminalReady: true }); ``` -------------------------------- ### SerialPort Interface Definition (IDL) Source: https://github.com/wicg/serial/blob/main/index.html Defines the SerialPort interface, which represents a serial port connection. It includes event handlers for connection status, properties for connection state and data streams, and methods for opening, configuring, and closing the port. ```idl interface SerialPort : EventTarget { attribute EventHandler onconnect; attribute EventHandler ondisconnect; readonly attribute boolean connected; readonly attribute ReadableStream? readable; readonly attribute WritableStream? writable; SerialPortInfo getInfo(); Promise open(SerialOptions options); Promise setSignals(optional SerialOutputSignals signals = {}); Promise getSignals(); Promise close(); Promise forget(); }; ``` -------------------------------- ### Toggle DTR signal using setSignals Source: https://github.com/wicg/serial/blob/main/index.html Demonstrates how to programmatically toggle the Data Terminal Ready (DTR) signal on a serial port. This is commonly used to trigger programming modes on microcontrollers. ```javascript await port.setSignals({ dataTerminalReady: false }); await new Promise(resolve => setTimeout(resolve, 200)); await port.setSignals({ dataTerminalReady: true }); ``` -------------------------------- ### SerialPort Stream Closure Handling Source: https://github.com/wicg/serial/blob/main/index.html Defines the steps to take when a readable or writable stream associated with a SerialPort is closed or becomes null. ```APIDOC ## SerialPort Stream Closure Handling ### Description This procedure outlines the actions taken when a stream (readable or writable) associated with a SerialPort is closed or set to null. It ensures proper state management and promise resolution for pending close operations. ### Method Internal Procedure ### Endpoint N/A (Internal to SerialPort object) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example (This is an internal process, no direct request example) ### Response #### Success Response (Implicit) - **undefined** - If a pending close promise exists, it is resolved with undefined. #### Response Example (Internal state management, no direct response example) ### Error Handling None explicitly defined for this procedure. ``` -------------------------------- ### Write Data to Serial Port using WritableStream Source: https://github.com/wicg/serial/blob/main/index.html This snippet demonstrates how to write data to a serial port using the WritableStream. It utilizes TextEncoder to convert a DOMString to Uint8Array and writes it using the port's writable stream. The writer is then released, and the process includes error handling for potential transmission issues. ```javascript const encoder = new TextEncoder(); const writer = port.writable.getWriter(); await writer.write(encoder.encode("PING")); writer.releaseLock(); ``` -------------------------------- ### Serial Interface Definition Source: https://github.com/wicg/serial/blob/main/index.html Defines the Serial interface, which inherits from EventTarget. It provides methods to retrieve available ports and request access to new serial devices, while handling connection and disconnection events. ```WebIDL [Exposed=(DedicatedWorker, Window), SecureContext] interface Serial : EventTarget { attribute EventHandler onconnect; attribute EventHandler ondisconnect; Promise> getPorts(); [Exposed=Window] Promise requestPort(optional SerialPortRequestOptions options = {}); }; ``` -------------------------------- ### SerialPort Readable Stream - Cancel Algorithm Source: https://github.com/wicg/serial/blob/main/index.html Details the process of canceling the readable stream, which involves discarding any buffered data and handling the stream's closure. ```APIDOC ## SerialPort Readable Stream - Cancel Algorithm ### Description This algorithm handles the cancellation of the readable stream. It ensures that any pending data in the port's buffers is discarded and the stream is properly closed. ### Method Internal Algorithm (triggered by stream cancellation) ### Endpoint N/A (Internal to SerialPort object) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example (This is an internal process, no direct request example) ### Response #### Success Response (Implicit) - **undefined** - The promise resolves with undefined upon successful cancellation. #### Response Example (Internal data handling, no direct response example) ### Error Handling None explicitly defined for cancellation itself, but underlying OS operations could potentially fail. ``` -------------------------------- ### SerialOutputSignals dictionary definition Source: https://github.com/wicg/serial/blob/main/index.html Defines the structure of the SerialOutputSignals dictionary used to configure serial port output signals. ```webidl dictionary SerialOutputSignals { boolean dataTerminalReady; boolean requestToSend; boolean break; }; ``` -------------------------------- ### Request Serial Port with USB Vendor ID Filter (JavaScript) Source: https://github.com/wicg/serial/blob/main/index.html This snippet demonstrates how to request a serial port with a filter for a specific USB vendor ID. This is useful for targeting devices like Arduino boards. It requires the `navigator.serial.requestPort()` method and returns a Promise that resolves with a SerialPort object or rejects if the user cancels or an error occurs. ```javascript const filter = { usbVendorId: 0x2341 }; const port = await navigator.serial.requestPort({ filters: [filter] }); ``` -------------------------------- ### Line-Based Communication with TransformStream (JavaScript) Source: https://context7.com/wicg/serial/llms.txt Explains how to use a custom TransformStream, LineBreakTransformer, to split incoming serial data into complete lines based on newline characters. This is useful for protocols that use line-terminated messages. ```javascript // LineBreakTransformer - splits stream by newlines class LineBreakTransformer { constructor() { this.container = ''; } transform(chunk, controller) { this.container += chunk; const lines = this.container.split('\r\n'); this.container = lines.pop(); // Keep incomplete line lines.forEach(line => controller.enqueue(line)); } flush(controller) { controller.enqueue(this.container); } } // Set up line-based reading async function setupLineReader(port) { const decoder = new TextDecoderStream(); const lineTransform = new TransformStream(new LineBreakTransformer()); const readableStreamClosed = port.readable .pipeThrough(decoder) .pipeThrough(lineTransform); const reader = readableStreamClosed.getReader(); while (true) { const { value, done } = await reader.read(); if (done) break; console.log('Line received:', value); // Process complete line here } } ```