Fazecast / jSerialComm

Platform-independent serial port access for Java
GNU Lesser General Public License v3.0
1.31k stars 278 forks source link

com.fazecast.jSerialComm.SerialPortIOException: This port appears to have been shutdown or disconnected. #320

Closed Michel-0 closed 2 years ago

Michel-0 commented 3 years ago

Hi,

since this seems to be the only place for support, i'm posting my problem here altough i'm not sure if it's actually a issue of the library or on my side.

Situation & Problem

However, i can't get it managed to establish a serial connection to a FTDI FT232RL USB VCP. I'm testing on Windows 10, device manager tells me everything is all right. The device seems to be correctly installed & active. I'm using jSerialComm provided by fazecast.github.io - jSerialComm-2.6.2.jar.

I can't get it managed to run. I bridged Tx & Rx, so i should receive what i send, but i can't even send anything... Maybe some of you guys might see what i obviously miss?

How to reproduce

image

  1. DropDown list gets correctly filled. I selected COM10.
  2. The log tells me Port "COM10: USB Serial Port (COM10) (FT232R USB UART)" is now closed. altough #open is called.
  3. I typed a into the send bar and hit send.
  4. The Exception as in title com.fazecast.jSerialComm.SerialPortIOException: This port appears to have been shutdown or disconnected. occurs. Always.

What's going wrong here?

EDIT: Meanwhile i implemented basically the same logic in C# with the .NET Framework & System.IO.Ports. It's working perfectly, so hardware faults are not a possible cause. Still, i can't see why System.IO.Ports can do what com.fazecast.jSerialComm can't do.

Sources

My communication handler class:

public class SerialCommunication {
    private SerialWindow gui;
    private SerialPort serialPort;
    private OutputStream serialOut;
    private InputStream serialIn;
    public SerialCommunication(SerialWindow gui) {
        this.gui = gui;
        this.serialPort = null;
        this.serialOut = null;
        this.serialIn = null;
        for (SerialPort port : SerialPort.getCommPorts()) {
            this.gui.addInterface(port.getSystemPortName() + ": " + port.getDescriptivePortName() + " (" + port.getPortDescription() + ")");
        }
    }
    public void setupInterface(String portName) {
        if (this.serialPort != null) {
            if (this.serialOut != null) {
                try {
                    this.serialOut.flush();
                    this.serialOut.close();
                } catch (IOException e) {
                    this.gui.log("Failed closing port: " + e.getMessage());
                }
                this.serialOut = null;
            }
            if (this.serialIn != null) {
                try {
                    this.serialIn.close();
                } catch (IOException e) {
                    this.gui.log("Failed closing port: " + e.getMessage());
                }
                this.serialIn = null;
            }
            this.serialPort.removeDataListener();
            this.serialPort.closePort();
            this.serialPort = null;
            this.gui.log("Closed port.");
        }
        this.serialPort = SerialPort.getCommPort(portName);
        if (this.serialPort != null) {
            this.serialPort.setComPortParameters(9600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
            this.serialPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 10000, 10000);
            this.serialPort.openPort();
            this.serialOut = this.serialPort.getOutputStream();
            this.serialIn = this.serialPort.getInputStream();
            this.serialPort.addDataListener(new SerialReceiver(this));
            this.gui.log("Port \"" + portName + "\" is now " + (this.serialPort.isOpen() ? "opened." : "closed."));
        } else {
            this.gui.log("Port \"" + portName + "\" invalid.");
        }
    }
    public void send(String text) {
        try {
            this.serialOut.write(text.getBytes());
            this.gui.log("> " + text);
        } catch (IOException e) {
            this.gui.log("Error while sending: " + e.getMessage());
        }
    }
    public void getDataAvailable() {
        try {
            byte[] newData = new byte[this.serialIn.available()];
            int numRead = this.serialIn.read(newData);
            this.gui.log("> [#" + Integer.toString(numRead) + "] " + new String(newData));
        } catch (IOException e) {
            this.gui.log("Error while receiving: " + e.getMessage());
        }
    }
}

My packet receiver:

public class SerialReceiver implements SerialPortDataListener {
    private SerialCommunication comm;
    public SerialReceiver(SerialCommunication comm) {
        this.comm = comm;
    }
    @Override
    public int getListeningEvents() {
        return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
    }
    @Override
    public void serialEvent(SerialPortEvent event) {
        if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
            this.comm.getDataAvailable();
        }
    }
}

