Pi4J / pi4j-v2

Pi4J Version 2.0
Apache License 2.0
273 stars 57 forks source link

IOAlreadyExistsException when reopening Serial-connection #257

Closed TorHahl closed 5 months ago

TorHahl commented 1 year ago

Hello. I've got a problem when re-opening a serial connection using the class com.pi4j.io.serial.Serial. Basically I want to write an interface class to receive data over an rs485-to-usb converter. And when the usb device gets disconnected and/or reconnected the software interface should close and reopen the serial connection. (Possibly the usb device could also change meanwhile - e.g. between ttyUSB0 and ttyUSB1, even when using the same usb slot.) So the serial interface works fine, without problems, after application start. But whenever the interface gets closed and reopened the Context.create-function delivers the following IOAlreadyExistsException:

Stacktrace: com.pi4j.io.exception.IOAlreadyExistsException: IO instance [com.pi4j.plugin.pigpio.provider.serial.PiGpioSerial] already exists in the Pi4J runtime context; unable to create a new instance using this reserved id.

I closes the serial interface by using the Serial.close() function. I've also tried to use additionally the functions Serial.shutdown() and/or Context.getProvider().shutdown() and/or Context.getProvider().initialize(). But nothing worked for me. So the only way to change the serial device is now for me to restart the application. I guess therefore that this is a bug and using the Serial.close() function doesn't unregister the used serial provider from the PI4J-Context. So I hope that someone here could verify this problem or has any idea what went wrong. Alternatively maybe someone has an idea, how I could change the serial device on the fly - without having to close the serial connection.

My specifications:

One more note: Using a raspberry-hat with a rs485-interface is unfortunately not really an option. Because some of the necessary I/O-Pins are still in use for other purposes.

FDelporte commented 1 year ago

Can you give the full stacktrace of this error? I remember we had some missing cleanup in another provider that was fixed recently, but can't immediately find it back.

I checked the code and calling close() on a serial connection should close it... https://github.com/Pi4J/pi4j-v2/blob/develop/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/serial/PiGpioSerial.java#L96

TorHahl commented 1 year ago

Of course, no problem.

Stacktrace: com.pi4j.io.exception.IOAlreadyExistsException: IO instance [com.pi4j.plugin.pigpio.provider.serial.PiGpioSerial] already exists in the Pi4J runtime context; unable to create a new instance using this reserved id. at com.pi4j@2.2.1/com.pi4j.registry.impl.DefaultRuntimeRegistry.add(DefaultRuntimeRegistry.java:80) at com.pi4j@2.2.1/com.pi4j.provider.impl.ProviderProxyHandler.invoke(ProviderProxyHandler.java:106) at com.sun.proxy.$Proxy3.create(Unknown Source) at com.pi4j@2.2.1/com.pi4j.context.Context.create(Context.java:317) at com.pi4j@2.2.1/com.pi4j.internal.IOCreator.create(IOCreator.java:58) at com.pi4j@2.2.1/com.pi4j.internal.IOCreator.create(IOCreator.java:146) at ... (my own connect function)

TorHahl commented 1 year ago

A short update: To avoid this problem I followed at least the tip in the neighboring issue thread Can't Create 2 serial connections and use jSerialComm. https://fazecast.github.io/jSerialComm/

Especially the handling of usb-to-serial devices is very easy with jSerialComm. Now I don't have to check all usb device connections anymore for myself. Many thanks then again at this point for the tip!