Web USB send to browser

Updated on 18 November 2022
dev board RobotDyn M0 mini
firmware Arduino
chip SAMD21
features WebUSB
This tutorial is more than 1 year old. If the steps below do not work, then please check the latest versions and the documentations of the individual tools used.

Before starting

Dependancies

Ensure the following dependancies are downloaded and available:

Pre-requisites

Try these simpler or similar examples:

Code

Download code webusb-send.ino
#include <WebUSB.h>

// Modified from example https://webusb.github.io/arduino/demos/console
WebUSB WebUSBSerial(1, "webusb.github.io/arduino/demos/console");
uint16_t irCode[4] = {3446, 1716, 416, 1310};

void setup() {
  WebUSBSerial.begin(9600);
  while (!WebUSBSerial) {}
  delay(100);
}

void loop() {
  WebUSBSerial.write("Hello world to the browser!");
  WebUSBSerial.flush();

  writeWebUSB((const uint8_t *)irCode, 8);

  delay(2000);
}

void writeWebUSB(const uint8_t *buffer, int size) {
    WebUSBSerial.write((const uint8_t *)buffer, size);
    WebUSBSerial.flush();
}

Makefile

BOARD?=arduino:samd:arduino_zero_native
PORT := $(shell ls /dev/cu.usbmodem*)

.PHONY: default lint all flash clean

default: lint all flash clean

lint:
	cpplint --extensions=ino --filter=-legal/copyright,-whitespace/line_length,-readability/casting,-readability/todo *.ino

all:
	# This custom PCB does not have a crytal on pins PA00 and PA01
	# Hence, use -DCRYSTALLESS to replace the extra_flags in boards.txt
	arduino-cli compile --fqbn $(BOARD) --build-properties build.extra_flags="-DCRYSTALLESS -D__SAMD21G18A__ {build.usb_flags}" ./

flash:
	arduino-cli upload -p $(PORT) --fqbn $(BOARD)

clean:
	rm -r build

server:
	echo "Open Chrome browser at http://localhost:8000/webusb-send.html"
	python -m SimpleHTTPServer 8000

Description

Send a simple sentence from the MCU to the browser on laptop.

Start the web browser code with make server.

Ensure the browser side of the code is also implemented with serial.js.

Download code

<button id="connect">Connect to device</button>
<p>Open the browser console to see received messages from the MCU!</p>

<!-- serial.js
From https://github.com/webusb/arduino/blob/gh-pages/demos/serial.js
Add 'vendorId': 0x2341 and 0x2a03 in line 27 and line 28
-->
<script src="serial.js"></script>
<script>
serial.requestPort = function() {
  const filters = [
    { 'vendorId': 0x2341 },
    { 'vendorId': 0x2a03 }
  ];
  return navigator.usb.requestDevice({ 'filters': filters }).then(
    device => new serial.Port(device)
  );
}

var port
let connectButton = document.querySelector('#connect')
let textDecoder = new TextDecoder()

connectButton.addEventListener('click', function() {
  if (port) { // If port is already connected, disconnect it
    connectButton.textContent = 'Connect'
    port.disconnect()
    port = null
    console.log('Device is disconnected.')
  } else { // If there is no port, then connect to a new port
    serial.requestPort().then(selectedPort => {
      port = selectedPort
      port.connect().then(() => {
        console.log('Device is connected to Product ID: ' + port.device_.productId.toString(16) + ' and Vendor ID: ' + port.device_.vendorId.toString(16))

        connectButton.textContent = 'Disconnect'
        port.onReceive = data => { console.log(textDecoder.decode(data))}
        port.onReceiveError = error => { console.log('Receive error: ' + error)}
      }, error => { console.log('Connection error: ' + error) })
    }).catch(error => { console.log('Connection error: ' + error) })
  }
})
</script>

References

Watch