Google Chrome V54

We had fun hosting thousands of developers at Chrome Dev Summit 2020! You can now watch all the sessions at goo.gle/cds20-sessions.
  1. Google Chrome V50 Download
  2. Google Chrome V41
  3. Google Chrome V64

Access USB Devices on the Web

If I said plainly and simply 'USB', there is a good chance that you willimmediately think of keyboards, mice, audio, video, and storage devices. You'reright but you'll find other kinds of Universal Serial Bus (USB) devices outthere.

Chrome is doing well being #1 browser and has no issue with just giving đź–• to all people with old GPUs. I am now hit by this shit and can no longer use chrome for webgl related work. In case anyone knows how to lift the GPU ban short of patching and recompiling Chrome, let me know. Google Chrome v54 and above (. See below) Opera v42 and above. Microsoft Edge (Chromium version) v80 and above (. See below) When you are on any of the pages in the site that support directly downloading to your CODE amplifier, you will see a status bar at the bottom of the page. This will indicate whether your browser is midi-capable.

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

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

  1. Buy a USB device.
  2. Plug it into your computer. A notification appears right away, with the rightwebsite to go to for this device.
  3. Click the notification. The website is there and ready to use!
  4. Click to connect and a USB device chooser shows up in Chrome where you canpick your device.

Tada!

What would this procedure be like without the WebUSB API?

  1. Install a platform-specific application.
  2. If it's even supported on my operating system, verify that I've downloadedthe right thing.
  3. Install the thing. If you're lucky, you'll get no scary OS prompts or popupswarning you about installing drivers/applications from the internet. Ifyou're unlucky, the installed drivers or applications malfunction and harmyour computer. (Remember, the web is built to contain malfunctioningwebsites).
  4. If you only use the feature once, the code stays on your computer until youthink to remove it. (On the Web, the space for unused is eventuallyreclaimed.)

Before I start #

This article assumes you have some basic knowledge of how USB works. If not, Irecommend 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 WebUSBAPI in the field, we've previously added this feature in Chrome 54 and Chrome57 as an origin trial.

The latest trial has successfully ended in September 2017.

Privacy and security #

HTTPS only #

Because of this feature's power, it only works on secure contexts. This meansyou'll need to build with TLS in mind.

User gesture required #

As a security precaution, navigator.usb.requestDevice() may onlybe called through a user gesture such as a touch or mouse click.

Feature Policy #

A feature policy is a mechanism that allows developers to selectively enableand disable various browser features and APIs. It can be defined via an HTTPheader and/or an iframe 'allow' attribute.

You can define a feature policy that controls whether the usb attribute isexposed on the Navigator object, or in other words if you allow WebUSB.

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

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

Let's start coding #

The WebUSB API relies heavily on JavaScript Promises. If you're not familiarwith them, check out this great Promises tutorial. One more thing, () => {}are simply ECMAScript 2015 Arrow functions.

Get access to USB devices #

You can either prompt the user to select a single connected USB device usingnavigator.usb.requestDevice() or call navigator.usb.getDevices() to get alist of all connected USB devices the origin has access to.

The navigator.usb.requestDevice() function takes a mandatory JavaScript objectthat defines filters. These filters are used to match any USB device with thegiven vendor (vendorId) and, optionally, product (productId) identifiers.The classCode, protocolCode, serialNumber, and subclassCode keys canalso be defined there as well.

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

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

Google Chrome V50 Download

The USB device returned in the fulfilled promise above has some basic, yetimportant information about the device such as the supported USB version,maximum packet size, vendor, and product IDs, the number of possibleconfigurations the device can have. Basically it contains all fields in thedevice USB Descriptor.

By the way, if a USB device announces its support for WebUSB, as well asdefining a landing page URL, Chrome will show a persistent notification when theUSB device is plugged in. Clicking this notification will open the landing page.

From there, you can simply call navigator.usb.getDevices() and access yourArduino device as shown below.

Talk to an Arduino USB board #

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

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

Please keep in mind that the WebUSB library I'm using here is just implementingone example protocol (based on the standard USB serial protocol) and thatmanufacturers can create any set and types of endpoints they wish.Control transfers are especially nice for small configuration commands asthey get bus priority and have a well defined structure.

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

The third-party WebUSB Arduino library used in the sample code above doesbasically two things:

  • The device acts as a WebUSB device enabling Chrome to read the landing pageURL.
  • It exposes a WebUSB Serial API that you may use to override the default one.

Look at the JavaScript code again. Once I get the device picked by the user,device.open() runs all platform-specific steps to start a session with the USBdevice. Then, I have to select an available USB Configuration withdevice.selectConfiguration(). Remember that a configuration specifies how thedevice is powered, its maximum power consumption and its number of interfaces.Speaking of interfaces, I also need to request exclusive access withdevice.claimInterface() since data can only be transferred to an interface orassociated endpoints when the interface is claimed. Finally callingdevice.controlTransferOut() is needed to set up the Arduino device with theappropriate commands to communicate through the WebUSB Serial API.

