I am trying to achieve what seems looks like a simple task, but like anything looks can be deceiving. Hoping someone here can point me in the right direction of what STUPID thing I am doing wrong...cant seem to get this going after days of searching....
Have a JavaFX application, that receives data from an Arduino nano, with data the provides voltage levels from two sensors. I also want to be able to send data back to the arduino, to have it alter some parameters. I have the data streaming in, comma delimited, and I am able through a bufferedreader to parse the data and stuff an Array. So far this has been working quite well.
On my JavaFX GUI (Build with Scenebuilder) I have several Radio buttons, that when pressed, I want to be able to send back some very simple data (like 1, 2, 3,4 etc) depending on what radio button was pushed. This in turn I will parse on the arduino, to have it change what it is sending, or perform some logic. This is where I AM STUCK! For the LIFE OF ME, I cant get my JavaFX application to SEND DATA BACK through the serial port. I am sure I am doing something dumb and stupid, maybe mixing up my threads etc. Have created buffered input and output streams, but I need some help on calling these methods under the serialport thread/event handler...Here is my Java Code:
package JSWRV3;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import com.sun.org.apache.xpath.internal.operations.String;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Cursor;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import java.io.*;
import java.lang.*;
import java.util.Scanner;
import static java.lang.System.out;
public class Main extends Application {
private java.lang.String Values[];
public double fwdVolts, revVolts, fwdPower, revPower;
SerialPort commPort = SerialPort.getCommPort("COM20");
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("ZTfxml.fxml"));
Parent root = loader.load(); //Need to create an instance of my controller here
ZTController myController = loader.getController(); //Injects controller here for us to use
primaryStage.setTitle("POWER METER");
primaryStage.setScene(new Scene(root, 800, 480));
primaryStage.show();
root.setCursor(Cursor.NONE);
//
//
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
commPort.closePort();
Platform.exit();
System.exit(0);
}
});
//
if (commPort.isOpen()) commPort.closePort();
try {
commPort.setComPortParameters(115200, 8, 1, 0);
commPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 1, 1);
commPort.openPort();
} catch (IOError ex) {out.println("Serial Port Error" + ex.toString()); }
//
//
commPort.addDataListener(new SerialPortDataListener() {
//
BufferedInputStream inputStream = new BufferedInputStream(commPort.getInputStream());
BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream));
BufferedOutputStream outputStream = new BufferedOutputStream(commPort.getOutputStream());
BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
//
//
@Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
@Override
public void serialEvent(SerialPortEvent serialPortEvent) {
if(serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE)
return;
//
try {
java.lang.String nextString = inputReader.readLine();
Values = nextString.split(",");
}catch(IOException ex){ex.printStackTrace();}
if(Values.length == 4){
parseString(Values);} //All this works GREAT!
Platform.runLater(()-> myController.setGauge(fwdVolts, revVolts, fwdPower, revPower));//Send to GUI Thread
}
});
}
//
public void parseString(java.lang.String[] inputString){
fwdVolts = Double.parseDouble(inputString[0]);
revVolts = Double.parseDouble(inputString[1]);
fwdPower = Double.parseDouble(inputString[2]);
revPower = Double.parseDouble(inputString[3]);
}
public void sendData(byte[] dataOut) {
try {//STUCK How do I access the port to write to it???
commPort.writeBytes(dataOut, dataOut.length);
} catch (IOError ex) {
ex.printStackTrace();
}
}
//
public static void main(java.lang.String args) {
launch(args);
}
}
and my Controller Class
package JSWRV3;
import com.fazecast.jSerialComm.SerialPort;
import eu.hansolo.enzo.gauge.RectangularGauge;
import eu.hansolo.enzo.lcd.Lcd;
import eu.hansolo.enzo.ledbargraph.LedBargraph;
import java.io.IOError;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
public class ZTController {
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private RectangularGauge fwdpower;
@FXML
private RectangularGauge revpower;
@FXML
private RadioButton B160;
@FXML
private RadioButton B80;
@FXML
private RadioButton B60;
@FXML
private RadioButton B40;
@FXML
private RadioButton B30;
@FXML
private RadioButton B20;
@FXML
private RadioButton B17;
@FXML
private RadioButton B15;
@FXML
private RadioButton B12;
@FXML
private RadioButton B10;
public void initialize( ) {
assert fwdpower != null : "fx:id=\"fwdpower\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert revpower != null : "fx:id=\"revpower\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B160 != null : "fx:id=\"B160\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B80 != null : "fx:id=\"B80\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B60 != null : "fx:id=\"B60\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B40 != null : "fx:id=\"B40\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B30 != null : "fx:id=\"B30\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B20 != null : "fx:id=\"B20\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B17 != null : "fx:id=\"B17\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B15 != null : "fx:id=\"B15\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B12 != null : "fx:id=\"B12\" was not injected: check your FXML file 'ZTfxml.fxml'.";
assert B10 != null : "fx:id=\"B10\" was not injected: check your FXML file 'ZTfxml.fxml'.";
//
ToggleGroup toggleRbuttons = new ToggleGroup(); //This allows ONLY ONE button to be selected!
B160.setToggleGroup(toggleRbuttons); //==> Has sendString action event defined (below);
B80.setToggleGroup(toggleRbuttons);
B60.setToggleGroup(toggleRbuttons);
B40.setToggleGroup(toggleRbuttons);
B30.setToggleGroup(toggleRbuttons);
B20.setToggleGroup(toggleRbuttons);
B17.setToggleGroup(toggleRbuttons);
B15.setToggleGroup(toggleRbuttons);
B12.setToggleGroup(toggleRbuttons);
B10.setToggleGroup(toggleRbuttons);
//
}
Main objects = new Main(); //Allows us to access non-static methods in Main!
//
@FXML
public void setGauge(Double fwdVolts, Double revVolts, Double fwdPower, Double revPower) {
fwdpower.setValue(fwdPower);
revpower.setValue(revPower);
}
}
// All the Radio button Events, and we need to send data BACK to the Arduino
//
@FXML
public void sendString(ActionEvent event){
byte[] testByte = "this is data FROM javaFX..testing..\r\n".getBytes();
//STUCK!! How to I send this to my bufferedWriter to be send to Serial port??????
//Trying to access objects.sendData(testByte); ==>Does not work...HELP!
//This is what I try:
objects.sendData(testByte);
}
}