1
1
const ArduinoUSBVendorId = 0x2341 ;
2
2
const UserActionAbortError = 8 ;
3
3
4
+ /**
5
+ * Handles the connection between the browser and the Arduino board via Web Serial.
6
+ */
4
7
class SerialConnectionHandler {
5
8
constructor ( baudRate = 115200 , dataBits = 8 , stopBits = 1 , parity = "none" , flowControl = "none" , bufferSize = 4096 , timeout = 2000 ) {
6
9
this . baudRate = baudRate ;
@@ -15,6 +18,10 @@ class SerialConnectionHandler {
15
18
this . registerEvents ( ) ;
16
19
}
17
20
21
+ /**
22
+ * Prompts the user to select a serial port.
23
+ * @returns {Promise<SerialPort> } The serial port that the user has selected.
24
+ */
18
25
async requestSerialPort ( ) {
19
26
try {
20
27
const port = await navigator . serial . requestPort ( { filters : [ { usbVendorId : ArduinoUSBVendorId } ] } ) ;
@@ -28,10 +35,20 @@ class SerialConnectionHandler {
28
35
}
29
36
}
30
37
38
+ /**
39
+ * Checks if the browser is connected to a serial port.
40
+ * @returns {boolean } True if the browser is connected, false otherwise.
41
+ */
31
42
isConnected ( ) {
32
43
return this . currentPort ?. readable != null ;
33
44
}
34
45
46
+ /**
47
+ * Opens a connection to the given serial port by using the settings specified in the constructor.
48
+ * If the port is already open, it will be closed first.
49
+ * This method will call the `onConnect` callback before it returns.
50
+ * @returns {boolean } True if the connection was successfully opened, false otherwise.
51
+ */
35
52
async connectSerial ( ) {
36
53
try {
37
54
// If the port is already open, close it
@@ -52,6 +69,12 @@ class SerialConnectionHandler {
52
69
}
53
70
}
54
71
72
+ /**
73
+ * Disconnects from the current serial port.
74
+ * If a reading operation is in progress, it will be canceled.
75
+ * This function will call the `onDisconnect` callback before it returns.
76
+ * @returns {Promise<void> } A promise that resolves when the port has been closed.
77
+ */
55
78
async disconnectSerial ( ) {
56
79
if ( ! this . currentPort ) return ;
57
80
try {
@@ -66,6 +89,11 @@ class SerialConnectionHandler {
66
89
} ;
67
90
}
68
91
92
+ /**
93
+ * Tries to establish a connection to the first available serial port that has the Arduino USB vendor ID.
94
+ * This only works if the user has previously granted the website access to that serial port.
95
+ * @returns {Promise<boolean> } True if the connection was successfully opened, false otherwise.
96
+ */
69
97
async autoConnect ( ) {
70
98
if ( this . currentPort ) {
71
99
console . log ( '🔌 Already connected to a serial port.' ) ;
@@ -85,6 +113,12 @@ class SerialConnectionHandler {
85
113
return false ;
86
114
}
87
115
116
+ /**
117
+ * Reads the specified number of bytes from the serial port.
118
+ * @param {number } numBytes The number of bytes to read.
119
+ * @param {number } timeout The timeout in milliseconds.
120
+ * If the timeout is reached, the reader will be canceled and the read lock will be released.
121
+ */
88
122
async readBytes ( numBytes , timeout = null ) {
89
123
if ( this . currentPort . readable . locked ) {
90
124
console . log ( '🔒 Stream is already locked. Ignoring request...' ) ;
@@ -143,6 +177,10 @@ class SerialConnectionHandler {
143
177
return bytesRead ;
144
178
}
145
179
180
+ /**
181
+ * Reqests an image frame from the Arduino board by writing a 1 to the serial port.
182
+ * @returns {Promise<void> } A promise that resolves when the frame has been requested and the write stream has been closed.
183
+ */
146
184
async requestFrame ( ) {
147
185
if ( ! this . currentPort ?. writable ) {
148
186
console . log ( '🚫 Port is not writable. Ignoring request...' ) ;
@@ -155,6 +193,11 @@ class SerialConnectionHandler {
155
193
await writer . close ( ) ;
156
194
}
157
195
196
+ /**
197
+ * Requests a frame from the Arduino board and reads the specified number of bytes from the serial port afterwards.
198
+ * Times out after the timeout in milliseconds specified in the constructor.
199
+ * @param {number } totalBytes The number of bytes to read.
200
+ */
158
201
async getFrame ( totalBytes ) {
159
202
if ( ! this . currentPort ) return ;
160
203
@@ -164,6 +207,13 @@ class SerialConnectionHandler {
164
207
return await this . readBytes ( totalBytes , this . timeout ) ;
165
208
}
166
209
210
+ /**
211
+ * Registers event listeners for the `connect` and `disconnect` events of the serial port.
212
+ * The `connect` event is fired when a serial port becomes available not when it is opened.
213
+ * When the `connect` event is fired, `autoConnect()` is called.
214
+ * The `disconnect` event is fired when a serial port is lost.
215
+ * When the `disconnect` event is fired, the `onDisconnect` callback is called.
216
+ **/
167
217
registerEvents ( ) {
168
218
navigator . serial . addEventListener ( "connect" , ( e ) => {
169
219
// Connect to `e.target` or add it to a list of available ports.
0 commit comments