My java application & GUI class:

public class SerialWindow extends Application {
    private SerialCommunication comm;
    @FXML
    private TextArea receiveLog;
    @FXML
    private TextArea sendLog;
    @FXML
    private TextField sendInput;
    @FXML
    private Button sendButton;
    @FXML
    private ComboBox<String> interfaceSelector;
    public static void main(String[] args) {
        SerialWindow.launch();
    }
    public void log(String message) {
        String timeStamp = String.format("%1$td.%1$tm.%1$tY-%1$tH:%1$tM:%1$tS", Calendar.getInstance().getTime());
        if (this.receiveLog.getLength() > 0) this.receiveLog.appendText("\n");
        if (this.sendLog.getLength() > 0) this.sendLog.appendText("\n");
        this.receiveLog.appendText("[" + timeStamp + "] <INFO> " + message);
    }
    public void addInterface(String text) {
        this.interfaceSelector.getItems().add(text);
    }
    public String getInterface() {
        return this.interfaceSelector.getValue();
    }
    @Override
    public void start(Stage primaryStage) {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("SerialWindow.fxml"));
            fxmlLoader.setController(this);
            Parent root = fxmlLoader.load();
            Scene scene = new Scene(root, 800, 600);
            primaryStage.setTitle("Serial communication");
            primaryStage.setScene(scene);
            primaryStage.show();
            this.comm = new SerialCommunication(this);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void stop() {
        this.comm.setupInterface("");
    }
    @FXML
    private void onSendButtonAction() {
        this.comm.send(this.sendInput.getText());
        this.sendInput.clear();
    }
    @FXML
    private void onInterfaceSelectorAction() {
        this.comm.setupInterface(this.interfaceSelector.getValue());
    }
}

My Java GUI:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<GridPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
  <columnConstraints>
    <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
    <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
      <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
      <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
  </columnConstraints>
  <rowConstraints>
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
  </rowConstraints>
   <children>
      <Label fx:id="title" text="Serial communication" GridPane.columnSpan="4" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.valignment="BOTTOM" GridPane.vgrow="NEVER">
         <font>
            <Font name="System Bold" size="24.0" />
         </font>
      </Label>
      <Label fx:id="receiveTitle" text="Receive Log" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="2" GridPane.valignment="BOTTOM" GridPane.vgrow="NEVER" />
      <Label fx:id="sendTitle" text="Send Log" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="2" GridPane.valignment="BOTTOM" GridPane.vgrow="NEVER" />
      <TextArea fx:id="receiveLog" editable="false" prefHeight="200.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="NEVER" GridPane.rowIndex="3" GridPane.valignment="TOP" GridPane.vgrow="NEVER" />
      <TextArea fx:id="sendLog" editable="false" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.halignment="LEFT" GridPane.hgrow="NEVER" GridPane.rowIndex="3" GridPane.valignment="TOP" GridPane.vgrow="NEVER" />
      <TextField fx:id="sendInput" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="4" GridPane.valignment="CENTER" GridPane.vgrow="NEVER" />
      <Button fx:id="sendButton" mnemonicParsing="false" onAction="#onSendButtonAction" text="Send" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="4" GridPane.valignment="CENTER" GridPane.vgrow="NEVER" />
      <ComboBox fx:id="interfaceSelector" onAction="#onInterfaceSelectorAction" prefWidth="150.0" promptText="Interfaces" GridPane.columnSpan="4" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="NEVER" />
   </children>
</GridPane>

Looking forward for some feedback... Kind regards, Michel-0

FolsomMike commented 3 years ago

I was getting this same error...not sure if my cause is the same, but worth investigating.

I was trying to talk to the USB Serial port on an Arduino and after sending three bytes from Java code it would give me the "This port appears to have been shutdown or disconnected." error.

I solved it in this case by constantly reading bytes on the Arduino side. Apparently, the USB-Serial adapter on the Arduino is only buffering 3 bytes despite the documentation stating that serial ports have 64 byte buffers.

This may purely be on the adapter side...I plan to try flow control on the Java side next. Otherwise, I will have to write my own Arduino interrupt to make sure data is read quickly at all times.

