Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Convert WebUSB article from WebFu #4095

Merged
merged 2 commits into from Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added src/site/content/en/blog/usb/hero.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
369 changes: 369 additions & 0 deletions src/site/content/en/blog/usb/index.md
@@ -0,0 +1,369 @@
---
title: Access USB Devices on the Web
subhead: |
The WebUSB API makes USB safer and easier to use by bringing it to the Web.
authors:
- beaufortfrancois
date: 2016-03-30
updated: 2020-10-19
hero: hero.jpg
thumbnail: thumbnail.jpg
alt: A photo of an Arduino Micro board
description: |
The WebUSB API makes USB safer and easier to use by bringing it to the Web.
tags:
- blog # blog is a required tag for the article to show up in the blog.
- capabilities
- devices
feedback:
- api
---

If I said plain and simple "USB", there is a good chance that you will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be either:

If I said plainly and simply "USB"...

or

If I said "plain and simple USB"...

I think the first is closer to what you're after.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

immediately think of keyboards, mice, audio, video and storage devices. You're
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
immediately think of keyboards, mice, audio, video and storage devices. You're
immediately think of keyboards, mice, audio, video, and storage devices. You're

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

right but you'll find other kinds of Universal Serial Bus (USB) devices out
there.

These non-standardized USB devices require hardware vendors to write native
drivers and SDKs in order for you (the developer) to take advantage of them.
Sadly this native code has historically prevented these devices from being used
by the Web. And that's one of the reasons the WebUSB API has been created: to
provide a way to expose USB device services to the Web. With this API, hardware
manufacturers will be able to build cross-platform JavaScript SDKs for their
devices.
But most importantly this will **make USB safer and easier to use by bringing
it to the Web**.

Let's see what you could expect with the WebUSB API:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Let's see what you could expect with the WebUSB API:
Let's see the behavior you could expect with the WebUSB API:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The language is a little more specific.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


1. Buy a USB device.
2. Plug it into your computer.
3. A notification appears right away, with the right website to go to for this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. Plug it into your computer.
3. A notification appears right away, with the right website to go to for this
2. Plug it into your computer. A notification appears right away, with the right website to go to for this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A best practice is that the steps always begin with the user action. Responses of a system are tacked to the end of the steps that initiated them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

device.
4. Simply click on it. Website is there and ready to use!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4. Simply click on it. Website is there and ready to use!
4. Click the notification. The website is there and ready to use!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

5. Click to connect and a USB device chooser shows up in Chrome, where you can
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
5. Click to connect and a USB device chooser shows up in Chrome, where you can
5. Click to connect and a USB device chooser shows up in Chrome where you can

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

pick your device.
6. Tada!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
6. Tada!
Tada!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the result of a procedure should be a paragraph after the procedure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


What would this procedure be like without the WebUSB API?

- Read a box, label, or search on line and possibly end up on the wrong website.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be numbered.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the next few steps I suggest a rewrite to make this follow the same standards as I've outlined above.

- Have to install a native application.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Have to install a native application.
- Install a native application.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
As noted by @kaycebasques, I'm now using "platform-specific" instead of "native"

- Is it supported on my operating system? Make sure you download the "right"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Is it supported on my operating system? Make sure you download the "right"
- If it's even supported on my operating system, verify that I've downloaded the right

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

thing.
- Scary OS prompts popup and warn you about installing drivers/applications from
the Internet.
- Malfunctioning code harms the whole computer. The Web is built to [contain
malfunctioning websites].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Scary OS prompts popup and warn you about installing drivers/applications from
the Internet.
- Malfunctioning code harms the whole computer. The Web is built to [contain
malfunctioning websites].
- Install the thing. If you're lucky, you'll get no scary OS prompts or popups
warning you about installing drivers/applications from the internet. If you're
unlucky, the installed drivers or applications malfunction and harm your
computer. (Remember, the web is built to [contain malfunctioning websites]).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

