Saturday, August 13, 2016

Bi direction communication between Arduino and PC using Java jSSC

Bi direction communication between Arduino and PC using Java jSSC


This example show Bi-direction communication between Arduino Uno and PC using Java + javaFX + jSSC:
Arduino to PC: Arduino Uno analog input, display on JavaFX LineChart
PC to Arduino: Button to control Arduino Uno on-board LED


Before start, you have to Prepare jSSC on your NetBeans project.

Arduino side: AnalogInputToUSB.ino, run on Arduino Uno.
/*
* AnalogInputUSB
* Read analog input from analog pin 0
* and send data to USB
*/

int ledPin = 13;
int analogPin = A0;
int analogValue = 0;

int incomingByte = 0;

void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop() {

if (Serial.available() > 0) {
incomingByte = Serial.read();

if(incomingByte & 0x01){
digitalWrite(ledPin, HIGH);
}else{
digitalWrite(ledPin, LOW);
}
}

analogValue = analogRead(analogPin); //Read analog input
analogValue = map(analogValue, 0, 1023, 0, 255);
Serial.write(analogValue); //write as byte, to USB

delay(100);
}a

PC Side, JavaFX_jssc_Uno.java
/*
* Example of using jSSC library to handle serial port
* Receive number from Arduino via USB/Serial and display on Label
*/
package javafx_jssc_uno;

import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import jssc.SerialPort;
import static jssc.SerialPort.MASK_RXCHAR;
import jssc.SerialPortEvent;
import jssc.SerialPortException;
import jssc.SerialPortList;

public class JavaFX_jssc_Uno extends Application {

SerialPort arduinoPort = null;
ObservableList<String> portList;

ToggleButton tbLED13;
Label labelValue;
final int NUM_OF_POINT = 50;
XYChart.Series series;

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) {

labelValue = new Label();
labelValue.setFont(new Font("Arial", 28));

detectPort();
final ComboBox comboBoxPorts = new ComboBox(portList);
comboBoxPorts.valueProperty()
.addListener(new ChangeListener<String>() {

@Override
public void changed(ObservableValue<? extends String> observable,
String oldValue, String newValue) {

System.out.println(newValue);
disconnectArduino();
connectArduino(newValue);

tbLED13.setSelected(false);
}

});

//Toggle Button to control LED on Arduino
tbLED13 = new ToggleButton("Arduino LED 13");
tbLED13.setOnAction((ActionEvent event) -> {
updateLED13();
});

//LineChart
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Voltage");

final LineChart<Number,Number> lineChart =
new LineChart<>(xAxis,yAxis);
lineChart.setTitle("Arduino Uno A0 Analog Input");
series = new XYChart.Series();
series.setName("A0 analog input");
lineChart.getData().add(series);
lineChart.setAnimated(false);

//pre-load with dummy data
for(int i=0; i<NUM_OF_POINT; i++){
series.getData().add(new XYChart.Data(i, 0));
}
//

VBox vBox = new VBox();
vBox.getChildren().addAll(
comboBoxPorts,
tbLED13,
labelValue,
lineChart);

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

Scene scene = new Scene(root, 500, 400);

primaryStage.setTitle(
"arduino-er.blogspot.com: Java + JavaFX + jSSC demo");
primaryStage.setScene(scene);
primaryStage.show();
}

private void updateLED13(){
try {
if(tbLED13.isSelected()){
if(arduinoPort != null){
arduinoPort.writeByte((byte)0x01);
System.out.println("LED 13 ON");
}else{
System.out.println("arduinoPort not connected!");
}
}else {
if(arduinoPort != null){
arduinoPort.writeByte((byte)0x00);
System.out.println("LED 13 OFF");
}else{
System.out.println("arduinoPort not connected!");
}
}
}catch (SerialPortException ex) {
Logger.getLogger(JavaFX_jssc_Uno.class.getName())
.log(Level.SEVERE, null, ex);
}
}

public void shiftSeriesData(float newValue)
{
for(int i=0; i<NUM_OF_POINT-1; i++){
XYChart.Data<String, Number> ShiftDataUp =
(XYChart.Data<String, Number>)series.getData().get(i+1);
Number shiftValue = ShiftDataUp.getYValue();
XYChart.Data<String, Number> ShiftDataDn =
(XYChart.Data<String, Number>)series.getData().get(i);
ShiftDataDn.setYValue(shiftValue);
}
XYChart.Data<String, Number> lastData =
(XYChart.Data<String, Number>)series.getData().get(NUM_OF_POINT-1);
lastData.setYValue(newValue);
}

public boolean connectArduino(String port){

System.out.println("connectArduino");

boolean success = false;
SerialPort serialPort = new SerialPort(port);
try {
serialPort.openPort();
serialPort.setParams(
SerialPort.BAUDRATE_9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setEventsMask(MASK_RXCHAR);
serialPort.addEventListener((SerialPortEvent serialPortEvent) -> {
if(serialPortEvent.isRXCHAR()){
try {

byte[] b = serialPort.readBytes();
int value = b[0] & 0xff; //convert to int
String st = String.valueOf(value);

//Update label in ui thread
Platform.runLater(() -> {
labelValue.setText(st);
shiftSeriesData((float)value * 5/255); //in 5V scale
});

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

}
});

arduinoPort = serialPort;
success = true;
} catch (SerialPortException ex) {
Logger.getLogger(JavaFX_jssc_Uno.class.getName())
.log(Level.SEVERE, null, ex);
System.out.println("SerialPortException: " + ex.toString());
}

return success;
}

public void disconnectArduino(){

System.out.println("disconnectArduino()");
if(arduinoPort != null){
try {
arduinoPort.removeEventListener();

if(arduinoPort.isOpened()){
arduinoPort.closePort();
}

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

@Override
public void stop() throws Exception {
disconnectArduino();
super.stop();
}

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

}


Connect a potentiometer in Arduino Uno side to set analog input A0.
Next:
- Run it remotely on Raspberry Pi 2.

Get