1

現在、シリアルデータを読み取ることができるJavaファイルがあり、コンソールに出力するだけです。別のファイルには、ランダムデータをリアルタイムグラフに生成するJFreeChartグラフがあります。

これらのファイルは両方とも同じプロジェクトにあります。現在使用しているランダムデータの代わりに、シリアルデータをリアルタイムグラフに追加するにはどうすればよいですか?

以下の最初のコードは、リアルタイムグラフのファイルです。

public class test224 extends ApplicationFrame implements ActionListener {
    String s;
    String tempbuff;
    private TimeSeries series;

    private double lastValue = 10.0;

    private Timer timer = new Timer(1000, this);
    DynamicTimeSeriesCollection dataset;
    float[] newData = new float[1];

    public test224(final String title) {
        super(title);
        this.series = new TimeSeries("Sensor Value", Millisecond.class);

        final TimeSeriesCollection dataset = new TimeSeriesCollection(this.series);
        final JFreeChart chart = createChart(dataset);
        timer.setInitialDelay(1000);
        chart.setBackgroundPaint(Color.LIGHT_GRAY);
        final JPanel content = new JPanel(new BorderLayout());
        final ChartPanel chartPanel = new ChartPanel(chart);
        content.add(chartPanel);
        chartPanel.setPreferredSize(new java.awt.Dimension(800, 500));
        setContentPane(content);
        timer.start();
    }

    private JFreeChart createChart(final XYDataset dataset) {
        final JFreeChart result = ChartFactory.createTimeSeriesChart(
            "Dynamic Line Chart of Arduino Data",
            "Zeit",
            "Wert",
            dataset,
            true,
            true,
            false
        );

        final XYPlot plot = result.getXYPlot();

        plot.setBackgroundPaint(new Color(0xffffe0));
        plot.setDomainGridlinesVisible(true);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.lightGray);

        ValueAxis xaxis = plot.getDomainAxis();
        xaxis.setAutoRange(true);

        xaxis.setFixedAutoRange(60000.0);
        xaxis.setVerticalTickLabels(true);

        ValueAxis yaxis = plot.getRangeAxis();
        yaxis.setRange(0.0, 300.0);

        return result;
    }

    public void actionPerformed(final ActionEvent e) {
        final double factor = 0.9 + 0.2*Math.random();
        this.lastValue = this.lastValue * factor;

        final Millisecond now = new Millisecond();
        this.series.add(new Millisecond(), this.lastValue);
    }

    public static void main(final String[] args) {
        final test224 demo = new test224("Dynamic Line And TimeSeries Chart");
        demo.pack();

        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }

実行されるアクションでは、ランダムデータが生成されます。次に、他のファイルのこのコードで、Arduinoシリアルデータをコンソールに出力します。これをリアルタイムグラフに表示するにはどうすればよいですか?

public synchronized void serialEvent(SerialPortEvent oEvent) {
    if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            inputLine=input.readLine();
            System.out.println(inputLine);

        }
        catch (Exception e) {
        }
    }
}
4

2 に答える 2

1

Runnable適切な forで呼び出しをラップせずにチャートのデータセットを更新するのは気が進まないでしょうinvokeLater()。このTableModelでは、匿名のバックグラウンド スレッドから を更新します。

さらに良いのは、ここSwingWorkerに示すように を使用することです。イベント ディスパッチ スレッドで実行されるメソッドと有用な結果でシリアル ポートを操作できます。doInBackground()publish()process()

于 2013-02-25T23:21:24.553 に答える
1

クラスをマージしserialEventてメソッドにコンテンツを移動するか、シリアル イベントを含むクラスから呼び出すことができるメソッドを提供する必要があります。どちらの場合も、serialEvent での処理を別のスレッドに移動する必要があると思います。actionPerformedpublic addDataPoint(double point)test224

次のようなことを試すことができます:

@Override
public void actionPerformed(final ActionEvent e) {

  //Initialise the serial port here before starting the new thread

  Runnable task = new Runnable() {

    @Override
    public void run() {
        if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                inputLine = input.readLine();
                System.out.println( inputLine );
                final Millisecond now = new Millisecond();
                series.add(new Millisecond(), Double.parseDouble(inputLine));  

            } catch (Exception e) {                             
            }
        }
    }
  };
  Thread serialThread = new  Thread(task);
  serialThread.start();
}

public addDataPoint(double point)関心の分離を維持するため、ソリューションが望ましいです。

public synchronized void serialEvent(SerialPortEvent oEvent) {
    if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            inputLine=input.readLine();
            System.out.println(inputLine);
            dataChart.addPoint(Double.parseDouble(inputLin));

        } catch (Exception e) {                             
        }
    }
}

シリアル ポイントが別のスレッドで監視されていることを確認する必要があります。

于 2013-02-25T09:42:19.340 に答える