Arduino Uno crash caused by serialPort.close() ? (JavaFX)

Greatings,

I'm trying to send a string from an JavaFX application to an Arduino Uno and show it on a 16x2 LCD.

The problem is that the LCD doesn't change to the new string but insted it stays on "Hallo, ich warte...".

I can't seem to find the problem and I'm afraid I'll need some help.

Here are the codes:

JavaFX:

package sample;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import jssc.SerialPort;
import jssc.SerialPortException;
import jssc.SerialPortList;

import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaFX_jSSC extends Application {

   ObservableList<String> portList;

   private void detectPort(){

       portList = FXCollections.observableArrayList();

       String[] serialPortNames = SerialPortList.getPortNames();
       for(String name: serialPortNames){
           System.out.println(name);
           portList.add(name);
       }
   }

   @Override
   public void start(Stage primaryStage) {
       detectPort();

       final ComboBox comboBoxPorts = new ComboBox(portList);
       final TextField textFieldOut = new TextField();
       Button btnSend = new Button("Send");

       btnSend.setOnAction( s -> {
           if(comboBoxPorts.getValue() != null &&
                   !comboBoxPorts.getValue().toString().isEmpty()){

               String stringOut = textFieldOut.getText();

               try {
                   SerialPort serialPort =
                           new SerialPort(comboBoxPorts.getValue().toString());

                   serialPort.openPort();
                   serialPort.setParams(
                           SerialPort.BAUDRATE_9600,
                           SerialPort.DATABITS_8,
                           SerialPort.STOPBITS_1,
                           SerialPort.PARITY_NONE);
                   serialPort.writeBytes(stringOut.getBytes());
                   serialPort.closePort();

               } catch ( SerialPortException ex) {
                   Logger.getLogger(
                           JavaFX_jSSC.class.getName()).log(Level.SEVERE, null, ex);
               }

           }else{
               System.out.println("No SerialPort selected!");
           }
       });

       VBox vBox = new VBox();
       vBox.getChildren().addAll(
               comboBoxPorts,
               textFieldOut,
               btnSend);

       StackPane root = new StackPane();
       root.getChildren().add(vBox);

       Scene scene = new Scene(root, 300, 250);

       primaryStage.setTitle("J-A-Kommu");
       primaryStage.setScene(scene);
       primaryStage.show();
   }


   public static void main(String[] args) {
       launch(args);
   }
}

Arduino:

//LiquidCrystal-Bibliothek einrichten
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

String charsIn = "";

void setup() {
 Serial.begin(9600);
 
 lcd.begin(16, 2);
 lcd.print("Hallo,");
 lcd.setCursor(0, 1);
 lcd.print("ich warte...");
}

void loop() {
 while(Serial.available()){
   char charRead = Serial.read();
   charsIn.concat(charRead);
   delay(3);
 }
 if(charsIn != ""){
   lcd.clear();
   delay(500);
   lcd.setCursor(0, 0);
   lcd.print(charsIn);
   charsIn = "";
 }
}

What do you see if you print charRead to the Serial monitor after a character has been read ?

I'm not using the Serial monitor. I'm using the serial conection to communicate with the JavaFX appliation. Do I need to open another Serial to print to the serial Monitor? Sorry I'm a beginner.

i didn't compile this, but it should work if you send a data to a right port

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
 Serial.begin(9600);
 lcd.begin(16, 2);
 lcd.print("Hallo,");
 lcd.setCursor(0, 1);
 lcd.print("ich warte...");
}

void loop() {
 while (Serial.available()) {
   String temp = Serial.readString();
   temp.trim();
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(temp);
 }
}

@EcstasyAwesome

I tried your code but it still doesn't work. Like before the LCD just flickers one time and shows the same text as before "Hallo, ich warte..."

I found a workaround. I now implemented a "Connect"-Button. Pushing it connects the JavaFX-programm to the Arduino via serial connection and pushing it again disconnects the two.

I think the problem was in the JavaFX code. While sending the string trough the serial connection the port was closed to early, so that the Atmega had an error and had the reaload the Arduino Sketch. Thats why the LCD always flickered for a second and showed the setup text again.

Here is the new code. While trying to find the source of the problem I have changed the code a bit. I now use the jSerialComm- Library(Java) insted of the jssc-Library(Java)

Still I want to thank you guys for your help.

JavaFX:

import com.fazecast.jSerialComm.SerialPort;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.PrintWriter;


public class JavaFX_jSSC extends Application {

    static SerialPort chosenPort;

    ObservableList<String> portList;

    private void detectPort(){

        portList = FXCollections.observableArrayList();

        SerialPort[] portNames = SerialPort.getCommPorts();
        for(int i = 0; i < portNames.length; i++)
            portList.add(portNames[i].getSystemPortName());
    }

