You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Support configuration changes without reopeningΒ #141
@reillyeon Would it be possible to reconsider this reconfigure() method? Most microcontrollers boot up and start listening on a Serial port at an specific baud rate but allow for clients to change the baud rate via commands. For instance in this project https://github.com/esphome/esp-web-tools for Flashing ESP devices over serial, most of the USBtoUART chips on those boards support speeds well above 115200, but once the port is open via Web Serial, and after issuing the command to change the baud rate, there is no way on the client side to also make that change.
A reconfigure() method seems very reasonable. It would probably work similarly to close() in that it requires the readable and writable streams to be closed. It looks like operating systems provide some flexibility around whether data is flushed and drained when the port is reconfigured. For transmitted data the requirement that writable is closed already handles that. For received data I think we can make the decision to only support flushing the read buffers when reconfiguring the port in order to avoid the application encountering corrupted data.
Reacted by Paulus Schoutsen, Dirk Luberth Dijkman, TMTron and Geoffrey Hunter
@reillyeon Thank you. So far on the eep-home-webtools we found a partial workaround in the meantime. We close the port and reopen it with the new baud rate. I say partial because there are some USB2Serial controllers commonly used on ESP boards that become irresponsive after closing the port, to that workaround does not work for them.
Speaking of flushing, the Espressiff guys on their flashing tool build with python flush the input buffers after changing the baud rate and after certain operations to get rid of some unneeded data. I believe the current api does not support a flushInput() method on the port, does it? that'd be a nice addition too.
letreader=port.readable.getReader();// Do whatever reading you want. When you want to flush the read buffer,awaitreader.cancel();// port.readable is replaced with a new ReadableStream.reader=port.readable.getReader();// Continue reading.
I am also interested in a reconfigure option to be able to properly emulate a DMX signal using a UART driven by the WebSerial interface.
The DMX protocol differs from the traditional RS485 transmission protocol in that it includes a "break" sequence that indicates that a message is about to be sent. Many DMX applications that use serial output emulate this break sequence by changing the baud rate to a much slower rate, broadcasting a 0 byte, then ramping the baud rate back up to the 250,000 baud rate of DMX. This slower baud transmission emulates the brake sequence by the line going low then high for a period.
At the moment, reconnecting the port takes way too long (as noted by @Azq2) and the signals are not close enough temporally for the DMX fixtures to recognize the break sequence.
Using this function you can set break to true, wait a specified time (e.g. 200ms) then set break to false. I have used this approach with https://ninjaterm.mbedded.ninja/ and it seems to work well.
Using this function you can set break to true, wait a specified time (e.g. 200ms) then set break to false. I have used this approach with https://ninjaterm.mbedded.ninja/ and it seems to work well.
Thanks @gbmhunter! I tried to use this however setSignals cannot be used on an open port. I get the following error when I try to use this right before I write my output:
TypeError: This writable stream writer has been released and cannot be used to monitor the stream's state
I also tried to set the signals before I use the port (right after opening). While it doesn't throw an error my UART does not recognize the signal. I don't have a logic analyzer to see what is going on on the wire though.
Note: Here is how I am setting signals (in both attempts)
await(portasany).setSignals({break: true});awaitnewPromise((resolve)=>setTimeout(resolve,200));// Do the writing here
I would like to also add my support for an addition to the API specification for an ability to change an open port's configuration - particularly the baud rate - without closing and re-opening the port.
My use case would be similar to the originally mentioned use case - for when communicating with microcontrollers that allow to change their baud rate on the fly.
I maintain a web-based ISP flashing tool for WCH RISC-V microcontrollers that uses the Web Serial API to communicate with the microcontroller bootloader. Many of the WCH microcontroller bootloaders support an optional command to change to a faster baud rate. To use it requires first connecting and issuing the "change baud" command at the default baud rate of 115200, then continuing all further communication at the new baud rate.
However, I am unable to currently implement such a feature because closing and re-opening the serial port (at the new baud rate) isn't feasible due to how the DTR/RTS control signals are also reset when doing so, which can be undesirable.
For my application, I reverted back to using Electron for better serial control compared to Web Serial. Web Serial is a great idea, but it does not seem like a priority at the moment to add features that would make it on par with native access (it is also lacking adoption in Firefox and Safari). I'm still hoping it improves in the future :-)
But I think this is not βjust a useful featureβ, but actually a bug. Without it, WebSerial cannot be considered complete.
Every major OS allows changing the speed without reopening the port, and thereβs no need to reset the buffer either.
For those who are frustrated by this:
WebSerial adapter for node-serialport: https://github.com/Azq2/node-serialport-bindings-webserial
Iβve implemented the ability to switch speed by reopening the port. This works perfectly fine.
Itβs also very useful β we can write applications that work both in Node.js and in the browser.
Activity
conradopoole commentedon Jun 25, 2021
@reillyeon Thank you. So far on the eep-home-webtools we found a partial workaround in the meantime. We close the port and reopen it with the new baud rate. I say partial because there are some USB2Serial controllers commonly used on ESP boards that become irresponsive after closing the port, to that workaround does not work for them.
Speaking of flushing, the Espressiff guys on their flashing tool build with python flush the input buffers after changing the baud rate and after certain operations to get rid of some unneeded data. I believe the current api does not support a flushInput() method on the port, does it? that'd be a nice addition too.
reillyeon commentedon Jun 25, 2021
This code will flush the input stream,
Azq2 commentedon Apr 22, 2024
I'm really sad that this important feature still does not exist in the standard.
Port reopening is not a reliable solution, because:
wmmiii commentedon May 28, 2024
I am also interested in a reconfigure option to be able to properly emulate a DMX signal using a UART driven by the WebSerial interface.
The DMX protocol differs from the traditional RS485 transmission protocol in that it includes a "break" sequence that indicates that a message is about to be sent. Many DMX applications that use serial output emulate this break sequence by changing the baud rate to a much slower rate, broadcasting a
0byte, then ramping the baud rate back up to the 250,000 baud rate of DMX. This slower baud transmission emulates the brake sequence by the line going low then high for a period.At the moment, reconnecting the port takes way too long (as noted by @Azq2) and the signals are not close enough temporally for the DMX fixtures to recognize the break sequence.
See this Chromium feature request for more details.
gbmhunter commentedon Jun 16, 2024
@wmmiii are you aware that you can send break signals of arbitrary lengths using the
setSignals()function (see https://developer.mozilla.org/en-US/docs/Web/API/SerialPort/setSignals)?Using this function you can set break to true, wait a specified time (e.g. 200ms) then set break to false. I have used this approach with https://ninjaterm.mbedded.ninja/ and it seems to work well.
wmmiii commentedon Jun 26, 2024
Thanks @gbmhunter! I tried to use this however
setSignalscannot be used on an open port. I get the following error when I try to use this right before I write my output:I also tried to set the signals before I use the port (right after opening). While it doesn't throw an error my UART does not recognize the signal. I don't have a logic analyzer to see what is going on on the wire though.
Note: Here is how I am setting signals (in both attempts)
I tried to search for
setSignalsin https://github.com/gbmhunter/NinjaTerm to no avail, can you give me an example of how you are using it?gbmhunter commentedon Jun 26, 2024
@wmmiii you should be able to use
setSignals()with an open port, at least I have been able to with no issues.I send the break signal in NinjaTerm in App.tsx (using an open port) in the function starting on Line 880 (in the latest version on main), see https://github.com/gbmhunter/NinjaTerm/blob/v4.18.0/src/model/App.tsx#L880 for the example you could look at.
reillyeon commentedon Jun 26, 2024
+1 to
setSignals()should work whenever the port is open. Its operation is independent of theWritableStream.basilhussain commentedon May 26, 2025
I would like to also add my support for an addition to the API specification for an ability to change an open port's configuration - particularly the baud rate - without closing and re-opening the port.
My use case would be similar to the originally mentioned use case - for when communicating with microcontrollers that allow to change their baud rate on the fly.
I maintain a web-based ISP flashing tool for WCH RISC-V microcontrollers that uses the Web Serial API to communicate with the microcontroller bootloader. Many of the WCH microcontroller bootloaders support an optional command to change to a faster baud rate. To use it requires first connecting and issuing the "change baud" command at the default baud rate of 115200, then continuing all further communication at the new baud rate.
However, I am unable to currently implement such a feature because closing and re-opening the serial port (at the new baud rate) isn't feasible due to how the DTR/RTS control signals are also reset when doing so, which can be undesirable.
Azq2 commentedon Aug 9, 2025
@reillyeon Any reason why this MOST WANTED feature has been ignored for 4 years? :(
gbmhunter commentedon Aug 10, 2025
For my application, I reverted back to using Electron for better serial control compared to Web Serial. Web Serial is a great idea, but it does not seem like a priority at the moment to add features that would make it on par with native access (it is also lacking adoption in Firefox and Safari). I'm still hoping it improves in the future :-)
reillyeon commentedon Aug 10, 2025
I understand your frustration but the team has been focused on other useful features.
Azq2 commentedon Aug 10, 2025
But I think this is not βjust a useful featureβ, but actually a bug. Without it, WebSerial cannot be considered complete.
Every major OS allows changing the speed without reopening the port, and thereβs no need to reset the buffer either.
For those who are frustrated by this:
WebSerial adapter for node-serialport: https://github.com/Azq2/node-serialport-bindings-webserial
Iβve implemented the ability to switch speed by reopening the port. This works perfectly fine.
Itβs also very useful β we can write applications that work both in Node.js and in the browser.
Example application: https://github.com/siemens-mobile-hacks/web-tools
SolidJS + node-serialport-bindings-webserial
AsyncSerialPort
Example (not library) for async wrapper around node-serialport. Very usefull in 2k25.