I'm writing an application (for personal use) that allows me to send a string over usb to an Arduino.
I wrote this method for sending the data:
/**
* Sends the data to the Arduino.
* A new Thread is created for sending the data.
* A transmission cool-down is started before send() method can be used again.
* @param data the data to send to the Arduino
*/
public void send(String data) {
if (connected && !sending) {
// Set 'sending' to true so only 1 Thread can be active at a time
sending = true;
// Create a new thread for sending the data
Thread thread = new Thread(() -> {
// Send the data
PrintWriter output = new PrintWriter(chosenPort.getOutputStream());
output.print(data);
System.out.println("Data sended");
output.flush();
// Wait for the transmission cool-down and set 'sending' to false to allow for another Thread to send data
try { Thread.sleep(transmissionCoolDown); } catch (InterruptedException interruptedException) { interruptedException.printStackTrace(); }
sending = false;
System.out.println("cooldown is over");
});
thread.start();
}
}
sending is a boolean value that I use to indicate whether a Thread is sending data. The transmissionCooldown is simply to enforce a certain waiting period before data can be sent again.
And this is where the method is being used:
@FXML
private void sendClicked() {
// Only do something if a connection is active and an image is selected.
// Should be unnecessary since the send button is only enables when both are true.
if (connected && selectedIV.getImage() != null) {
if (!sending) {
// Save the original text of the send button and disable the disconnect button
String ogText = sendButton.getText();
System.out.println(ogText);
connectButton.setDisable(true);
// If the data has not been saved before, get the data by formatting the image
if (data == null) {
data = imgCon.toStringFormat(true);
}
ardComm.send(data);
// While the ArduinoCommunicator is busy sending, change the text on the send button to indicate the data is being transmitted
sendButton.setText("busy");
while (ardComm.isSending()) {
}
// Restore the text on the send button
sendButton.setText(ogText);
connectButton.setDisable(false);
}
}
}
sendButton is the JavaFX Button that calls the sendClicked() method and ardCom is and instance of the class that contains the send() method. isSending() simply returns the sending attribute of the ardCom, which is set to true at the start of the send() method and set to false when the Thread is done sending.
The problem is with this piece of code:
sendButton.setText("busy");
while (ardComm.isSending()) {
}
// Restore the text on the send button
sendButton.setText(ogText);
I'm trying to set the sendButton's text to busy to indicate that the data is being sent, then loop until the data transmission is finished (sending is set to false) and end it with changing the text on the sendButton back to the original text. I know this is probably not the best way to achieve this, but I was playing around and could not figure out why this is not working as expected.
The problem is that for some reason, the while loop never ends.