我有四个压力传感器通过串行端口连接(使用jSerialComm进行通信)连接到Arduino Uno板,然后连接到PC。我希望能够以半实时方式绘制四个读数的图形(以每秒获取100次数据,但不必以如此快的速度绘制数据),以便随后可以进行简短的计算。
Arduino代码:
int vals[4];
int a0,a1,a2,a3;
void setup() {
Serial.flush();
Serial.begin(9600);
delay(1000);
}
void loop() {
a0 = analogRead(0);
a1 = analogRead(1);
a2 = analogRead(2);
a3 = analogRead(3);
vals[0] = a0;
vals[1] = a1;
vals[2] = a2;
vals[3] = a3;
Serial.print("<,");
delay(1);
for(int i=0;i<4;i++)
{
Serial.print(vals[i]);
Serial.print(",");
}
delay(1);
Serial.println('>');
}
和Java代码:
import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import com.fazecast.jSerialComm.SerialPort;
public class SerialTest extends ApplicationFrame
{
private TimeSeriesCollection timeSeriesCollection;
private TimeSeries series0; // a0 series data
private TimeSeries series1; // a1 series data
private TimeSeries series2; // a2 series data
private TimeSeries series3; // a3 series data
private BufferedReader input; // input reader
private SerialPort thisPort; // serial port object
public SerialTest(String title) throws IOException
{
super(title);
connectArduino();
timeSeriesCollection = new TimeSeriesCollection();
series0 = new TimeSeries("Sensor0");
series1 = new TimeSeries("Sensor1");
series2 = new TimeSeries("Sensor2");
series3 = new TimeSeries("Sensor3");
timeSeriesCollection.addSeries(series0);
timeSeriesCollection.addSeries(series1);
timeSeriesCollection.addSeries(series2);
timeSeriesCollection.addSeries(series3);
JFreeChart chart = createChart();
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setMouseWheelEnabled(true);
chartPanel.setPreferredSize(new java.awt.Dimension(1000,500));
chartPanel.setInitialDelay(1000);
setContentPane(chartPanel);
getData();
}
public boolean connectArduino()
{
thisPort = SerialPort.getCommPorts()[0]; //set serial port to first port we find
thisPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
thisPort.closePort();
thisPort.openPort();
input = new BufferedReader(new InputStreamReader(thisPort.getInputStream())); //give BufferedReader a stream of chars
return thisPort.isOpen();
}
public void getData() throws IOException
{
if (thisPort.isOpen() == true)
{
try
{
while ((input.readLine())!=null )
{
String inputLine = input.readLine();
String[] inputVals = inputLine.split(",");
while(!inputVals[0].equals("<") || !inputVals[inputVals.length -1].equals(">"))
{
inputLine = input.readLine();
inputVals = inputLine.split(",");
}
if (inputVals[0].equals("<") && inputVals[inputVals.length -1].equals(">"))
{
System.out.println("OK" + inputLine);
for(int i=1; i<inputVals.length-2; i++)
inputVals[i].replaceAll("[^\\d.]", "");
int in_0 = new Integer(inputVals[1]).intValue();
int in_1 = new Integer(inputVals[2]).intValue();
int in_2 = new Integer(inputVals[3]).intValue();
int in_3 = new Integer(inputVals[4]).intValue();
timeSeriesCollection.getSeries(0).add(new Millisecond(),in_0);
timeSeriesCollection.getSeries(1).add(new Millisecond(),in_1);
timeSeriesCollection.getSeries(2).add(new Millisecond(),in_2);
timeSeriesCollection.getSeries(3).add(new Millisecond(),in_3);
getData();
}
else getData();
}
} catch(Exception e) {}
}else System.out.println("port not open");
}
public JFreeChart createChart()
{
JFreeChart chart = ChartFactory.createTimeSeriesChart("Force Plat", "Time", "ADC Reading", timeSeriesCollection, true, true, false);
chart.setBackgroundPaint(Color.white);
XYPlot plot = (XYPlot) chart.getPlot();
DateAxis axis = (DateAxis) plot.getDomainAxis();
axis.setAutoRange(true);
axis.setFixedAutoRange(60000);
return chart;
}
public void close()
{
if(thisPort != null)
thisPort.closePort();
}
public static void main(String[] args) throws IOException
{
SerialTest demo = new SerialTest("demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
Arduino会打印一个开始字符'<'和结束字符'>'来标识每个字符串的开头,每个读数之间用逗号分隔。它偶尔会打印错误的<或>,似乎对程序影响不大。
我认为我遇到的主要问题是在getData()
方法中。它将绘制一个或两个传感器数据点,然后不再显示。我不确定是否需要像现在这样的事件监听器,例如排序,线程或递归。