24 de mai. de 2017

Controlando o Arduino de uma aplicação JavaFX

É muito empolgante isso! Eu tinha acabado de escrever um pequeno artigo sobre Java e JArduino, mas eu queria fazer um teste com JavaFX e em poucos minutos estava funcionando!

Mostrando informação de um sensor de luz em label


No post sobre Java e JArduino nós imprimimos no console a atual intensidade de luz vinda de um sensor LDR conectado a um arduino. Em menos de um minuto conseguimos mostrar essa informação em um label, veja:



 Eu basicamente reusei a mesma classe do outro post e li a saída em uma thread JavaFX (veja Platform.runLater no código abaixo).

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();
}
}
view raw App.java hosted with ❤ by GitHub
O plano era também ligar um led da aplicação JavaFX, então vamos seguir o plano original.

Controlando um LED e lendo o LDR


Na segunda versão eu usei um gráfico para mostrar os dados do sensor LDR em tempo relam e também um botão para controlar um LED, então quanod ligamos o LED podemos ver o valor do sensor mudando.

Veja nosso circuito e note um LED no pino digital D1:



Agora o código da classe LightSensorApp (que estende de  JArduino) foi modificado para incluir um comando de um LED. A App JavaFX ainda é simples, tem um gráfico e um botão:



O seguinte vídeo mostra a aplicação em ação:



O código está mostrado abaixo e não modificamos o pom.xml, somente dois arquivos Java que temos em nosso projeto.

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));
}
}
view raw App.java hosted with ❤ by GitHub
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;
}
}

O código usado nesse projeto está no  meu github.




Nenhum comentário:

Postar um comentário