From there, device.transferIn() performs a bulk transfer onto thedevice to inform it that the host is ready to receive bulk data. Then, thepromise is fulfilled with a result object containing a DataViewdata thathas to be parsed appropriately.

If you're familiar with USB, all of this should look pretty familiar.

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 commandparameters to a USB device, are handled with controlTransferIn(setup, length) and controlTransferOut(setup, data).
  • INTERRUPT transfers, used for a small amount of time sensitive data, arehandled with the same methods as BULK transfers withtransferIn(endpointNumber, length) and transferOut(endpointNumber, data).
  • ISOCHRONOUS transfers, used for streams of data like video and sound, arehandled with isochronousTransferIn(endpointNumber, packetLengths) andisochronousTransferOut(endpointNumber, data, packetLengths).
  • BULK transfers, used to transfer a large amount of non-time-sensitive data ina reliable way, are handled with transferIn(endpointNumber, length) andtransferOut(endpointNumber, data).

Google Chrome V41

You may also want to have a look at Mike Tsao's WebLight project whichprovides a ground-up example of building a USB-controlled LED device designedfor 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-logwhere you can see all USB device related events in one single place.

Google chrome v44

The internal page chrome://usb-internals also comes in handy and allows youto simulate connection and disconnection of virtual WebUSB devices.This is be useful for doing UI testing without for real hardware.

On most Linux systems, USB devices are mapped with read-only permissions bydefault. To allow Chrome to open a USB device, you will need to add a new udevrule. Create a file at /etc/udev/rules.d/50-yourdevicename.rules with thefollowing content:

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 youruser is a member of the plugdev group. Then, just reconnect your device.

Microsoft OS 2.0 Descriptors used by the Arduino examples only work on Windows8.1 and later. Without that Windows support still requires manual installationof an INF file.

Resources #

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

Please share your WebUSB demos with the #webusb hashtag.

Acknowledgements #

Thanks to Joe Medley for reviewing this article.

Google Chrome V64

Last updated: Improve article

Currently, the browsers that support Web Midi are:

Opera v42 and above
Microsoft Edge (Chromium version) v80 and above (** See below)

When you are on any of the pages in the site that support directly downloading to your CODE amplifier, you will see a status bar at the bottom of the page. This will indicate whether your browser is midi-capable:

  • Midi is not supported by your browser
  • Midi is supported by your browser, but your CODE amp is not connected
  • Midi is supported by your browser, and your CODE amp is connected

You should note that Web Midi is still a draft specification, and although we've found it to be pretty stable, there could be combinations of hardware and software which have problems.

* Chrome v62 on Mac OS X:

There seems to be an issue when running Chrome v62 on Mac OSX, which prevents the firmware update from completing successfully. If this occurs, try the following:

  • Switch your amp off.
  • Quit out of Chrome, if it is already running.
  • Start Chrome, and just open one tab for the My Marshall site.
  • Go to the Firmware Update page, and click on the button for 'Firmware Update in Browser'.
  • Switch on the amp in bootloader mode, by holding down the PreFX, Mod and Rev buttons (the first, third and fifth buttons), and then turning the power button to 'On'.
  • After a few seconds, the amp should show as connected.
  • Start the install, or reinstall, of the firmware.

UPDATE: Google have confirmed that this issue was fixed in Chrome version 63. However, if the same issue occurs in later versions, then please try the above troubleshooting steps.

* Chrome v80 on Windows:

Chrome's MIDI configuration has changed in v80, which may cause some issues. If you are running Windows 10, there is a setting within Chrome that allows it to use the Windows RT implementation of MIDI, which is more reliable. However, this is turned off by default. To turn it on, open a new tab in Chrome, and enter the following:

chrome://flags/#use-winrt-midi-api

You should then set the option to 'enabled', as shown below:

** Microsoft Edge

Note that Microsoft Edge with version numbers of 79 and above use the Chromium engine (i.e. the same engine as Chrome). This means that these versions support WebMIDI, and will behave exactly the same as the Chrome version with the same number.

N.B. The issue with Chrome v80, and the fix to set the MIDI flag above, is exactly the same with Edge v80, except that to change the flag setting you will need to enter 'edge://flags/#use-winrt-midi-api' in the browser url box.

If you still have problems using midi from this site, here are some things you can try:

  • Check that you are using one of the browsers listed above. Make sure that the version you're using is at least the version shown.
  • Check that you have given permission for the My Marshall site to use midi devices in your browser. You will normally be prompted to do this the first time you use the site, but you can view and change the permissions later from your browser settings.
  • On Windows, only one application can use the underlying system midi driver at a time. Make sure that you're not running any other software that could be using the midi port, such as a Digital Audio Workstation or Midi Mapper.
  • If midi initially works, but you then start to have problems, close all of your browser windows, and then check that there is not a hidden instance of the browser running in the background. On Windows, use the Task Manager to do this, and on a Mac you can use Activity Monitor.
  • If all else fails, try turning your computer off and back on again! Sometimes when things crash, they can take the midi drivers with them, and the only option is to do a reboot.