0

JAVAFX & Arduino Analog Değerleri Seriport’tan okuyup Grafiğe Aktarma Part -2

Merhaba Arkadaşlar birinci bölümde işimizin görselini ve fonksiyonunu hazırlamıştık seri port’a bağlanıp veri almamıştık. Birinci bölümde verileri randomize olarak grafiğe aktarıyorduk şimdi ise seri port’tan gelen bilgileri ekrana yazdıracağız  o yüzden bu bölümde kod kısmında biraz değişikliklere gideceğiz ve son halini vermiş olacağız . Hatta birinci bölümü ayrı bir proje ikinci bölümü ayrı bir proje olarak bile değerlendirebelirsiniz ancak ikinci bölüm birinci bölümün devamı niteliğinde.

Şimdi Arduino kartımıza yükleyeceğimiz programa bakalım .

const int analogInPin = A0;  //Okunacak Analog Pin portu

int sensorValue = 0;        // potansiyometreden yada ldr den yada vb... okunan değeri alacağız
int outputValue = 0;        // çıkış değerini tutacağız

void setup() {
  // seri port ile bağlantı hızımızı ayaralayım.
  Serial.begin(9600);
}

void loop() {
  // analaog değeri okuyalım
  sensorValue = analogRead(analogInPin);
  // analog girişi map edelim
  outputValue = map(sensorValue, 0, 1023, 0, 255); // Analog 0 - 1023 arası olduğundan bunu 0 255 arasına dönüştürelim

  Serial.println(outputValue);

  // 1 saniye bekleyelim nefes alsın 🙂
  delay(1000);
}

Evet bu bölümde SerialPort bağlantısı için ayrı bir class açacağız. Seri port işlemleri için jssc.jar kütüphanesini kullanacağız. Google’ye yazarsanız o size kütüphaneyi nerden nasıl bulacağınızı söyler :). Buradaki sınıfımı ben Singleton deseni ile tasarladım. Hemde singleton yazısına örnek olsun diye. 

import javafx.application.Platform;
import jssc.*;

import java.lang.reflect.Array;

public class SerialPortIslemler implements SerialPortEventListener {


    SerialPort serialPort=null;
    public static double value=0;


    public static SerialPortIslemler instance=new SerialPortIslemler();

    private SerialPortIslemler(){}


    public static SerialPortIslemler getInstance(){

        return instance;
    }

    public void connect(String portName) throws SerialPortException {

        disConnect();
        serialPort=new SerialPort(portName);
        serialPort.openPort();
        serialPort.setParams(SerialPort.BAUDRATE_9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
        int mask = SerialPort.MASK_RXCHAR ; 
        serialPort.setEventsMask(mask);
        serialPort.addEventListener(this::serialEvent);


    }

    public void disConnect()  {

        if(serialPort!=null) {
            if (serialPort.isOpened()) {

                try {
                    serialPort.removeEventListener();
                    serialPort.closePort();
                    System.out.println("Port Kapatıldı");
                } catch (SerialPortException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void serialEvent(SerialPortEvent event) {

        if(event.isRXCHAR()) {

            try {

                String data = serialPort.readString();
                if (event.getEventValue() > 0) {
                    if (!data.equals(null)) {


                        if (!data.equals("")) {
                          
                            Platform.runLater(new Runnable() {
                            // serialport farklı bir thread 'de port'u dinlediği için bilgelirin ana thread'e aktarımı için böyle kullandık
                                @Override
                                public void run() {
                                    Screen.graphValue = (Double.parseDouble(data.trim())) * 5 / 255;
                                }
                            });

                        }
                    }
                }

            } catch (SerialPortException ex) {
                System.out.println(ex);
            }

        }

    }


}

Screen.java  tekrardan düzenlenen haliyle

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.geometry.Insets;
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.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import  jssc.*;
import java.text.DecimalFormat;
import java.util.Random;


public class Screen extends Application {


    SerialPort serialPort=null;
    ComboBox<String> portsCombo;
    ObservableList<String> portList;
    boolean portSelected=false;

    static Double graphValue=0.0;

    void  getAndSetPorts(){
        // Bilgisayarımızdaki portları listeye aktaralım
        portList= FXCollections.observableArrayList(SerialPortList.getPortNames());
        portsCombo=new ComboBox<>(portList);

    }


    // X ve Y eksenlerini oluşturalım
    NumberAxis xAxis=new NumberAxis();
    NumberAxis yAxis=new NumberAxis();


     XYChart.Series<Number,Number> series;

     private static final int  TICK_COUNT = 50;  // y eksenindeki işaretlerin sayısı


    @Override
    public void start(Stage primaryStage) throws Exception {

        BorderPane mainRoot=new BorderPane();
        getAndSetPorts();
        VBox leftPane=new VBox();
        leftPane.setPadding(new Insets(20));
        leftPane.setSpacing(20);
        leftPane.setStyle("-fx-background-color: #1F1F1F");
        leftPane.setPrefWidth(200);

        Text text=new Text("Bağlı Portu Seçiniz");
        text.setFill(Color.WHITE);

        leftPane.getChildren().addAll(text,portsCombo);

        portsCombo.valueProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
              // Seçilen porta bağlantı yapalım
                try {
                    SerialPortIslemler.getInstance().connect(newValue);
                    portSelected=true;
                } catch (SerialPortException e) {
                    e.printStackTrace();
                }

            }
        });


        VBox root=new VBox();
        root.setSpacing(30);
        root.setAlignment(Pos.CENTER);

        // X ve Y ekseni için bir etiket belirleyelim
        yAxis.setLabel("Voltaj Değeri");
        xAxis.setLabel("Süre");
        yAxis.setTickLabelFill(Color.WHITE);
        xAxis.setTickLabelFill(Color.WHITE);


        // Şimdi LineChart 'ımızı oluşturalım
        LineChart<Number,Number> lineChart=new LineChart<>(xAxis,yAxis);
        lineChart.setAnimated(false);
        lineChart.setTitle(" Javafx & Arduino Analog Port Okuma");
        lineChart.setPadding(new Insets(30));
        lineChart.setCreateSymbols(false); // chart üzerindeki noktaları kaldırır

        // İçinde gösterilen herbir grafige ait bilgileri Series nesnesi tutuyor
        series=new XYChart.Series<>();
        series.setName("A0 Analog Port Değerleri");

        // İlk program açıldığında tümünü sıfırlamak için bütün x değerlerine sıfır atayalım
        for(int i=0; i<TICK_COUNT;i++) {

            series.getData().add(new XYChart.Data<>(i,0));
        }


        // Seriyi lineChart 'ın içine atalım
        lineChart.getData().add(series);

        Button button=new Button("Değerleri Okumaya Başla");
        button.setPadding(new Insets(10));

        button.setOnAction(event -> {  
      // Butona basınca port'u dinlemeye başlayalım bunu yeni bir thread'de yapalım ki ana Thread donup kalmasın
            if(portSelected) {
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {

                        while (true) {
                            // ana thread'deki componentlere ulaşıp veri yazmak için thread'den ana thread verileri yollayalım
                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                    grafigiKaydir(graphValue);
                                }
                            });

                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                });

                thread.setDaemon(true);
                thread.start();

            }


        });

