5

FXApps: Control Arduino from a JavaFX application

 3 years ago
source link: http://fxapps.blogspot.com/2017/04/control-arduino-from-javafx-application.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
That's exciting. I just finished a post about JArduino and Java and I was supposed to sleep, but I wanted to give it a try with JavaFX, so I did and in less than a minute I could make a first experiment!

Show a light sensor information in a label

In Control Arduino from Java using JArduino post we printed on console the current light intensity coming from a LDR connected to an arduino. In less than a minute I could add it to a label in a JavaFX application, see:
Screenshot%2Bfrom%2B2017-04-30%2B00-29-28.png
 I basically reused the same class from the other post and read the output in a JavaFX thread (see Platform.runLater on the code below).

package org.fxapps.arduino;

import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; import javafx.stage.Stage;

public class App extends Application { LightSensorApp lightSensorApp;

public static void main(String[] args) { // this method should not be required on fx apps launch(); }

@Override public void start(Stage stage) throws Exception { Label lbl = new Label(); Scene scene = new Scene(new StackPane(lbl),300, 100); lightSensorApp = new LightSensorApp("/dev/ttyUSB0" , s -> Platform.runLater(() -> lbl.setText("light: " + s )) ); lightSensorApp.runArduinoProcess(); stage.setScene(scene); stage.setTitle("Light control with monitoring"); stage.show(); }

}

My plan was to also turn on a LED from the JavaFX application. So let's continue on the original plan.

Controlling a LED and reading a LDR

In the second version I used a chart to display the LDR sensor data in real time and also used a button to control a LED, so when we turn the LED on we can see the values changing.

See our circuit now and notice a LED on digital pin D1:
photo4911725729738237881.jpg
Now the code on LightSensorApp (which extends JArduino) was modified to include also a LED command. The JavaFX application still look simple, we have a button a chart.
Screenshot%2Bfrom%2B2017-04-30%2B02-29-02.png
The following video shows it in action:

The code is below and we didn't modify the maven pom.xml, so please check the only two Java files we have in our project.

package org.fxapps.arduino;

import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart.Data; import javafx.scene.control.ToggleButton; import javafx.scene.layout.VBox; import javafx.stage.Stage;

public class App extends Application {

XYChart.Series<Number, Number> series; LightSensorApp lightSensorApp; long initialTime;

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

@Override public void start(Stage stage) throws Exception { lightSensorApp = new LightSensorApp("/dev/ttyUSB0", false, this::updateChart); LineChart<Number, Number> chart = createChart(); initialTime = System.currentTimeMillis(); series = new XYChart.Series<>(); ToggleButton tbLed = new ToggleButton("LED"); tbLed.selectedProperty().addListener(c -> lightSensorApp.setTurnOnLed(tbLed.isSelected())); chart.getData().add(series); lightSensorApp.runArduinoProcess(); VBox vb = new VBox(50, chart, tbLed); vb.setAlignment(Pos.CENTER); Scene scene = new Scene(vb, 800, 600); stage.setScene(scene); stage.setTitle("Light control with monitoring"); stage.show(); stage.setOnCloseRequest(e -> System.exit(0)); }

private LineChart<Number, Number> createChart() { LineChart<Number, Number> chart = new LineChart<>(new NumberAxis(), new NumberAxis()); chart.setTitle("Light Intensity"); chart.getXAxis().setTickLabelsVisible(false); chart.getXAxis().setLabel("Time"); chart.getXAxis().setTickMarkVisible(false); chart.setCreateSymbols(false); chart.setLegendVisible(false); chart.setAlternativeColumnFillVisible(false); return chart; }

private void updateChart(Short s) { long time = System.currentTimeMillis() - initialTime; Data<Number, Number> data = new XYChart.Data<>(time, s); Platform.runLater(() -> series.getData().add(data)); }

}

package org.fxapps.arduino;

import java.util.function.Consumer; import org.sintef.jarduino.AnalogPin; import org.sintef.jarduino.DigitalPin; import org.sintef.jarduino.InvalidPinTypeException; import org.sintef.jarduino.JArduino;

public class LightSensorApp extends JArduino {

private final DigitalPin LED_PIN = DigitalPin.PIN_2; private Consumer<Short> receiveLight; private boolean turnOnLed;

public LightSensorApp(String port, boolean led, Consumer<Short> receiveLight) { super(port); this.turnOnLed = led; this.receiveLight = receiveLight; }

@Override protected void setup() throws InvalidPinTypeException { pinMode(LED_PIN, OUTPUT); }

@Override protected void loop() throws InvalidPinTypeException { short light = analogRead(AnalogPin.A_0); digitalWrite(LED_PIN, turnOnLed? HIGH : LOW); System.out.println(light); receiveLight.accept((short) map(light, 300, 1023, 0, 100)); delay(100); }

public void setTurnOnLed(boolean turnOnLed) { this.turnOnLed = turnOnLed; }

}

The code used in these projects are on my github.

What's next?

You tell me. This is so exciting and my head explode about the possibilities. Think about using API with the great hansolo libraries, such as TilesFX and Medusa. Or about integrating your business process with "things" using the JArduino ethernet integration and jBPM.... The list goes on and on.
NOTE: I know and understand that we have many other modern boards with modern APIs, but arduino is, easy, cheap and popular which makes it really exciting!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK