-
-
Notifications
You must be signed in to change notification settings - Fork 240
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
multiple modbusRTU open/close will end with "Error Resource temporarily unavailable Cannot lock port" #547
Comments
I just found out, that the work around is not really working. Whenever a call to readHoldingRegister terminates with ETIMEDOUT and you close the connection afterwards, the resource is still locked. If you do a successful readHoldingRegister after ETIMEDOUT Exception, you can close it without locking the resource.
this produces this output:
|
I'm investigating something recently, and it happens to be somewhat related to this matter. maybe you can try because in this repo implement, distroy will call but close doesn't. internal variable until clear when you use and What I want to express is that it is very likely that the resource operation cannot be responded to until the transaction is completely processed. but at the same time, I also feel that there are some problems and loopholes in this mechanism. open source code open(callback) {
const modbus = this;
// open the serial port
modbus._port.open(function(error) {
if (error) {
modbusSerialDebug({ action: "port open error", error: error });
/* On serial port open error call next function */
if (callback)
callback(error);
} else {
/* init ports transaction id and counter */
modbus._port._transactionIdRead = 1;
modbus._port._transactionIdWrite = 1;
/* On serial port success
* (re-)register the modbus parser functions
*/
modbus._port.removeListener("data", modbus._onReceive);
modbus._port.on("data", modbus._onReceive);
/* On serial port error
* (re-)register the error listener function
*/
modbus._port.removeListener("error", modbus._onError);
modbus._port.on("error", modbus._onError);
/* Hook the close event so we can relay it to our callers. */
modbus._port.once("close", modbus.emit.bind(modbus, "close"));
/* On serial port open OK call next function with no error */
if (callback)
callback(error);
}
});
} _onReceive function _onReceive(data) {
const modbus = this;
let error;
// set locale helpers variables
const transaction = modbus._transactions[modbus._port._transactionIdRead];
// the _transactionIdRead can be missing, ignore wrong transaction it's
if (!transaction) {
return;
}
if (transaction.responses) {
/* Stash what we received */
transaction.responses.push(Uint8Array.prototype.slice.call(data));
}
// ............ |
Hi, destroy doesn't change the situation: This seems to be a bug. You can use the test program to reproduce it. As I wrote before: My ides was: If I close the connection after using it, other apps could also connect to the same USB rs485.
|
I'll give it a try when I have more free time. |
Thank you. Take your time. The workaround is working fine. |
When you execute ModbusRTU.open/ModbusRTU.close multiple times, it will work only for the first open call.
The second open call will fail with "Error Resource temporarily unavailable Cannot lock port".
You can see in the debug log, that second open call does not trigger "Creating poller". May be this is the reason.
As a work around, you can always create a new ModbusRTU and call connectRTU instead of calling ModbusRTU.open.
Here is how to reproduce it:
This is the debug output
The text was updated successfully, but these errors were encountered: