Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dce754b

Browse filesBrowse files
Improve USBVendor Example (espressif#9349)
* Add WebUSB console * Improve Console Page * Improve example * Add comments * Add flush method --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
1 parent b92ad55 commit dce754b
Copy full SHA for dce754b

File tree

Expand file treeCollapse file tree

7 files changed

+273
-6
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+273
-6
lines changed

‎cores/esp32/USB.cpp

Copy file name to clipboardExpand all lines: cores/esp32/USB.cpp
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
#define USB_WEBUSB_ENABLED false
4949
#endif
5050
#ifndef USB_WEBUSB_URL
51-
#define USB_WEBUSB_URL "https://espressif.github.io/arduino-esp32/webusb.html"
51+
#define USB_WEBUSB_URL "https://docs.espressif.com/projects/arduino-esp32/en/latest/_static/webusb.html"
5252
#endif
5353

5454
#if CFG_TUD_DFU

‎docs/_static/webusb.html

Copy file name to clipboard
+128Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<!-- Based on https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/subsys/usb/webusb -->
2+
3+
<!DOCTYPE html>
4+
<html lang="en">
5+
<head>
6+
<title>Espressif WebUSB Console Example</title>
7+
</head>
8+
9+
<body>
10+
<script>
11+
var serial = {};
12+
13+
(function() {
14+
'use strict';
15+
16+
serial.getPorts = function() {
17+
return navigator.usb.getDevices().then(devices => {
18+
return devices.map(device => new serial.Port(device));
19+
});
20+
};
21+
22+
serial.requestPort = function() {
23+
const filters = [
24+
{ 'vendorId': 0x10c4, 'productId': 0xea60 },
25+
{ 'vendorId': 0x303a, 'productId': 0x1001 },
26+
{ 'vendorId': 0x303a, 'productId': 0x0002 },
27+
];
28+
return navigator.usb.requestDevice({ 'filters': filters }).then(
29+
device => new serial.Port(device)
30+
);
31+
}
32+
33+
serial.Port = function(device) {
34+
this.device_ = device;
35+
};
36+
37+
serial.Port.prototype.connect = function() {
38+
let readLoop = () => {
39+
const {
40+
endpointNumber
41+
} = this.device_.configuration.interfaces[0].alternate.endpoints[0]
42+
this.device_.transferIn(endpointNumber, 64).then(result => {
43+
this.onReceive(result.data);
44+
readLoop();
45+
}, error => {
46+
this.onReceiveError(error);
47+
});
48+
};
49+
50+
return this.device_.open()
51+
.then(() => {
52+
if (this.device_.configuration === null) {
53+
return this.device_.selectConfiguration(1);
54+
}
55+
})
56+
.then(() => this.device_.claimInterface(0))
57+
.then(() => {
58+
readLoop();
59+
});
60+
};
61+
62+
serial.Port.prototype.disconnect = function() {
63+
return this.device_.close();
64+
};
65+
66+
serial.Port.prototype.send = function(data) {
67+
const {
68+
endpointNumber
69+
} = this.device_.configuration.interfaces[0].alternate.endpoints[1]
70+
return this.device_.transferOut(endpointNumber, data);
71+
};
72+
})();
73+
74+
let port;
75+
76+
function connect() {
77+
port.connect().then(() => {
78+
port.onReceive = data => {
79+
let textDecoder = new TextDecoder();
80+
console.log("Received:", textDecoder.decode(data));
81+
document.getElementById('output').value += textDecoder.decode(data);
82+
}
83+
port.onReceiveError = error => {
84+
console.error(error);
85+
document.querySelector("#connect").style = "visibility: initial";
86+
port.disconnect();
87+
};
88+
});
89+
}
90+
91+
function send(string) {
92+
console.log("sending to serial:" + string.length);
93+
if (string.length === 0)
94+
return;
95+
console.log("sending to serial: [" + string +"]\n");
96+
97+
let view = new TextEncoder('utf-8').encode(string);
98+
console.log(view);
99+
if (port) {
100+
port.send(view);
101+
}
102+
};
103+
104+
window.onload = _ => {
105+
document.querySelector("#connect").onclick = function() {
106+
serial.requestPort().then(selectedPort => {
107+
port = selectedPort;
108+
this.style = "visibility: hidden";
109+
connect();
110+
});
111+
}
112+
113+
document.querySelector("#submit").onclick = () => {
114+
let source = document.querySelector("#input").value;
115+
send(source);
116+
}
117+
}
118+
</script>
119+
120+
<button id="connect" style="visibility: initial">Connect To ESP Device</button>
121+
<br><br><label for="input">Sender: </label> <br>
122+
<textarea id="input" rows="25" cols="80">Send to ESP Device</textarea>
123+
<br><button id="submit">Send</button>
124+
<br><br>
125+
<label for="output">Receiver: </label> <br>
126+
<textarea id="output" rows="25" cols="80"></textarea>
127+
</body>
128+
</html>

‎docs/en/api/usb.rst

Copy file name to clipboardExpand all lines: docs/en/api/usb.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ This function is used to get the ``webUSBURL``.
303303
304304
const char * webUSBURL(void);
305305
306-
The default ``webUSBURL`` is: https://espressif.github.io/arduino-esp32/webusb.html
306+
The default ``webUSBURL`` is: https://docs.espressif.com/projects/arduino-esp32/en/latest/_static/webusb.html
307307

308308
enableDFU
309309
^^^^^^^^^

‎libraries/USB/examples/USBVendor/USBVendor.ino

Copy file name to clipboardExpand all lines: libraries/USB/examples/USBVendor/USBVendor.ino
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ void setup() {
164164

165165
USB.onEvent(usbEventCallback);
166166
USB.webUSB(true);
167-
USB.webUSBURL("http://localhost/webusb");
167+
// Set the URL for your WebUSB landing page
168+
USB.webUSBURL("https://docs.espressif.com/projects/arduino-esp32/en/latest/_static/webusb.html");
168169
USB.begin();
169170
}
170171

@@ -176,9 +177,11 @@ void loop() {
176177
if (buttonState == LOW) {
177178
Serial.println("Button Pressed");
178179
Vendor.println("Button Pressed");
180+
Vendor.flush(); //Without flushing the data will only be sent when the buffer is full (64 bytes)
179181
} else {
180-
Vendor.println("Button Released");
181182
Serial.println("Button Released");
183+
Vendor.println("Button Released");
184+
Vendor.flush(); //Without flushing the data will only be sent when the buffer is full (64 bytes)
182185
}
183186
delay(100);
184187
}
@@ -188,6 +191,7 @@ void loop() {
188191
uint8_t b[l];
189192
l = Serial.read(b, l);
190193
Vendor.write(b, l);
194+
Vendor.flush(); //Without flushing the data will only be sent when the buffer is full (64 bytes)
191195
}
192196
}
193197
#endif /* ARDUINO_USB_MODE */
+133Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<!-- Based on https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/subsys/usb/webusb -->
2+
3+
<!--
4+
Example of WebUSB web page to communicate with a USB device.
5+
This can be used as a starting point for your self-hosted WebUSB landing page.
6+
-->
7+
8+
<!DOCTYPE html>
9+
<html lang="en">
10+
<head>
11+
<title>Espressif WebUSB Console Example</title>
12+
</head>
13+
14+
<body>
15+
<script>
16+
var serial = {};
17+
18+
(function() {
19+
'use strict';
20+
21+
serial.getPorts = function() {
22+
return navigator.usb.getDevices().then(devices => {
23+
return devices.map(device => new serial.Port(device));
24+
});
25+
};
26+
27+
serial.requestPort = function() {
28+
const filters = [
29+
{ 'vendorId': 0x10c4, 'productId': 0xea60 },
30+
{ 'vendorId': 0x303a, 'productId': 0x1001 },
31+
{ 'vendorId': 0x303a, 'productId': 0x0002 },
32+
];
33+
return navigator.usb.requestDevice({ 'filters': filters }).then(
34+
device => new serial.Port(device)
35+
);
36+
}
37+
38+
serial.Port = function(device) {
39+
this.device_ = device;
40+
};
41+
42+
serial.Port.prototype.connect = function() {
43+
let readLoop = () => {
44+
const {
45+
endpointNumber
46+
} = this.device_.configuration.interfaces[0].alternate.endpoints[0]
47+
this.device_.transferIn(endpointNumber, 64).then(result => {
48+
this.onReceive(result.data);
49+
readLoop();
50+
}, error => {
51+
this.onReceiveError(error);
52+
});
53+
};
54+
55+
return this.device_.open()
56+
.then(() => {
57+
if (this.device_.configuration === null) {
58+
return this.device_.selectConfiguration(1);
59+
}
60+
})
61+
.then(() => this.device_.claimInterface(0))
62+
.then(() => {
63+
readLoop();
64+
});
65+
};
66+
67+
serial.Port.prototype.disconnect = function() {
68+
return this.device_.close();
69+
};
70+
71+
serial.Port.prototype.send = function(data) {
72+
const {
73+
endpointNumber
74+
} = this.device_.configuration.interfaces[0].alternate.endpoints[1]
75+
return this.device_.transferOut(endpointNumber, data);
76+
};
77+
})();
78+
79+
let port;
80+
81+
function connect() {
82+
port.connect().then(() => {
83+
port.onReceive = data => {
84+
let textDecoder = new TextDecoder();
85+
console.log("Received:", textDecoder.decode(data));
86+
document.getElementById('output').value += textDecoder.decode(data);
87+
}
88+
port.onReceiveError = error => {
89+
console.error(error);
90+
document.querySelector("#connect").style = "visibility: initial";
91+
port.disconnect();
92+
};
93+
});
94+
}
95+
96+
function send(string) {
97+
console.log("sending to serial:" + string.length);
98+
if (string.length === 0)
99+
return;
100+
console.log("sending to serial: [" + string +"]\n");
101+
102+
let view = new TextEncoder('utf-8').encode(string);
103+
console.log(view);
104+
if (port) {
105+
port.send(view);
106+
}
107+
};
108+
109+
window.onload = _ => {
110+
document.querySelector("#connect").onclick = function() {
111+
serial.requestPort().then(selectedPort => {
112+
port = selectedPort;
113+
this.style = "visibility: hidden";
114+
connect();
115+
});
116+
}
117+
118+
document.querySelector("#submit").onclick = () => {
119+
let source = document.querySelector("#input").value;
120+
send(source);
121+
}
122+
}
123+
</script>
124+
125+
<button id="connect" style="visibility: initial">Connect To ESP Device</button>
126+
<br><br><label for="input">Sender: </label> <br>
127+
<textarea id="input" rows="25" cols="80">Send to ESP Device</textarea>
128+
<br><button id="submit">Send</button>
129+
<br><br>
130+
<label for="output">Receiver: </label> <br>
131+
<textarea id="output" rows="25" cols="80"></textarea>
132+
</body>
133+
</html>