It is possible that other USB-Serial adapters have similar issues.

hedgecrw commented 2 years ago

Please test using this version of the library and let me know if you are still seeing the same issue: https://drive.google.com/file/d/1QzWPJg5MU_2YrnsB1MsOWeTbjYD84D2h/view?usp=sharing

gsrunion commented 2 years ago

@hedgecrw is there a particular commit that you feel like might address this issue?

sergimn commented 2 years ago

I've been having this issue as well and it seems like the problem was that I was using a faulty USB cable. At least using a thicker one that's probably shielded does not make the connection crash anymore.

hedgecrw commented 2 years ago

@gsrunion, I can't point you to a specific commit as there has been a substantial rewrite of the native-side code among a ton of commits between versions 2.7.0 and 2.8.0 addressing this issue. The best test would be to use the latest code/library beta version in the link above to test. I feel that @FolsomMike's issue is probably not the same as the Original Poster's (since he could open successfully and read before getting disconnected), but testing the new version will help narrow this down since the disconnects should not happen.

In addition, we are implementing a way to retrieve the OS-reported error codes as well as the source code locations of the errors for easier debugging in the future. I have added two functions which should allow you to view both the native errno and the source code line that threw it. These method signatures are:

int getLastErrorCode();
int getLastErrorLocation();

If you test these out using the above beta library version, you should be able to do a search through the source code files under src/main/c/Posix to determine which line threw an error and look up what the error code means for your OS. Thanks!

gsrunion commented 2 years ago

@hedgecrw it is like you are reading my mind. Not having access to the error codes returned from the OS was a big challenge.

hedgecrw commented 2 years ago

@gsrunion, agreed. It was especially difficult to do any sort of debugging with users who were able to produce bugs that I couldn't reproduce on my end. If you get a chance to test the beta JAR from the link above, it would be a great help to me, as this is one of those issues I've never been able to reproduce. My hope is that the current library restructuring to be less strict about read errors will solve this problem.

huoxingdawang commented 2 years ago

I ran into a similar problem today.I have two serial ports, one will appear "This port appears to have been shutdown or disconnected." and the other will not. However, when I open the two serial ports on another software, the normal serial port can be opened, and the abnormal serial port will cause a "Permission denied" error.

After that, I tried to use sudo to run my code and it worked perfectly. So I think, may be the the error message could be modified in order to give a clear reason.

And the bug hasn't been fixed yet in 2.8.0beta mentioned in the https://github.com/Fazecast/jSerialComm/issues/320#issuecomment-971314930

One possible solution is to add your username into the "dialout" group by ”sudo usermod -aG dialout username“, and then reboot your computer.

hedgecrw commented 2 years ago

I believe most of these issues should have been resolved with today's new library release v2.8.0.

@huoxingdawang, your suggestion to add your username to the dialout group is correct, and this recommendation is already present in both the Wiki instructions and the troubleshooting page. Regarding the "port appears to have been shutdown or disconnected" message...if you are seeing this after opening your port and trying to use it, I suspect that you are not checking the return value of the openPort() call (which will be false in the case of a permissions error).

With this new release, you are able to determine what the error code was the caused a port not to open by calling getLastErrorCode() which will return the native OS-specific return code that was encountered at the source code line returned from getLastErrorLocation() for your OS. If need be, this can be used to determine the underlying reason for a failure to open a port. This methodology was chosen because the underlying failure reasons vary so much between all the different operating systems that it's impossible to cover all possible cases in a cross-platform-friendly way.

I'm going to leave this issue open for another month or so to let people continue to test everything using the new library version and make sure that their issues appear to be solved before closing.

dariol83 commented 2 years ago

Hi, I landed on this thread, as I am trying to use jSerialComm for serial communication over a USB-to-serial adapter, and I am experiencing the same issue that Michel-0 was having. I tried out version 2.8.0 of the library, fetched from Maven Central.

Some additional information before providing the test code I wrote:

