-
-
Save nuta/2c70ba8855f50c536a51f0c5993c1e4c to your computer and use it in GitHub Desktop.
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>esptool.js</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/2.9.2/xterm.min.js" integrity="sha256-8rsVcpCnO6HdeJL84i0VdubjM42fjSmO8aONghdq3gc=" crossorigin="anonymous"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/xterm/2.9.2/xterm.min.css" integrity="sha256-w69o8Y6P5VZjfYFmn2KlqMU7TUi2I+oWObi8FLlVZZg=" crossorigin="anonymous" /> | |
| </head> | |
| <body> | |
| <h1>esptool.js</h1> | |
| <button id="flash-button" style="padding: 30px; font-size: 40px">Flash</button> | |
| <div id="serial"></div> | |
| <script src="esptool.js"></script> | |
| <script> | |
| const term = new Terminal() | |
| term.open(document.querySelector("#serial")) | |
| document.querySelector("#flash-button").addEventListener("click", () => { | |
| const esp = new Esptool() | |
| esp.connect().then(() => { | |
| const receive = () => { | |
| esp.serial.read().then(data => { | |
| const s = String.fromCharCode.apply(null, new Uint8Array(data)) | |
| term.write(s) | |
| receive() | |
| }) | |
| } | |
| receive() | |
| }) | |
| }) | |
| </script> | |
| </body> | |
| </html> |
| const { Serial } = require("./serial") | |
| class Esptool { | |
| constructor() { | |
| this.serial = new Serial() | |
| } | |
| connect() { | |
| return this.serial.connect().then(() => { | |
| return this.serial.initialize() | |
| }) | |
| } | |
| async flash() { | |
| } | |
| } | |
| if (window) { | |
| // Web browser | |
| window.Esptool = Esptool; | |
| } |
| { | |
| "name": "esptool.js", | |
| "version": "0.0.1", | |
| "description": "Esptool implemented for Node.js and web browsers.", | |
| "main": "lib/index.js", | |
| "repository": "https://github.com/seiyanuta/esptool.js", | |
| "author": "Seiya Nuta <[email protected]>", | |
| "license": "(CC0-1.0 OR MIT)", | |
| "devDependencies": { | |
| "copy-webpack-plugin": "^4.3.1", | |
| "webpack": "^3.10.0", | |
| "webpack-dev-server": "^2.11.1" | |
| } | |
| } |
| class Serial { | |
| constructor() { | |
| this.usb = null | |
| } | |
| connect() { | |
| const filters = [ | |
| { 'vendorId': 0x10c4, 'productId': 0xea60 } | |
| ] | |
| return navigator.usb.getDevices().then(devices => { | |
| if (devices.length > 0) { | |
| const usb = devices[0] | |
| this.usb = usb | |
| return usb | |
| } else { | |
| return navigator.usb.requestDevice({ filters }).then(usb => { | |
| this.usb = usb | |
| return usb | |
| }) | |
| } | |
| }) | |
| } | |
| initialize() { | |
| return this.usb.open() | |
| .then(() => { | |
| return this.usb.selectConfiguration(1) | |
| }) | |
| .then(() => { | |
| console.log(this.usb) | |
| return this.usb.claimInterface(0) | |
| }) | |
| .then(() => { | |
| return this.usb.controlTransferOut({ | |
| requestType: 'vendor', | |
| recipient: 'device', | |
| request: 0x00, | |
| index: 0x00, | |
| value: 0x01 | |
| }) | |
| }) | |
| .then(() => { | |
| return this.usb.controlTransferOut({ | |
| requestType: 'vendor', | |
| recipient: 'device', | |
| request: 0x07, | |
| index: 0x00, | |
| value: 0x03 | 0x0100 | 0x0200 | |
| }) | |
| }) | |
| .then(() => { | |
| return this.usb.controlTransferOut({ | |
| requestType: 'vendor', | |
| recipient: 'device', | |
| request: 0x01, | |
| index: 0x00, | |
| value: 0x384000 / 115200 | |
| }) | |
| }) | |
| } | |
| async read() { | |
| const r = await this.usb.transferIn(1, 64) | |
| return new Uint8Array(r.data.buffer) | |
| } | |
| async write(data) { | |
| await this.usb.transferIn(1, data) | |
| } | |
| } | |
| module.exports = { Serial } |
| const path = require("path") | |
| module.exports = { | |
| entry: { | |
| app: ["./index.js"] | |
| }, | |
| output: { | |
| path: __dirname, | |
| publicPath: "/", | |
| filename: "esptool.js" | |
| } | |
| }; |
@vanminh0910 I've tried just now but it doesn't work for me. I'd recommend to use Serial API instead. It's way better than this gist.
@vanminh0910 If you want to flash a firmware, in addition to the serial device driver like this, you'll need to implement esptool protocol. ESP32 programming on the web sounds really exciting to me, but unfortunately I have no time to work on it for now.
@AlexFundorin It seems it no longer work though, index.html instantiates xterm.js (for printing colored device messages) and writes received data into it.
@seiyanuta this - https://github.com/scottchiefbaker/ESP-WebOTA
Thank you for sharing! It looks interesting :)
I'm already using it in my project. Well, it's working, yet I'm still updating firmware directly from VSCode, using OTA.
This device (https://yolostem.com) using esp32 supports web programming using webusb API which is available on Chrome already, but not Serial API. Here is its programming page https://lab.yolostem.com. Sadly the homepage is mainly in Vietnamese.
I'm mostly interested in uploading firmware to a second Arduino board via ESP32.
Don't see much point in the actual programming, using webusb.
@vanminh0910 looks to me that the device is using an atmega chip inside that translates the webusb, I looked at the files and found this https://lab.yolostem.com/assets/webusb.js, inside the vendorID is 0x2341 which corresponds to the arduino.
Could you, please, explain in a couple of words, what is the purpose of this index.html?