    @Override
    public void start(Stage primaryStage) {


        detectPort();

        final ComboBox comboBoxPorts = new ComboBox(portList);
        final TextField textFieldOut = new TextField();
        Button btnSend = new Button("Send");
        Button btnConnect = new Button("Connect");

        btnSend.setDisable(true);

        btnConnect.setOnAction( c -> {
            if (btnConnect.getText().equals("Connect")){
                //Versuch eine Verbindung zum seriellen Port herzustellen
                chosenPort = SerialPort.getCommPort(comboBoxPorts.getValue().toString());
                chosenPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
                if (chosenPort.openPort()){
                    btnConnect.setText("Disconnect");
                    comboBoxPorts.setDisable(true);
                    btnSend.setDisable(false);
                }
            }else{
                chosenPort.closePort();
                comboBoxPorts.setDisable(false);
                btnConnect.setText("Connect");
                btnSend.setDisable(true);
            }
        });

        btnSend.setOnAction( s -> {

            try {Thread.sleep(100); } catch(Exception e) {}

            PrintWriter output = new PrintWriter(chosenPort.getOutputStream());
            output.print(textFieldOut.getText());
            output.flush(); //Sendet die Daten

        });

        VBox vBox = new VBox();
        HBox hBox = new HBox(10);
        hBox.getChildren().addAll(comboBoxPorts, btnConnect);
        vBox.getChildren().addAll(
                hBox,
                textFieldOut,
                btnSend);

        StackPane root = new StackPane();
        root.getChildren().add(vBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("J-A-Kommu");
        primaryStage.setScene(scene);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

Arduino:

//LiquidCrystal-Bibliothek einrichten
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

String charsIn = "";

void setup() {
  lcd.begin(16, 2);
  lcd.print("Hallo,");
  lcd.setCursor(0, 1);
  lcd.print("ich warte...");
  Serial.begin(9600);
  Serial.setTimeout(50);
}

void loop() {
  String text = Serial.readString();
  String line1 = text.substring(0, 16);
  String line2 = text.substring(16, 32);
  
  if(text.length() > 0) {
    lcd.setCursor(0, 0);
    lcd.print("                ");
    lcd.setCursor(0, 1);
    lcd.print("                ");
  }
  
    lcd.setCursor(0, 0);
    lcd.print(line1);
    lcd.setCursor(0, 1);
    lcd.print(line2);
}

Hey guys,

I got a quick question. Is it possible to crash the Atmega by closing a serialport while it is reading or writing, so that it restarts the Sketch?

I had some issues trying to send a string from a JavaFX-programm to the Arduino Uno and showing it on a LCD. After sending the string via serialport, I closed it right after flushing. It seemed like the close command caused some problems in the Arduino and it loaded the setup and with it the default LCD-text again insted of clearing the LCD and showing the sent string.

Opening the serial port will cause an auto reset. Perhaps closing the port does as well. You can temporarily disable the auto reset by putting a 10uF cap between the reset pin and ground. Remove the cap to upload code as the auto reset is necessary for upload.

The Uno uses DTR from the serial port of the PC to cause a reset (it is a reprogramming thing). If closing the serial port causes DTR to be dropped, the Uno will be reset and may appear to have crashed but it just did what it was told to do. There is a trace that can be cut to prevent this behavior but then you will have a more challenging time when you want to reprogram your Uno. It would be better to avoid dropping DTR.

Befor i changed my JavaFX programm, the openPort, flush and closePort command were all executed by pressing the send button. Doing that caused the Arduino to reset. But now ,that I splitted those commands into a connect button ( connects to serialport on first press and disconnects if pressed for a second time) and a send button ( only enabled if the port is open), the Uno does not reset after disconnecting. It now still shows the last sent string after I disconnected the serial port.

I do not understand why it does not restart now, but it did before the change.

I think the problem was in the JavaFX code. While sending the string trough the serial connection the port was closed to early,

Opening the serial port on a device attached to the Arduino causes it to reset which explains the symptoms that you see. Could you leave the serial connection open once it has been established ?

it can help to solve your problem, or don't close the connection like it was said in the previous post.
https://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection/

UKHeliBob:
Opening the serial port on a device attached to the Arduino causes it to reset which explains the symptoms that you see. Could you leave the serial connection open once it has been established ?

I changed my code in that way that I connect via a connect-button. If I press it the send-button is enabled which lets me send my string to the LCD. By pressing the connect-button again the connection is closed and the send-button disabled.

The difference now is that my Arduino does not restart after openening the serial port nor closing it.

The new code is shown in my replay above.

I do not understand the difference, because i still close the port via connect-button but no restart occurs.