The software I wrote is the following: `public class Terminal {

public static void main(String[] args) throws InterruptedException {
    SerialPort[] ports = SerialPort.getCommPorts();
    for (SerialPort sp : ports) {
        System.out.println("Available serial port: " + sp);
    }
    if(args.length != 5) {
        System.err.println("Usage: Terminal <interface name> <baudrate> <data bits> <stop bits> <parity: 0,1,2>");
        System.exit(1);
    }
    System.out.println("Arguments: " + Arrays.toString(args));
    SerialPort comPort = SerialPort.getCommPort(args[0]);
    comPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 10000, 10000);

    comPort.setBaudRate(Integer.parseInt(args[1]));
    comPort.setParity(Integer.parseInt(args[4]));
    comPort.setNumDataBits(Integer.parseInt(args[2]));
    comPort.setNumStopBits(Integer.parseInt(args[3]));
    comPort.setFlowControl(SerialPort.FLOW_CONTROL_RTS_ENABLED | SerialPort.FLOW_CONTROL_CTS_ENABLED);

    comPort.openPort();

    InputStream is = comPort.getInputStream();
    OutputStream os = comPort.getOutputStream();

    Thread.sleep(1000);

    comPort.addDataListener(new SerialPortDataListener() {
        @Override
        public int getListeningEvents() {
            return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
        }

        @Override
        public void serialEvent(SerialPortEvent serialPortEvent) {
            try {
                byte[] data = new byte[1024];
                int read = 0;
                if (is.available() > 0) {
                    while ((read = is.read(data)) > 0) {
                        System.out.print(new String(data, 0, read, StandardCharsets.US_ASCII));
                    }
                }
            } catch (IOException e) {
                System.out.println("Last error code: " + comPort.getLastErrorCode() + ", " + comPort.getLastErrorLocation());
                e.printStackTrace();
            }
        }
    });
    try {
        // Read from keyboard and send on Enter
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while((line = br.readLine()) != null) {
            byte[] toSend = line.getBytes(StandardCharsets.US_ASCII);
            os.write(toSend);
            os.write(new byte[] { 0x0D, 0x0A });
        }
    } catch (Exception e) {
        System.out.println("Last error code: " + comPort.getLastErrorCode() + ", " + comPort.getLastErrorLocation());
        e.printStackTrace();
    } finally {
        comPort.closePort();
    }
}

} ` When I run the software and I try to send something, I get the following exception:

Available serial port: Dispositivo Bluetooth Available serial port: Spp1 Available serial port: Porta di comunicazione (COM1) Available serial port: USB-Serial Controller Arguments: [USB-Serial Controller, 4800, 7, 1, 2] this is a test Last error code: 0, -1 com.fazecast.jSerialComm.SerialPortIOException: This port appears to have been shutdown or disconnected. at com.fazecast.jSerialComm/com.fazecast.jSerialComm.SerialPort$SerialPortOutputStream.write(SerialPort.java:1858) at com.fazecast.jSerialComm/com.fazecast.jSerialComm.SerialPort$SerialPortOutputStream.write(SerialPort.java:1840) at eu.dariolucia.reatmetric.driver.serial/eu.dariolucia.reatmetric.driver.serial.tool.Terminal.main(Terminal.java:85)

If I change the code to start a separate thread and perform a read directly on the comPort InputStream, then I get the same exception. I am available to run any further test or debugging that it might be required to get this fixed.

dariol83 commented 2 years ago

My bad. Disregard the previous post: I am using the string returned by the toString() method instead of the proper system port name. Sorry!

Now everything works if:

The last bit I need to understand, is how to use a BufferedReader to read lines out of the InputStream, because I am getting tons of SerialPortTimeoutExceptions, even if the port is set as nonblocking and the read timeout is set to something like 5 millions...

Sorry again for the mess. A suggestion perhaps: why is the getCommPort returning a "fake" ("User Defined") port instead of raising an exception, when the specified port ID is not found?

hedgecrw commented 2 years ago

Answers to your questions:

1) getCommPort() returns a "User Defined" port instead of raising an exception because the primary purpose of this method was to allow users to define their own serial port that failed to enumerate correctly using the getCommPorts() method. We need to maintain a way for users to self-identify such a port without forcing it to be present in the enumerated ports list. If you don't need to do this, the recommended way to get a SerialPort object is to take it from the list returned by getCommPorts(). 2) The reason you are getting tons of SerialPortTimeoutExceptions is because you are setting the serial port to non-blocking mode (which is the opposite of what you want). Non-blocking means it will immediately return with any available data (so your read timeouts are meaningless), and since no data is available when you call the function, it throws a timeout exception. In your case, I think you actually want a blocking or semi-blocking read timeout.