        Region spacer=new Region();
        root.setVgrow(spacer, Priority.ALWAYS);
        root.getChildren().addAll(lineChart,button,spacer);
        mainRoot.setCenter(root);
        mainRoot.setLeft(leftPane);





                // Sahneyi ve Stage yi ayarlayalım
        Scene scene = new Scene(mainRoot, 800, 600);
        scene.getStylesheets().add("styles/style.css");
        primaryStage.setTitle("Javafx & Arduino Grafik Uygulaması");
        primaryStage.setScene(scene);
        primaryStage.show();


    }

    @Override
    public void stop() throws Exception {
        super.stop();
        SerialPortIslemler.getInstance().disConnect();

    }

    public  void grafigiKaydir( double newValue)   {


        for(int i=0; i<TICK_COUNT-1;i++){

           // Grafigi kaydırmak için en sonuncu haric diğerleri için
           // hep bir sonrakini alıp bir öncekine atayacağız

            XYChart.Data sonraki= series.getData().get(i+1);
            XYChart.Data onceki=series.getData().get(i);
            onceki.setYValue(sonraki.getYValue());

        }
            // son değeri alalım ve ona değer ataması yapalım
            XYChart.Data sonuncu=series.getData().get(TICK_COUNT-1);

            sonuncu.setYValue(newValue);

            // Double olan değer 2.0000000 gibi uzun olacağından böyle formatlayalım
            DecimalFormat decimalFormat=new DecimalFormat("#.##");

            //x Axis in label'ine yazalım
            xAxis.setLabel("Okunan Değer = "+ (decimalFormat.format(newValue)+" V"));

    }

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









}

stil sayfası style.css

.progress-bar > .track {
    -fx-text-box-border: transparent;
    -fx-control-inner-background:#fff;

}

.chart-series-line {
    -fx-stroke-width: 1px;
    -fx-effect: null;

}

.chart-vertical-grid-lines {
    -fx-stroke: #fff;
    -fx-opacity: 0.2;
}
.chart-horizontal-grid-lines {
    -fx-stroke: #fff;
    -fx-opacity: 0.2;
}


.default-color0.chart-series-line { -fx-stroke: #fff; }
.root{
    -fx-background-color: #000;
}

.chart{

    -fx-background-color: #000;
}
.chart-content{
    -fx-background-color: #000;

}

.axis-label{
    -fx-text-fill: #fff;

}

.chart-title{

   -fx-text-fill: #EEEEEE;
}

.chart-legend{

    -fx-background-color: transparent;

}

.chart-legend-item{

    -fx-text-fill: #fff;
}

.chart-plot-background{
    -fx-background-color: linear-gradient(to bottom, #2979FF, #304FFE);

}

 

Konu ile ilgili kafasına soru takılan olursa yorum yazabilir

admin

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir