This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,6 +2,9 @@
|
|||||||
# Compiled class file
|
# Compiled class file
|
||||||
*.class
|
*.class
|
||||||
|
|
||||||
|
# ---> CSV
|
||||||
|
*.csv
|
||||||
|
|
||||||
# Log file
|
# Log file
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
@@ -64,3 +67,4 @@ target/maven-archiver/pom.properties
|
|||||||
target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
|
target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
|
||||||
target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
|
target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
|
||||||
>>>>>>> f462d53 (yessssssssss!)
|
>>>>>>> f462d53 (yessssssssss!)
|
||||||
|
logs/dyno_2025-06-10_19-41-50.csv
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class AnalogMeter extends JPanel {
|
|||||||
this.maxValue = maxValue;
|
this.maxValue = maxValue;
|
||||||
this.currentValue = 0.0;
|
this.currentValue = 0.0;
|
||||||
this.needleColor = needleColor;
|
this.needleColor = needleColor;
|
||||||
setPreferredSize(new Dimension(200, 200));
|
setPreferredSize(new Dimension(250, 250));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(double value) {
|
public void setValue(double value) {
|
||||||
@@ -41,8 +41,9 @@ public class AnalogMeter extends JPanel {
|
|||||||
int centerY = getHeight() / 2;
|
int centerY = getHeight() / 2;
|
||||||
int radius = Math.min(centerX, centerY) - 10;
|
int radius = Math.min(centerX, centerY) - 10;
|
||||||
|
|
||||||
// Draw meter background
|
// Draw meter background with gradient
|
||||||
g2d.setColor(Color.LIGHT_GRAY);
|
GradientPaint gradient = new GradientPaint(0, 0, Color.LIGHT_GRAY, 0, getHeight(), Color.WHITE);
|
||||||
|
g2d.setPaint(gradient);
|
||||||
g2d.fillOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
|
g2d.fillOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
|
||||||
|
|
||||||
// Draw scale and ticks
|
// Draw scale and ticks
|
||||||
@@ -73,7 +74,7 @@ public class AnalogMeter extends JPanel {
|
|||||||
int needleX = (int) (centerX + needleLength * Math.cos(angle));
|
int needleX = (int) (centerX + needleLength * Math.cos(angle));
|
||||||
int needleY = (int) (centerY - needleLength * Math.sin(angle));
|
int needleY = (int) (centerY - needleLength * Math.sin(angle));
|
||||||
|
|
||||||
g2d.setStroke(new BasicStroke(3));
|
g2d.setStroke(new BasicStroke(4)); // Thicker needle
|
||||||
g2d.drawLine(centerX, centerY, needleX, needleY);
|
g2d.drawLine(centerX, centerY, needleX, needleY);
|
||||||
g2d.fillOval(centerX - 5, centerY - 5, 10, 10);
|
g2d.fillOval(centerX - 5, centerY - 5, 10, 10);
|
||||||
|
|
||||||
@@ -82,6 +83,6 @@ public class AnalogMeter extends JPanel {
|
|||||||
g2d.setFont(new Font("Arial", Font.BOLD, 16));
|
g2d.setFont(new Font("Arial", Font.BOLD, 16));
|
||||||
FontMetrics fm = g2d.getFontMetrics();
|
FontMetrics fm = g2d.getFontMetrics();
|
||||||
int labelWidth = fm.stringWidth(label);
|
int labelWidth = fm.stringWidth(label);
|
||||||
g2d.drawString(label, centerX - labelWidth / 2, centerY + radius + 20);
|
g2d.drawString(label, centerX - labelWidth / 2, centerY + radius + 30); // Adjusted position
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
53
src/main/java/com/puchdyno/CSVLogger.java
Normal file
53
src/main/java/com/puchdyno/CSVLogger.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package com.puchdyno;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class that appends each sample coming from the dyno run to a csv file.
|
||||||
|
* The file will be created the first time it is needed and automatically closed
|
||||||
|
* when the logger is closed.
|
||||||
|
*/
|
||||||
|
public class CSVLogger implements Closeable {
|
||||||
|
private static final DateTimeFormatter FILE_TS = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
|
||||||
|
private static final DateTimeFormatter ROW_TS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
|
|
||||||
|
private final BufferedWriter writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new logger that writes to the given directory using the current timestamp as file name.
|
||||||
|
*/
|
||||||
|
public CSVLogger(File directory) throws IOException {
|
||||||
|
if (!directory.exists() && !directory.mkdirs()) {
|
||||||
|
throw new IOException("Unable to create log directory " + directory);
|
||||||
|
}
|
||||||
|
File file = new File(directory, "dyno_" + LocalDateTime.now().format(FILE_TS) + ".csv");
|
||||||
|
boolean created = file.createNewFile();
|
||||||
|
writer = new BufferedWriter(new FileWriter(file, true));
|
||||||
|
if (created) {
|
||||||
|
writer.write("timestamp,rpm,ps,nm");
|
||||||
|
writer.newLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void log(double rpm, double ps, double nm) {
|
||||||
|
try {
|
||||||
|
writer.write(String.format("%s,%.2f,%.2f,%.2f", LocalDateTime.now().format(ROW_TS), rpm, ps, nm));
|
||||||
|
writer.newLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// we can't do much more than print the stacktrace at this point
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,16 @@ public class DynoGUI extends JFrame {
|
|||||||
private final AnalogMeter hpMeter;
|
private final AnalogMeter hpMeter;
|
||||||
private final XYSeries powerSeries;
|
private final XYSeries powerSeries;
|
||||||
private final XYSeries torqueSeries;
|
private final XYSeries torqueSeries;
|
||||||
|
private final XYSeries efficiencySeries;
|
||||||
private final ChartPanel chartPanel;
|
private final ChartPanel chartPanel;
|
||||||
|
private final JLabel maxLeistungLabel;
|
||||||
|
private final JLabel maxDrehmomentLabel;
|
||||||
|
private double maxLeistung = 0.0;
|
||||||
|
private double maxDrehmoment = 0.0;
|
||||||
|
private double maxLeistungRpm = 0.0;
|
||||||
|
private double maxLeistungNmAtHp = 0.0;
|
||||||
|
private double maxDrehmomentRpm = 0.0;
|
||||||
|
private double maxDrehmomentPsAtNm = 0.0;
|
||||||
|
|
||||||
public DynoGUI() {
|
public DynoGUI() {
|
||||||
setTitle("Puch Maxi Dyno");
|
setTitle("Puch Maxi Dyno");
|
||||||
@@ -27,12 +36,24 @@ public class DynoGUI extends JFrame {
|
|||||||
setLayout(new BorderLayout(10, 10));
|
setLayout(new BorderLayout(10, 10));
|
||||||
|
|
||||||
// Top panel: analog meters
|
// Top panel: analog meters
|
||||||
JPanel meterPanel = new JPanel(new GridLayout(1, 2, 10, 10));
|
JPanel meterPanel = new JPanel(new GridLayout(1, 2, 20, 20));
|
||||||
meterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
meterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
rpmMeter = new AnalogMeter("RPM", 12000, Color.BLUE);
|
rpmMeter = new AnalogMeter("RPM", 12000, Color.BLUE);
|
||||||
hpMeter = new AnalogMeter("Horse Power", 15, Color.RED);
|
hpMeter = new AnalogMeter("Horse Power", 15, Color.RED);
|
||||||
meterPanel.add(rpmMeter);
|
|
||||||
meterPanel.add(hpMeter);
|
rpmMeter.setToolTipText("Motordrehzahl in U/min");
|
||||||
|
hpMeter.setToolTipText("Motorleistung in PS");
|
||||||
|
|
||||||
|
JPanel rpmWrapper = new JPanel(new BorderLayout());
|
||||||
|
rpmWrapper.setBorder(BorderFactory.createTitledBorder("Drehzahl [RPM]"));
|
||||||
|
rpmWrapper.add(rpmMeter, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
JPanel hpWrapper = new JPanel(new BorderLayout());
|
||||||
|
hpWrapper.setBorder(BorderFactory.createTitledBorder("Leistung [PS]"));
|
||||||
|
hpWrapper.add(hpMeter, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
meterPanel.add(rpmWrapper);
|
||||||
|
meterPanel.add(hpWrapper);
|
||||||
add(meterPanel, BorderLayout.NORTH);
|
add(meterPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
// Center panel: chart and labels
|
// Center panel: chart and labels
|
||||||
@@ -46,24 +67,35 @@ public class DynoGUI extends JFrame {
|
|||||||
|
|
||||||
leistungLabel = new JLabel("Leistung: 0.00 PS");
|
leistungLabel = new JLabel("Leistung: 0.00 PS");
|
||||||
drehmomentLabel = new JLabel("Drehmoment: 0.00 Nm");
|
drehmomentLabel = new JLabel("Drehmoment: 0.00 Nm");
|
||||||
|
maxLeistungLabel = new JLabel("Max Leistung: 0.00 PS");
|
||||||
|
maxDrehmomentLabel = new JLabel("Max Drehmoment: 0.00 Nm");
|
||||||
|
|
||||||
leistungLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
|
leistungLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
|
||||||
drehmomentLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
|
drehmomentLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
|
||||||
|
maxLeistungLabel.setFont(new Font("SansSerif", Font.PLAIN, 14));
|
||||||
|
maxDrehmomentLabel.setFont(new Font("SansSerif", Font.PLAIN, 14));
|
||||||
|
|
||||||
leistungLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
leistungLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
drehmomentLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
drehmomentLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
maxLeistungLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
maxDrehmomentLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
|
||||||
labelPanel.add(leistungLabel);
|
labelPanel.add(leistungLabel);
|
||||||
labelPanel.add(Box.createVerticalStrut(10));
|
|
||||||
labelPanel.add(drehmomentLabel);
|
labelPanel.add(drehmomentLabel);
|
||||||
|
labelPanel.add(Box.createVerticalStrut(5));
|
||||||
|
labelPanel.add(maxLeistungLabel);
|
||||||
|
labelPanel.add(Box.createVerticalStrut(5));
|
||||||
|
labelPanel.add(maxDrehmomentLabel);
|
||||||
centerPanel.add(labelPanel, BorderLayout.NORTH);
|
centerPanel.add(labelPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
// Data series
|
// Data series
|
||||||
powerSeries = new XYSeries("Power (PS)");
|
powerSeries = new XYSeries("Power (PS)");
|
||||||
torqueSeries = new XYSeries("Torque (Nm)");
|
torqueSeries = new XYSeries("Torque (Nm)");
|
||||||
|
efficiencySeries = new XYSeries("Efficiency");
|
||||||
|
|
||||||
XYSeriesCollection powerDataset = new XYSeriesCollection(powerSeries);
|
XYSeriesCollection powerDataset = new XYSeriesCollection(powerSeries);
|
||||||
XYSeriesCollection torqueDataset = new XYSeriesCollection(torqueSeries);
|
XYSeriesCollection torqueDataset = new XYSeriesCollection(torqueSeries);
|
||||||
|
XYSeriesCollection efficiencyDataset = new XYSeriesCollection(efficiencySeries);
|
||||||
|
|
||||||
// Date for chart title
|
// Date for chart title
|
||||||
String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
|
String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
|
||||||
@@ -107,6 +139,15 @@ public class DynoGUI extends JFrame {
|
|||||||
plot.setDataset(1, torqueDataset);
|
plot.setDataset(1, torqueDataset);
|
||||||
plot.mapDatasetToRangeAxis(1, 1);
|
plot.mapDatasetToRangeAxis(1, 1);
|
||||||
|
|
||||||
|
// Efficiency axis (additional, right side 2)
|
||||||
|
NumberAxis effAxis = new NumberAxis("Effizienz [arb.u.]");
|
||||||
|
effAxis.setAutoRangeIncludesZero(false);
|
||||||
|
effAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 12));
|
||||||
|
effAxis.setLabelFont(new Font("SansSerif", Font.BOLD, 14));
|
||||||
|
plot.setRangeAxis(2, effAxis);
|
||||||
|
plot.setDataset(2, efficiencyDataset);
|
||||||
|
plot.mapDatasetToRangeAxis(2, 2);
|
||||||
|
|
||||||
// X axis
|
// X axis
|
||||||
NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
|
NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
|
||||||
xAxis.setRange(0.0, 12000.0);
|
xAxis.setRange(0.0, 12000.0);
|
||||||
@@ -123,6 +164,12 @@ public class DynoGUI extends JFrame {
|
|||||||
torqueRenderer.setSeriesPaint(0, new Color(38, 139, 210)); // Blue
|
torqueRenderer.setSeriesPaint(0, new Color(38, 139, 210)); // Blue
|
||||||
plot.setRenderer(1, torqueRenderer);
|
plot.setRenderer(1, torqueRenderer);
|
||||||
|
|
||||||
|
XYLineAndShapeRenderer effRenderer = new XYLineAndShapeRenderer(false, true);
|
||||||
|
effRenderer.setSeriesPaint(0, new Color(133, 153, 0)); // green
|
||||||
|
effRenderer.setSeriesShapesVisible(0, true);
|
||||||
|
effRenderer.setSeriesShape(0, new java.awt.geom.Ellipse2D.Double(-4, -4, 8, 8));
|
||||||
|
plot.setRenderer(2, effRenderer);
|
||||||
|
|
||||||
// Chart panel setup
|
// Chart panel setup
|
||||||
chartPanel = new ChartPanel(chart);
|
chartPanel = new ChartPanel(chart);
|
||||||
chartPanel.setPreferredSize(new Dimension(800, 400));
|
chartPanel.setPreferredSize(new Dimension(800, 400));
|
||||||
@@ -149,6 +196,36 @@ public class DynoGUI extends JFrame {
|
|||||||
leistungLabel.setText(String.format("Leistung: %.2f PS", leistung));
|
leistungLabel.setText(String.format("Leistung: %.2f PS", leistung));
|
||||||
drehmomentLabel.setText(String.format("Drehmoment: %.2f Nm", drehmoment));
|
drehmomentLabel.setText(String.format("Drehmoment: %.2f Nm", drehmoment));
|
||||||
|
|
||||||
|
// update max hold values
|
||||||
|
boolean effUpdated = false;
|
||||||
|
if (leistung > maxLeistung) {
|
||||||
|
maxLeistung = leistung;
|
||||||
|
maxLeistungLabel.setText(String.format("Max Leistung: %.2f PS", maxLeistung));
|
||||||
|
maxLeistungRpm = rpm;
|
||||||
|
maxLeistungNmAtHp = drehmoment;
|
||||||
|
effUpdated = true;
|
||||||
|
}
|
||||||
|
if (drehmoment > maxDrehmoment) {
|
||||||
|
maxDrehmoment = drehmoment;
|
||||||
|
maxDrehmomentLabel.setText(String.format("Max Drehmoment: %.2f Nm", maxDrehmoment));
|
||||||
|
maxDrehmomentRpm = rpm;
|
||||||
|
maxDrehmomentPsAtNm = leistung;
|
||||||
|
effUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effUpdated) {
|
||||||
|
efficiencySeries.clear();
|
||||||
|
if (maxLeistungNmAtHp > 0) {
|
||||||
|
efficiencySeries.add(maxLeistungRpm, maxLeistung / maxLeistungNmAtHp);
|
||||||
|
}
|
||||||
|
if (maxDrehmoment > 0) {
|
||||||
|
double effNm = maxDrehmomentPsAtNm == 0 ? 0.0 : maxDrehmomentPsAtNm / maxDrehmoment;
|
||||||
|
// avoid duplicate point if same rpm
|
||||||
|
if (maxDrehmomentRpm != maxLeistungRpm)
|
||||||
|
efficiencySeries.add(maxDrehmomentRpm, effNm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
powerSeries.add(rpm, leistung);
|
powerSeries.add(rpm, leistung);
|
||||||
torqueSeries.add(rpm, drehmoment);
|
torqueSeries.add(rpm, drehmoment);
|
||||||
}
|
}
|
||||||
@@ -156,6 +233,14 @@ public class DynoGUI extends JFrame {
|
|||||||
public void resetChart() {
|
public void resetChart() {
|
||||||
powerSeries.clear();
|
powerSeries.clear();
|
||||||
torqueSeries.clear();
|
torqueSeries.clear();
|
||||||
|
efficiencySeries.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetMaxHold() {
|
||||||
|
maxLeistung = 0.0;
|
||||||
|
maxDrehmoment = 0.0;
|
||||||
|
maxLeistungLabel.setText("Max Leistung: 0.00 PS");
|
||||||
|
maxDrehmomentLabel.setText("Max Drehmoment: 0.00 Nm");
|
||||||
}
|
}
|
||||||
|
|
||||||
public JFreeChart getChart() {
|
public JFreeChart getChart() {
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ public class Main {
|
|||||||
private static ScheduledExecutorService serialExecutor;
|
private static ScheduledExecutorService serialExecutor;
|
||||||
private static BufferedReader serialReader;
|
private static BufferedReader serialReader;
|
||||||
|
|
||||||
|
private static CSVLogger csvLogger;
|
||||||
|
private static boolean measurementActive = false;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
dynoGUI = new DynoGUI();
|
dynoGUI = new DynoGUI();
|
||||||
@@ -67,10 +70,22 @@ public class Main {
|
|||||||
resetChartButton.addActionListener(e -> dynoGUI.resetChart());
|
resetChartButton.addActionListener(e -> dynoGUI.resetChart());
|
||||||
controlPanel.add(resetChartButton);
|
controlPanel.add(resetChartButton);
|
||||||
|
|
||||||
|
JButton resetMaxButton = new JButton("Reset Max-Hold");
|
||||||
|
resetMaxButton.addActionListener(e -> dynoGUI.resetMaxHold());
|
||||||
|
controlPanel.add(resetMaxButton);
|
||||||
|
|
||||||
JButton reconnectButton = new JButton("Reconnect Serial");
|
JButton reconnectButton = new JButton("Reconnect Serial");
|
||||||
reconnectButton.addActionListener(e -> reconnectSerial());
|
reconnectButton.addActionListener(e -> reconnectSerial());
|
||||||
controlPanel.add(reconnectButton);
|
controlPanel.add(reconnectButton);
|
||||||
|
|
||||||
|
JButton startMeasButton = new JButton("Start Messung");
|
||||||
|
startMeasButton.addActionListener(e -> startMeasurement());
|
||||||
|
controlPanel.add(startMeasButton);
|
||||||
|
|
||||||
|
JButton stopMeasButton = new JButton("Stop Messung");
|
||||||
|
stopMeasButton.addActionListener(e -> stopMeasurement());
|
||||||
|
controlPanel.add(stopMeasButton);
|
||||||
|
|
||||||
dynoGUI.add(controlPanel, BorderLayout.SOUTH);
|
dynoGUI.add(controlPanel, BorderLayout.SOUTH);
|
||||||
dynoGUI.revalidate();
|
dynoGUI.revalidate();
|
||||||
dynoGUI.repaint();
|
dynoGUI.repaint();
|
||||||
@@ -144,6 +159,10 @@ public class Main {
|
|||||||
testDataExecutor = null;
|
testDataExecutor = null;
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
dynoGUI.updateWerte(0, 0, 0); // Reset gauges
|
dynoGUI.updateWerte(0, 0, 0); // Reset gauges
|
||||||
|
if (csvLogger != null) {
|
||||||
|
try { csvLogger.close(); } catch (Exception ex) { ex.printStackTrace(); }
|
||||||
|
csvLogger = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,6 +281,11 @@ public class Main {
|
|||||||
currentSerialPort = null;
|
currentSerialPort = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (csvLogger != null) {
|
||||||
|
try { csvLogger.close(); } catch (Exception ex) { ex.printStackTrace(); }
|
||||||
|
csvLogger = null;
|
||||||
|
}
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
dynoGUI.updateWerte(0, 0, 0); // Reset gauges
|
dynoGUI.updateWerte(0, 0, 0); // Reset gauges
|
||||||
});
|
});
|
||||||
@@ -292,6 +316,19 @@ public class Main {
|
|||||||
|
|
||||||
lastTimestamp = currentTimestamp;
|
lastTimestamp = currentTimestamp;
|
||||||
lastOmega = currentOmega;
|
lastOmega = currentOmega;
|
||||||
|
|
||||||
|
if (measurementActive) {
|
||||||
|
if (csvLogger == null) {
|
||||||
|
try {
|
||||||
|
csvLogger = new CSVLogger(new java.io.File("logs"));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.err.println("Could not create CSV logger: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (csvLogger != null) {
|
||||||
|
csvLogger.log(rpm, leistung, drehmoment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processRPMData(double rpm, double forcedDeltaTime) {
|
private static void processRPMData(double rpm, double forcedDeltaTime) {
|
||||||
@@ -306,6 +343,19 @@ public class Main {
|
|||||||
|
|
||||||
lastOmega = currentOmega;
|
lastOmega = currentOmega;
|
||||||
lastTimestamp = System.currentTimeMillis();
|
lastTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (measurementActive) {
|
||||||
|
if (csvLogger == null) {
|
||||||
|
try {
|
||||||
|
csvLogger = new CSVLogger(new java.io.File("logs"));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.err.println("Could not create CSV logger: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (csvLogger != null) {
|
||||||
|
csvLogger.log(rpm, leistung, drehmoment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double rpmToOmega(double rpm) {
|
private static double rpmToOmega(double rpm) {
|
||||||
@@ -340,9 +390,13 @@ public class Main {
|
|||||||
JButton savePdfButton = new JButton("Save as PDF");
|
JButton savePdfButton = new JButton("Save as PDF");
|
||||||
savePdfButton.addActionListener(e -> saveChartAsPdf(printChartPanel));
|
savePdfButton.addActionListener(e -> saveChartAsPdf(printChartPanel));
|
||||||
|
|
||||||
|
JButton savePngButton = new JButton("Save as PNG");
|
||||||
|
savePngButton.addActionListener(e -> saveChartAsPng(printChartPanel));
|
||||||
|
|
||||||
JPanel controlPanel = new JPanel();
|
JPanel controlPanel = new JPanel();
|
||||||
controlPanel.add(printButton);
|
controlPanel.add(printButton);
|
||||||
controlPanel.add(savePdfButton);
|
controlPanel.add(savePdfButton);
|
||||||
|
controlPanel.add(savePngButton);
|
||||||
chartFrame.add(controlPanel, BorderLayout.SOUTH);
|
chartFrame.add(controlPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
chartFrame.setLocationRelativeTo(dynoGUI);
|
chartFrame.setLocationRelativeTo(dynoGUI);
|
||||||
@@ -391,4 +445,60 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void saveChartAsPng(ChartPanel chartPanel) {
|
||||||
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
|
fileChooser.setDialogTitle("Save Chart as PNG");
|
||||||
|
fileChooser.setFileFilter(new FileNameExtensionFilter("PNG Image (*.png)", "png"));
|
||||||
|
|
||||||
|
int userSelection = fileChooser.showSaveDialog(null);
|
||||||
|
|
||||||
|
if (userSelection == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File fileToSave = fileChooser.getSelectedFile();
|
||||||
|
String filePath = fileToSave.getAbsolutePath();
|
||||||
|
if (!filePath.toLowerCase().endsWith(".png")) {
|
||||||
|
filePath += ".png";
|
||||||
|
}
|
||||||
|
File finalFile = new File(filePath);
|
||||||
|
try {
|
||||||
|
org.jfree.chart.ChartUtils.saveChartAsPNG(finalFile, chartPanel.getChart(), chartPanel.getWidth(), chartPanel.getHeight());
|
||||||
|
JOptionPane.showMessageDialog(null, "Chart saved as PNG successfully!\n" + finalFile.getAbsolutePath(), "Save Successful", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Error saving chart as PNG: " + ex.getMessage(), "Save Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startMeasurement() {
|
||||||
|
if (measurementActive) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Messung läuft bereits.", "Info", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
measurementActive = true;
|
||||||
|
dynoGUI.resetChart();
|
||||||
|
dynoGUI.resetMaxHold();
|
||||||
|
if (csvLogger != null) {
|
||||||
|
try { csvLogger.close(); } catch (Exception ex) { ex.printStackTrace(); }
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
csvLogger = new CSVLogger(new java.io.File("logs"));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
csvLogger = null;
|
||||||
|
System.err.println("CSV Logger konnte nicht erstellt werden: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void stopMeasurement() {
|
||||||
|
if (!measurementActive) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Keine laufende Messung.", "Info", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
measurementActive = false;
|
||||||
|
if (csvLogger != null) {
|
||||||
|
try { csvLogger.close(); } catch (Exception ex) { ex.printStackTrace(); }
|
||||||
|
csvLogger = null;
|
||||||
|
}
|
||||||
|
JOptionPane.showMessageDialog(null, "Messung gestoppt.", "Info", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user