stefanusbenhard commented 2 years ago

Hi, i received this error as well No bytes written. This port appears to have been shutdown or disconnected. And also i already use this : int getLastErrorCode(); int getLastErrorLocation();

And get this result 0 -> Last Error Code 323 -> Last Error Location

The problem is, i don't know what is that code means. Btw i'm using release version 2.8.1 JSerialComm. My java program working on Ubuntu Environment. I was using 2.8.0 beta before this version and it ran completely. But after a while im using and it displays that error. So i'm changing to 2.8.1 and it still display the same

hedgecrw commented 2 years ago

@stefanusbenhard, can you post a small example of your code that illustrates how you're opening the port, configuring it, calling the write method, and printing out the errors? Also, what OS are you using? I can't see a way in the code for the error location you're seeing to be correct, so I need to figure out exactly how you're getting to this error. Also, if possible, could you please try it with this version which has some updated error code internals:

https://www.dropbox.com/t/TKIbuNhB0K03KFPO

hedgecrw commented 2 years ago

@stefanusbenhard, you can actually just use the latest release for testing now - v2.8.2 was released today.

stefanusbenhard commented 2 years ago

Hi @hedgecrw sorry for my late response. I Already install the 2.8.2 version today including the Beta-1 you send me before and it's just act the same. For now i can only give you my code and hopefully can repair the plugin. This is my code that include opening port, set baud rate (configuration) include for printing out through serial port.

`public class PrintingTesting {

SerialPort printingPort;

private void printingFunction(String path) {
    printingPort = SerialPort.getCommPort("/dev/ttyUSB1");
    printingPort.setBaudRate(19200);
    printingPort.setNumDataBits(8);
    printingPort.setNumStopBits(1);
    printingPort.setParity(SerialPort.NO_PARITY);
    printingPort.openPort();

    InputStream inputStream=null;
    if (printingPort.isOpen()) {
        try {
            File fileObject = new File(path);
            inputStream = new FileInputStream(fileObject);
            IOUtils.copy(inputStream, printingPort.getOutputStream());
        } catch (final FileNotFoundException ex) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    ex.printStackTrace();
                }
            });
        } catch (final IOException ex2) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    ex2.printStackTrace();
                }
            });
        } finally {
            try {
                inputStream.close();
                printingPort.getOutputStream().close();
            } catch (IOException ex) {
            }
        }
    } 
}

public static void main(String[] args) {
    PrintingTesting pt = new PrintingTesting();
    pt.printingFunction("/home/it/Project/PrinterAdapter/data_file_print/2022-01-14_15:52:48.txt");
}

}`

And this is the error section

image

Btw i'm using : DISTRIB_ID=Ubuntu DISTRIB_RELEASE=20.04 DISTRIB_CODENAME=focal DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"

Linux 5.11.0-46-generic #51~20.04.1-Ubuntu SMP Fri Jan 7 06:51:40 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

I hope that you can gave me advice on how to repair this thing. Because it affect my work so badly. I'm using this program to output the file through serialport and going to EPSON Printer LX-300+ii, this comment also attach a file that been encode by EPSON LX-300+ii driver. So in the meantime, this program should read the encode file and output it through serialPort to EPSON LX-300+ii printer. Last time i remember use it and it works [Completely Printing through serialport], i think i'm using 2.7.0, but for now it all not working, including the beta one you send me.

2022-01-14_15:52:48.txt

stefanriesner commented 2 years ago

I'm getting the same error message on Linux (always, reproducibly) with version 2.8.2 while version 2.7.0 works (reproducibly). Both versions 2.8.2 as well as 2.7.0 work on Windows 10 (reproducibly). Linux is RaspbianOS on a Raspberry Pi. Both the Raspi and the Windows machine are connected to the same hardware via RS232, so there is no difference in the cable or the connected device. Code: ` @Component public class Rs232 implements ApplicationRunner {

private static final Logger LOG = LoggerFactory.getLogger(Rs232.class);

@Override
public void run(ApplicationArguments args) throws Exception {
    SerialPort serialPort = getSerialPort();
    initSerialPort(serialPort);
    Read5Bytes(serialPort);
    serialPort.closePort();
    LOG.info("Port closed.");
}

