// Third-party WebUSB Arduino library
#include <WebUSB.h>

WebUSB WebUSBSerial(1 /* https:// */, "editor.p5js.org/shawn/full/tQA-v09N_");  // Landing page

#define Serial WebUSBSerial

const int ledPin = 13;
int inByte = 0;

void setup() {
  pinMode(ledPin, OUTPUT);

  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  
  Serial.begin(9600);
  while (!Serial) {
    ; // Wait for serial port to connect.
  }
  
  Serial.write("WebUSB!");
  Serial.flush();
  
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
}

void loop() {
  if (Serial) {
    digitalWrite(ledPin, LOW);
    delay(500);
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
    digitalWrite(ledPin, HIGH);
    inByte = Serial.read();
    Serial.write(inByte);
    Serial.flush();
    delay(10);
  }
}
const ARDUINO_ID = 0x2341;

let startButton;
let writeButton;
let serialDevice;
let decoder;
let encoder;
let count = 0;
let latestData = "Waiting...";

function setup() {
  createCanvas(400, 400);
  
  decoder = new TextDecoder();
  encoder = new TextEncoder();

  
  startButton = createButton("Start USB Connection");
  startButton.mousePressed(connectUSB);
  writeButton = createButton("Write Data");
  writeButton.mousePressed(function() {readWriteData(count); count++ });
}

function draw() {
  background(220);
  text(latestData,10,50);
}

async function readWriteData(dataToWrite) {
  let arraybuffer = encoder.encode(dataToWrite);
  let bytearraybuffer = new Uint8Array(arraybuffer);
  
  console.log("transferIn");
  try {
    const result = await serialDevice.transferIn(2, 64);
    const data = decoder.decode(result.data);
    console.log("Read:" + data);
    latestData = data;
    
    await serialDevice.transferOut(1,bytearraybuffer);
  } catch (e) {
    console.log('Error reading data', e);
  }
}

async function connectUSB() {
  try {
    serialDevice = await navigator.usb.requestDevice({ filters: [{ vendorId: ARDUINO_ID }] })
    console.log(serialDevice.productName);      // "Arduino XXXXX"
    console.log(serialDevice.manufacturerName); // "Arduino LLC"
    console.log(serialDevice); // See the configurations and interfaces
    await serialDevice.open(); // Begin a session.
    console.log("selectConfiguration");
    await serialDevice.selectConfiguration(1); // Select configuration 1 for the device.
    console.log("claimInterface");
    await serialDevice.claimInterface(0); // Request exclusive control over interface 0.
    console.log("selectAlternateInterface");
    await serialDevice.selectAlternateInterface(0,0);
    console.log("controlTransferOut");
    await serialDevice.controlTransferOut({
        requestType: 'class',
        recipient: 'interface',
        request: 0x22,
        value: 0x01,
        index: 0x00}); // Ready to receive data
  } catch(error) { 
    console.error(error); 
  }  
}

Interface Configuration

After you connect the device to your computer, you can see your USB info by using

console.log(serialDevice);

Then you can see your device’s info on the DevTool of Chrome.

Untitled

In this case, I used Arduino Micro and found out the interface number is 2.

Other boards

Some microcontrollers don’t support WebUSB arduino for several reasons.

Then you can use tinyUSB instead in that case. Here is the list of the link what the devices are supported by tinyUSB.

If you can find your board in this list, it’s actually easier to connect WebUSB than the previous way.

tinyusb/supported.rst at master · hathach/tinyusb

Using ESP32 S1 or other devices

Unfortunately, according to this page we can’t use Webusb with ESP S1 series.

You need to use Webserial instead.