- Only use the USB device once? On the Web, the website is gone once you closed
tab. On a computer the code sticks around.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Only use the USB device once? On the Web, the website is gone once you closed
tab. On a computer the code sticks around.
- If you only use the feature once, the code stays on your computer until you think to remove it. (On the Web, the space for unused is eventually reclaimed.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


## Before we start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Before we start
## Before I start

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


This article assumes you have some basic knowledge of how USB works. If not, I
recommend reading [USB in a NutShell]. For background information about USB,
check out the [official USB specifications].

The [WebUSB API] is available in Chrome 61.

### Available for Origin Trials

In order to get as much feedback as possible from developers using the WebUSB
API in the field, we've previously added this feature in Chrome 54 and Chrome
57 as an [origin trial].

The latest trial has successfully ended in September 2017.

## Privacy and security

### HTTPS only

Because this experimental API is a powerful new feature added to the Web, it is
made available only to [secure contexts]. This means you'll need to build with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Because this experimental API is a powerful new feature added to the Web, it is
made available only to [secure contexts]. This means you'll need to build with
Because of this feature's power, it only works on [secure contexts]. This means you'll need to build with

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

TLS in mind.

### User gesture required

As a security feature, getting access to connected USB devices with
`navigator.usb.requestDevice` must be called via a user gesture
like a touch or mouse click.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
As a security feature, getting access to connected USB devices with
`navigator.usb.requestDevice` must be called via a user gesture
like a touch or mouse click.
As a security precaution, `navigator.usb.requestDevice()` may only
be called through a user gesture such as a touch or mouse click.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


### Feature Policy

A feature policy is a mechanism that allows developers to selectively enable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A feature policy is a mechanism that allows developers to selectively enable
A [feature policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Feature_Policy)
is a mechanism that allows developers to selectively enable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

and disable various browser features and APIs. It can be defined via a HTTP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
and disable various browser features and APIs. It can be defined via a HTTP
and disable various browser features and APIs. It can be defined via an HTTP

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

header and/or an iframe "allow" attribute.

You can define a feature that controls whether the usb attribute is exposed on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can define a feature that controls whether the usb attribute is exposed on
You can define a feature policy that controls whether the usb attribute is exposed on

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

the Navigator object, or in other words if you allow WebUSB.

Below is an example of a header policy where WebUSB is not allowed:

```http
Feature-Policy: fullscreen "*"; usb "none"; payment "self" https://payment.example.com
```

Below is another example of a different container policy where USB is allowed:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Below is another example of a different container policy where USB is allowed:
Below is another example of a container policy where USB is allowed:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


```html
<iframe allowpaymentrequest allow="usb; fullscreen"></iframe>
```

## Let's start coding

The WebUSB API relies heavily on JavaScript [Promises]. If you're not familiar
with them, check out this great [Promises tutorial]. One more thing, `() => {}`
are simply ECMAScript 2015 [Arrow functions] -- they have a shorter syntax
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
are simply ECMAScript 2015 [Arrow functions] -- they have a shorter syntax
are simply ECMAScript 2015 [Arrow functions]. They have a shorter syntax

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need to explain promises and arrow functions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted in #4090, I've removed the explanation but kept links as developers interested in Bluetooth or USB may not necessarily be web developers.

compared to function expressions and lexically bind the `this` value.

### Get access to USB devices

You can either prompt the user to select a single connected USB device using
`navigator.usb.requestDevice` or call `navigator.usb.getDevices` to get a list
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`navigator.usb.requestDevice` or call `navigator.usb.getDevices` to get a list
`navigator.usb.requestDevice()` or call `navigator.usb.getDevices()` to get a list

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

of all connected USB devices the origin has access to.

The `navigator.usb.requestDevice` function takes a mandatory JavaScript object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The `navigator.usb.requestDevice` function takes a mandatory JavaScript object
The `navigator.usb.requestDevice()` function takes a mandatory JavaScript object

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

that defines `filters`. These filters are used to match any USB device with the
given vendor (`vendorId`) and optionally product (`productId`) identifiers. The
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
given vendor (`vendorId`) and optionally product (`productId`) identifiers. The
given vendor (`vendorId`) and, optionally, product (`productId`) identifiers. The

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

`classCode`, `protocolCode`, `serialNumber`, and `subclassCode` keys can also be
defined there as well.

<figure class="w-figure">
<img src="./usb-device-chooser.png" class="w-screenshot" alt="Screenshot of the USB device user prompt in Chrome">
<figcaption class="w-figcaption">USB device user prompt.</figcaption>
</figure>

For instance, here's how to get access to a connected Arduino device configured
to allow the origin.

```js
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(device => {
console.log(device.productName); // "Arduino Micro"
console.log(device.manufacturerName); // "Arduino LLC"
})
.catch(error => { console.log(error); });
```

Before you ask, I didn't magically come up with this `0x2341` hexadecimal
number. I simply searched for the word "Arduino" in this [List of USB ID's].

The USB `device` returned in the fulfilled promise above has some basic, yet
important information about the device such as the supported USB version,
maximum packet size, vendor and product IDs, the number of possible
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
maximum packet size, vendor and product IDs, the number of possible
maximum packet size, vendor, and product IDs, the number of possible

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

configurations the device can have - basically all fields contained in the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
configurations the device can have - basically all fields contained in the
configurations the device can have. Basically it contains all fields in the

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

[device USB Descriptor].

For info, if a USB device announces its [support for WebUSB], as well as
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For info, if a USB device announces its [support for WebUSB], as well as
By the way, if a USB device announces its [support for WebUSB], as well as

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

defining a landing page URL, Chrome will show a persistent notification when the
USB device is plugged in. Clicking on this notification will open the landing page.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
USB device is plugged in. Clicking on this notification will open the landing page.
USB device is plugged in. Clicking this notification will open the landing page.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


<figure class="w-figure">
<img src="./web-usb-notification.png" class="w-screenshot" alt="Screenshot of the WebUSB notification in Chrome">
<figcaption class="w-figcaption">WebUSB notification.</figcaption>
</figure>

From there, you can simply call `navigator.usb.getDevices` and get access to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
From there, you can simply call `navigator.usb.getDevices` and get access to
From there, you can simply call `navigator.usb.getDevices()` and access to

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

your Arduino device as shown below.

```js
navigator.usb.getDevices().then(devices => {
devices.forEach(device => {
console.log(device.productName); // "Arduino Micro"
console.log(device.manufacturerName); // "Arduino LLC"
});
})
```

### Talk to an Arduino USB board

Okay, now let's see how easy it is to communicate from a WebUSB compatible
Arduino board over the USB port. Check out instructions at
[https://github.com/webusb/arduino] to WebUSB-enable your [sketches].

Don't worry, I'll cover all the WebUSB device methods mentioned below later in
this article.

```js
let device;

navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(selectedDevice => {
device = selectedDevice;
return device.open(); // Begin a session.
})
.then(() => device.selectConfiguration(1)) // Select configuration #1 for the device.
.then(() => device.claimInterface(2)) // Request exclusive control over interface #2.
.then(() => device.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x01,
index: 0x02})) // Ready to receive data
.then(() => device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5.
.then(result => {
const decoder = new TextDecoder();
console.log('Received: ' + decoder.decode(result.data));
})
.catch(error => { console.log(error); });
```

Please keep in mind that the WebUSB library we are using here is just
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Please keep in mind that the WebUSB library we are using here is just
Please keep in mind that the WebUSB library I'm using here is just

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

implementing one example protocol (based on the standard USB serial protocol)
and that manufacturers can create any set and types of endpoints they wish.
Control transfers are especially nice for small configuration commands as
they get bus priority and have a well defined structure.

And here's the sketch that has been uploaded to the Arduino board.

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

WebUSB WebUSBSerial(1 /* https:// */, "webusb.github.io/arduino/demos");

#define Serial WebUSBSerial

void setup() {
Serial.begin(9600);
while (!Serial) {
; // Wait for serial port to connect.
}
Serial.write("WebUSB FTW!");
Serial.flush();
}

void loop() {
// Nothing here for now.
}
```

The third-party [WebUSB Arduino library] used in the sample code above does
basically two things:
- The device acts as a WebUSB device enabling Chrome to read the [landing page
URL].
- It exposes a WebUSB Serial API that you may use to override the default one.

Let's look at the JavaScript code again. Once we get the `device` picked by the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Let's look at the JavaScript code again. Once we get the `device` picked by the
Look at the JavaScript code again. Once I get the `device` picked by the

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

user, `device.open` simply runs all platform-specific steps to start a session
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
user, `device.open` simply runs all platform-specific steps to start a session
user, `device.open()` runs all platform-specific steps to start a session

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

with the USB device. Then, we have to select an available USB Configuration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with the USB device. Then, we have to select an available USB Configuration
with the USB device. Then, I have to select an available USB Configuration

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

with `device.selectConfiguration`. Remember that a Configuration specifies how
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with `device.selectConfiguration`. Remember that a Configuration specifies how
with `device.selectConfiguration`. Remember that a configuration specifies how

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

the device is powered, its maximum power consumption and its number of
interfaces. Talking about interfaces, we also need to request exclusive access
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
interfaces. Talking about interfaces, we also need to request exclusive access
interfaces. Speaking of interfaces, I also need to request exclusive access

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

with `device.claimInterface` since data can only be transferred to an interface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with `device.claimInterface` since data can only be transferred to an interface
with `device.claimInterface()` since data can only be transferred to an interface

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

or associated endpoints when the interface is claimed. Finally calling
`device.controlTransferOut` is needed to set up the Arduino device with the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`device.controlTransferOut` is needed to set up the Arduino device with the
`device.controlTransferOut()` is needed to set up the Arduino device with the

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

appropriate commands to communicate through the WebUSB Serial API.

From there, `device.transferIn` performs a bulk transfer onto the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
From there, `device.transferIn` performs a bulk transfer onto the
From there, `device.transferIn()` performs a bulk transfer onto the

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

device to inform it that the host is ready to receive bulk data. Then, the
promise is fulfilled with a `result` object containing a [DataView] `data` that
has to be parsed appropriately.

For those who are familiar with USB, all of this should look pretty familiar.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For those who are familiar with USB, all of this should look pretty familiar.
If you're familiar with USB, all of this should look pretty familiar.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


### I want more

The WebUSB API lets you interact with the all USB transfer/endpoint types:

- CONTROL transfers, used to send or receive configuration or command
parameters to a USB device are handled with `controlTransferIn(setup,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parameters to a USB device are handled with `controlTransferIn(setup,
parameters to a USB device, are handled with `controlTransferIn(setup,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

length)` and `controlTransferOut(setup, data)`.
- INTERRUPT transfers, used for a small amount of time sensitive data are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- INTERRUPT transfers, used for a small amount of time sensitive data are
- INTERRUPT transfers, used for a small amount of time sensitive data, are

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

handled with the same methods as BULK transfers with
`transferIn(endpointNumber, length)` and `transferOut(endpointNumber, data)`.
- ISOCHRONOUS transfers, used for streams of data like video and sound are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- ISOCHRONOUS transfers, used for streams of data like video and sound are
- ISOCHRONOUS transfers, used for streams of data like video and sound, are

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

handled with `isochronousTransferIn(endpointNumber, packetLengths)` and
`isochronousTransferOut(endpointNumber, data, packetLengths)`.
- BULK transfers, used to transfer a large amount of non-time-sensitive data in
a reliable way are handled with `transferIn(endpointNumber, length)` and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
a reliable way are handled with `transferIn(endpointNumber, length)` and
a reliable way, are handled with `transferIn(endpointNumber, length)` and

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

`transferOut(endpointNumber, data)`.

You may also want to have a look at Mike Tsao's [WebLight project] which
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you verified that the project is still up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. I still have some devices as well ;)

provides a ground-up example of building a USB-controlled LED device designed
for the WebUSB API (not using an Arduino here). You'll find hardware, software,
and firmware.

## Tips

Debugging USB in Chrome is easier with the internal page `chrome://device-log`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the information on the Chrome pages up to date?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

where you can see all USB device related events in one single place.

<figure class="w-figure">
<img src="./web-usb-device-log-page.png" class="w-screenshot" alt="Screenshot of the device log page to debug WebUSB in Chrome">
<figcaption class="w-figcaption">Device log page in Chrome for debugging the WebUSB API.</figcaption>
</figure>

The internal page `chrome://usb-internals` also comes in handy and allows you
to simulate connection connection and disconnection of virtual WebUSB devices.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
to simulate connection connection and disconnection of virtual WebUSB devices.
to simulate connection connection and disconnection of virtual WebUSB devices.
Suggested change
to simulate connection connection and disconnection of virtual WebUSB devices.
to simulate connection and disconnection of virtual WebUSB devices.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

This is be useful for doing UI testing without the need for real hardware.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This is be useful for doing UI testing without the need for real hardware.
This is be useful for doing UI testing without real hardware.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


<figure class="w-figure">
<img src="./web-usb-internals-page.png" class="w-screenshot" alt="Screenshot of the internal page to debug WebUSB in Chrome">
<figcaption class="w-figcaption">Internal page in Chrome for debugging the WebUSB API.</figcaption>
</figure>

On most Linux systems, USB devices are mapped with read-only permissions by
default. To allow Chrome to open a USB device, you will need to add a new [udev
rule]. Create a file at `/etc/udev/rules.d/50-yourdevicename.rules` with the
following content:

```vim
SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
```

where `[yourdevicevendor]` is `2341` if your device is an Arduino for instance.
`ATTR{idProduct}` can also be added for a more specific rule. Make sure your
`user` is a member of the `plugdev` group. Then, just reconnect your device.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the plugdev group? How do I make sure I'm a member of it? Links will be fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a link that includes both answers.


## What's next
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this section need to be updated? I couldn't find any features for shared or service workers on Chrome Status. I did find this: https://www.chromestatus.com/features/5928209916887040

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I've missed this. You're right.
I've removed this "What's next" section


A second iteration of the WebUSB API will look at [Shared Worker] and [Service
Worker] support. Imagine for instance a security key website using the WebUSB
API that would install a service worker to act as a middle man to authenticate
users.

{% Aside %}
Microsoft OS 2.0 Descriptors used by the Arduino examples only work on Windows
8.1 and later. Without that Windows support still requires manual installation
of an INF file.
{% endAside %}

## Resources

- Stack Overflow: [https://stackoverflow.com/questions/tagged/webusb](https://stackoverflow.com/questions/tagged/webusb)
- WebUSB API Spec: [http://wicg.github.io/webusb/](https://wicg.github.io/webusb/)
- Chrome Feature Status: [https://www.chromestatus.com/feature/5651917954875392](https://www.chromestatus.com/feature/5651917954875392)
- Spec Issues: [https://github.com/WICG/webusb/issues](https://github.com/WICG/webusb/issues)
- Implementation Bugs: [http://crbug.com?q=component:Blink>USB](http://crbug.com?q=component:Blink>USB)
- WebUSB ❤ ️Arduino: [https://github.com/webusb/arduino](https://github.com/webusb/arduino)
- IRC: [#webusb](irc://irc.w3.org:6665/#webusb) on W3C's IRC
- WICG Mailing list: [https://lists.w3.org/Archives/Public/public-wicg/](https://lists.w3.org/Archives/Public/public-wicg/)
- WebLight project: [https://github.com/sowbug/weblight](https://github.com/sowbug/weblight)

Please share your WebUSB demos with the [#webusb] hashtag.

<!-- lint disable definition-case -->
[contain malfunctioning websites]: https://www.youtube.com/watch?v=29e0CtgXZSI
[USB in a NutShell]: http://www.beyondlogic.org/usbnutshell
[official USB specifications]: https://www.usb.org/
[WebUSB API]: https://wicg.github.io/webusb/
[origin trial]: https://github.com/GoogleChrome/OriginTrials/blob/gh-pages/developer-guide.md
[secure contexts]: https://w3c.github.io/webappsec/specs/powerfulfeatures/#intro
[Promises]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
[Promises tutorial]: /promises
[Arrow functions]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions
[List of USB ID's]: http://www.linux-usb.org/usb.ids
[device USB Descriptor]: http://www.beyondlogic.org/usbnutshell/usb5.shtml#DeviceDescriptors
[support for WebUSB]: https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
[https://github.com/webusb/arduino]: https://github.com/webusb/arduino
[sketches]: http://www.arduino.cc/en/Tutorial/Sketch
[WebUSB Arduino library]: https://github.com/webusb/arduino/tree/gh-pages/library/WebUSB
[landing page URL]: https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
[DataView]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
[WebLight project]: https://github.com/sowbug/weblight
[udev rule]: https://www.freedesktop.org/software/systemd/man/udev.html
[Shared Worker]: https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker
[Service Worker]: https://jakearchibald.github.io/isserviceworkerready/resources.html
[#webusb]: https://twitter.com/search?q=webusb
<!-- lint enable definition-case -->
Binary file added src/site/content/en/blog/usb/thumbnail.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.