private SerialPort getSerialPort() {
    SerialPort[] serialPortList = SerialPort.getCommPorts();
    SerialPort preferredPort = null;
    for (SerialPort port : serialPortList) {
        String systemPortName = port.getSystemPortName();
        LOG.info("Existing Port: System name: {}", systemPortName);
        if (systemPortName.equals("ttyS0") || systemPortName.equals("COM1")) {
            preferredPort = port;
            break;
        }
    }
    return preferredPort;
}

private void initSerialPort(SerialPort serialPort) {
    LOG.info("Opening port {}", serialPort.getSystemPortName());
    serialPort.openPort();
    LOG.info("Port opened.");
    serialPort.setBaudRate(38400);
    serialPort.setNumDataBits(8);
    serialPort.setNumStopBits(1);
    serialPort.setParity(SerialPort.NO_PARITY);
    serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
    serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
    LOG.info("Settings done.");
}

private void Read4Bytes(SerialPort serialPort) {
    try {
        InputStream inputStream = serialPort.getInputStream();
        for (int i = 1; i < 5; i++) {
            readInput(inputStream);
        }
    } catch (Exception e) { LOG.error("Exception thrown: ", e); }
}

private int readInput(InputStream inputStream) {
    LOG.info("Reading input stream...");
    int input;
    try {
        input = inputStream.read();
        LOG.info("Byte read: {}", input);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    return input;
}

} `

Output under Windows (identical with 2.7.0 and 2.8.2): 2022-01-17 20:13:42.593 INFO 16556 --- [ main] rs232.Rs232 : Existing Port: System name: COM1 2022-01-17 20:13:42.593 INFO 16556 --- [ main] rs232.Rs232 : Opening port COM1 2022-01-17 20:13:42.810 INFO 16556 --- [ main] rs232.Rs232 : Port opened. 2022-01-17 20:13:44.030 INFO 16556 --- [ main] rs232.Rs232 : Settings done. 2022-01-17 20:13:44.030 INFO 16556 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:13:44.030 INFO 16556 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:13:44.030 INFO 16556 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:13:44.764 INFO 16556 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:13:44.765 INFO 16556 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:13:45.751 INFO 16556 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:13:45.751 INFO 16556 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:13:46.754 INFO 16556 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:13:46.770 INFO 16556 --- [ main] rs232.Rs232 : Port closed.

Output under Linux at Raspi with 2.7.0: 2022-01-17 20:18:01.990 INFO 2264 --- [ main] rs232.Rs232 : Existing Port: System name: ttyS0 2022-01-17 20:18:01.994 INFO 2264 --- [ main] rs232.Rs232 : Opening port ttyS0 2022-01-17 20:18:02.196 INFO 2264 --- [ main] rs232.Rs232 : Port opened. 2022-01-17 20:18:03.397 INFO 2264 --- [ main] rs232.Rs232 : Settings done. 2022-01-17 20:18:03.403 INFO 2264 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:18:15.427 INFO 2264 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:18:15.428 INFO 2264 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:18:16.431 INFO 2264 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:18:16.431 INFO 2264 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:18:17.440 INFO 2264 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:18:17.441 INFO 2264 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:18:18.449 INFO 2264 --- [ main] rs232.Rs232 : Byte read: 5 2022-01-17 20:18:18.450 INFO 2264 --- [ main] rs232.Rs232 : Port closed.

Output under Linux at Raspi with 2.8.2: 2022-01-17 20:18:53.102 INFO 2292 --- [ main] rs232.Rs232 : Existing Port: System name: ttyS0 2022-01-17 20:18:53.107 INFO 2292 --- [ main] rs232.Rs232 : Opening port ttyS0 2022-01-17 20:18:53.308 INFO 2292 --- [ main] rs232.Rs232 : Port opened. 2022-01-17 20:18:53.308 INFO 2292 --- [ main] rs232.Rs232 : Settings done. 2022-01-17 20:18:53.311 INFO 2292 --- [ main] rs232.Rs232 : Reading input stream... 2022-01-17 20:18:53.324 ERROR 2292 --- [ main] rs232.Rs232 : Exception thrown:

java.lang.RuntimeException: com.fazecast.jSerialComm.SerialPortIOException: This port appears to have been shutdown or disconnected. at rs232.Rs232.readInput(Rs232.java:70) ~[classes!/:na] at rs232.Rs232.Read4Bytes(Rs232.java:58) ~[classes!/:na] at rs232.Rs232.run(Rs232.java:22) ~[classes!/:na] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:758) ~[spring-boot-2.6.2.jar!/:2.6.2] at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:748) ~[spring-boot-2.6.2.jar!/:2.6.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:309) ~[spring-boot-2.6.2.jar!/:2.6.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.2.jar!/:2.6.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) ~[spring-boot-2.6.2.jar!/:2.6.2] at rs232.Rs232Application.main(Rs232Application.java:9) ~[classes!/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[rs232--2-8-2.jar:na] at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[rs232--2-8-2.jar:na] at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[rs232--2-8-2.jar:na] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[rs232--2-8-2.jar:na] Caused by: com.fazecast.jSerialComm.SerialPortIOException: This port appears to have been shutdown or disconnected. at com.fazecast.jSerialComm.SerialPort$SerialPortInputStream.read(SerialPort.java:1791) ~[jSerialComm-2.8.2.jar!/:2.8.2] at rs232.Rs232.readInput(Rs232.java:67) ~[classes!/:na] ... 16 common frames omitted

hedgecrw commented 2 years ago

@stefanriesner and @stefanusbenhard, could you please try testing your applications using the following library version:

https://www.dropbox.com/t/s6TAYAXp5FiXVIGB

The only thing I can see that might be causing your issues is related to the way that pointers are being passed between Java and native C code. Hopefully this update will resolve that issue.

stefanusbenhard commented 2 years ago

@hedgecrw it still causing the same thing. I already import the library and using clean and build to ensure cleaning the earliest version. But it still showed the same thing

stefanriesner commented 2 years ago

@hedgecrw It works now for me with your version 2.8.3-beta1, under Linux as well as Windows. Nice!

hedgecrw commented 2 years ago

@stefanusbenhard, I'm not seeing how this error can be thrown any more with the most recent fix. Perhaps your application was still pulling the latest release instead of using the local beta JAR? In either case, to make it simpler, please update your application to use the latest actual release from today which contains all of these fixes (2.8.4), and then also update your printing function to the following and let me know what it says regarding the error number and line number:

private void printingFunction(String path) {
    printingPort = SerialPort.getCommPort("/dev/ttyUSB1");
    printingPort.setBaudRate(19200);
    printingPort.setNumDataBits(8);
    printingPort.setNumStopBits(1);
    printingPort.setParity(SerialPort.NO_PARITY);
    printingPort.openPort();

    InputStream inputStream=null;
    if (printingPort.isOpen()) {
        try {
            File fileObject = new File(path);
            inputStream = new FileInputStream(fileObject);
            IOUtils.copy(inputStream, printingPort.getOutputStream());
        } catch (final SerialPortIOException ex) {
            System.out.println("SerialPortIOException encountered, Code = " + printingPort.getLastErrorCode() + ", Line = " + printingPort.getLastErrorLocation());
        } catch (final FileNotFoundException ex) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    ex.printStackTrace();
                }
            });
        } catch (final IOException ex2) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    ex2.printStackTrace();
                }
            });
        } finally {
            try {
                inputStream.close();
                printingPort.getOutputStream().close();
            } catch (IOException ex) {
            }
        }
    } 
}
stefanusbenhard commented 2 years ago

@hedgecrw the error has been gone. But the output of the serial port is still the same (Only half of serial port data that have been sended) And when i use the code you give me. It throws an IOException

image

hedgecrw commented 2 years ago

@stefanusbenhard, great - that error code and line are super helpful! I think I see the problem. Please test the following version, and I expect it to fix your problem:

https://www.dropbox.com/t/vNq3bHI0o75vtP3X

stefanusbenhard commented 2 years ago

@hedgecrw Thankyou so much for the new release! It Workss.. Superb developer (y) I really appreciate your works Mate. I'm waiting for the release version. Once again thankyou so much

hedgecrw commented 2 years ago

All issues in this thread should now be fixed with today's release v2.8.5. I'm going to go ahead and close this issue since it's getting quite long and let users with future problems open a new issue to address them. Thanks for everyone's help and extended testing on this thread!