Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support configuration changes without reopening #141

Open
reillyeon opened this issue Jun 25, 2021 · 8 comments
Open

Support configuration changes without reopening #141

reillyeon opened this issue Jun 25, 2021 · 8 comments

Comments

@reillyeon
Copy link
Collaborator

From #71,

@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.

@conradopoole
Copy link

@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
Copy link
Collaborator Author

This code will flush the input stream,

let reader = port.readable.getReader();
// Do whatever reading you want. When you want to flush the read buffer,
await reader.cancel();
// port.readable is replaced with a new ReadableStream.
reader = port.readable.getReader();
// Continue reading.

@Azq2
Copy link

Azq2 commented 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:

  • We lose time. Closing/opening is not a fast operation.
  • Port signals are reset to default values.
  • A lot of redundant code for handling unexpected reopen of the port.

@wmmiii
Copy link

wmmiii commented 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 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.

See this Chromium feature request for more details.

@gbmhunter
Copy link

@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
Copy link

wmmiii commented Jun 26, 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.

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 (port as any).setSignals({ break: true });
await new Promise((resolve) => setTimeout(resolve, 200));

// Do the writing here

I tried to search for setSignals in https://github.com/gbmhunter/NinjaTerm to no avail, can you give me an example of how you are using it?

@gbmhunter
Copy link

@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
Copy link
Collaborator Author

+1 to setSignals() should work whenever the port is open. Its operation is independent of the WritableStream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants