Pi4J / pi4j-v1

DEPRECATED Java I/O library for Raspberry Pi (GPIO, I2C, SPI, UART)
http://www.pi4j.com
Apache License 2.0
1.31k stars 447 forks source link

serial.close() causes program to hang #462

Closed andrfgs closed 3 years ago

andrfgs commented 5 years ago

The pi4j library is extremely unstable when using serial communication. Everything seems to crash everything.

I'm using pi4j core 1.2 and a Raspberry Pi Zero W (I purchased it a month ago, so I assume it's the most recent model).

GpioController gpio = GpioFactory.getInstance();
Gpio.wiringPiSetupGpio();
SerialConfig config = new SerialConfig();
Serial serial = SerialFactory.createInstance();
config.device("/dev/ttyS0")
                .baud(Baud._9600)
                .dataBits(DataBits._8)
                .parity(Parity.NONE)
                .stopBits(StopBits._1)
                .flowControl(FlowControl.NONE);

serial.open(config);

 serial.write("1");
InputStream is = serial.getInputStream();
byte[] data = getAllBytes(is);
int ctr = 0;
StringBuilder str = new StringBuilder();
while (data[ctr] != 10)
    str.append(Character.toString((char)data[ctr++]));

System.out.println(str.toString());
System.out.println("Finished");
serial.close();
gpio.shutdown();

This prints the ASCII string returned by the device connected to the serial (an Arduino, to be specific). Then it prints "Finished" and hangs.

If I take out the serial.close(); the program simply crashes with exception

Exception in thread "Thread-3" java.util.concurrent.RejectedExecutionException: Task com.pi4j.io.serial.tasks.SerialDataEventDispatchTaskImpl@110c7bc rejected from java.util.concurrent.ThreadPoolExecutor@1885290[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:668) at com.pi4j.io.serial.impl.SerialImpl$1.onDataReceive(SerialImpl.java:200) at com.pi4j.jni.SerialInterrupt.onDataReceiveCallback(SerialInterrupt.java:109)

I can also use the event listener functions, the same happens. If possible, I'd rather use this on the Main thread, the arduino only sends information after it receives anything from the raspberry pi, so there's no risk of the buffer keep growing.

Right now, what works is not closing or shutting down the wiring pi. But this sucks because it will cause problems if I rerun the program.

savageautomate commented 3 years ago

Closed.

I realize this is an old issue but I was doing some clean up for the upcoming v1.3 release and resolved this issue. I found a number of minor improvements to optimize and found the native serial port monitoring thread that was causing the blocking issue. This should be working now in v1.3-SNAPSHOT.