‎libraries/USB/src/USBVendor.cpp

Copy file name to clipboardExpand all lines: libraries/USB/src/USBVendor.cpp
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,9 @@ size_t USBVendor::read(uint8_t *buffer, size_t size){
212212
return count;
213213
}
214214

215-
void USBVendor::flush(void){}
215+
void USBVendor::flush(void){
216+
tud_vendor_n_write_flush(itf);
217+
}
216218

217219
#endif /* CONFIG_TINYUSB_VENDOR_ENABLED */
218220
#endif /* SOC_USB_OTG_SUPPORTED */

‎variants/esp32s2usb/pins_arduino.h

Copy file name to clipboardExpand all lines: variants/esp32s2usb/pins_arduino.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define USB_PRODUCT "ESP32-S2-USB"
1111
#define USB_SERIAL "0"
1212
#define USB_WEBUSB_ENABLED false
13-
#define USB_WEBUSB_URL "https://espressif.github.io/arduino-esp32/webusb.html"
13+
#define USB_WEBUSB_URL "https://docs.espressif.com/projects/arduino-esp32/en/latest/_static/webusb.html"
1414

1515
// Default USB FirmwareMSC Settings
1616
#define USB_FW_MSC_VENDOR_ID "ESP32-S2" //max 8 chars

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.