From ee0b524967124dc78e963855674659e40c85a6d7 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Tue, 10 Apr 2018 20:49:26 +0200 Subject: [PATCH 1/6] Add clear button to SerialPlotter --- app/src/processing/app/SerialPlotter.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index 363753749..68262f7ba 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -37,6 +37,7 @@ public class SerialPlotter extends AbstractMonitor { private final StringBuffer messageBuffer; private JComboBox serialRates; + private JButton clearButton; private Serial serial; private int serialRate, xCount; @@ -231,6 +232,8 @@ public class SerialPlotter extends AbstractMonitor { messageBuffer = new StringBuffer(); graphs = new ArrayList<>(); + + clearButton.addActionListener(ae -> {graphs.clear();}); } protected void onCreateWindow(Container mainPane) { @@ -248,16 +251,20 @@ public class SerialPlotter extends AbstractMonitor { for (String serialRateString : serialRateStrings) serialRates.addItem(serialRateString + " " + tr("baud")); serialRates.setMaximumSize(serialRates.getMinimumSize()); - + + clearButton = new JButton(tr("Clear output")); + pane.add(Box.createHorizontalGlue()); pane.add(Box.createRigidArea(new Dimension(8, 0))); pane.add(serialRates); + pane.add(clearButton); mainPane.add(pane, BorderLayout.SOUTH); } protected void onEnableWindow(boolean enable) { serialRates.setEnabled(enable); + clearButton.setEnabled(enable); } private void onSerialRateChange(ActionListener listener) { From 518cbc396d63b8483cfddd7d94be82da092d5231 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Tue, 10 Apr 2018 23:30:07 +0200 Subject: [PATCH 2/6] added the possebilety to change the ringbuffer size --- app/src/processing/app/SerialPlotter.java | 48 +++++++++++++++---- .../app/helpers/CircularBuffer.java | 10 +++- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index 363753749..5843ac98d 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -37,18 +37,22 @@ public class SerialPlotter extends AbstractMonitor { private final StringBuffer messageBuffer; private JComboBox serialRates; + private JSpinner graphWidth; private Serial serial; private int serialRate, xCount; private ArrayList graphs; - private final static int BUFFER_CAPACITY = 500; + private final static int BUFFER_CAPACITY_DEFAULT = 500; + private final static int BUFFER_CAPACITY_MAX = 5000; + private final static int BUFFER_CAPACITY_MIN = 10; + private int buffer_capacity = BUFFER_CAPACITY_DEFAULT; private static class Graph { public CircularBuffer buffer; private Color color; - public Graph(int id) { - buffer = new CircularBuffer(BUFFER_CAPACITY); + public Graph(int id, int capacity) { + buffer = new CircularBuffer(capacity); color = Theme.getColorCycleColor("plotting.graphcolor", id); } @@ -146,12 +150,12 @@ public class SerialPlotter extends AbstractMonitor { } // handle data count - int cnt = xCount - BUFFER_CAPACITY; - if (xCount < BUFFER_CAPACITY) cnt = 0; + int cnt = xCount - buffer_capacity; + if (xCount < buffer_capacity) cnt = 0; double zeroTick = ticks.getTick(0); double lastTick = ticks.getTick(ticks.getTickCount() - 1); - double xTickRange = BUFFER_CAPACITY / ticks.getTickCount(); + double xTickRange = buffer_capacity / ticks.getTickCount(); for (int i = 0; i < ticks.getTickCount() + 1; i++) { String s; @@ -167,7 +171,7 @@ public class SerialPlotter extends AbstractMonitor { s = String.valueOf((int)(xTickRange * i)+cnt); fBounds = fm.getStringBounds(s, g); sWidth = (int)fBounds.getWidth()/2; - xValue = (int)((bounds.width - xOffset - xPadding) * ((xTickRange * i) / BUFFER_CAPACITY) + xOffset); + xValue = (int)((bounds.width - xOffset - xPadding) * ((xTickRange * i) / buffer_capacity) + xOffset); } // draw graph x axis, ticks and labels g.setColor(boundsColor); @@ -184,7 +188,7 @@ public class SerialPlotter extends AbstractMonitor { g.drawLine(xOffset, (int) transformY(zeroTick), bounds.width - xPadding, (int)transformY(zeroTick)); g.setTransform(AffineTransform.getTranslateInstance(xOffset, 0)); - float xstep = (float) (bounds.width - xOffset - xPadding) / (float) BUFFER_CAPACITY; + float xstep = (float) (bounds.width - xOffset - xPadding) / (float) buffer_capacity; int legendLength = graphs.size() * 10 + (graphs.size() - 1) * 3; for(int i = 0; i < graphs.size(); ++i) { @@ -231,6 +235,8 @@ public class SerialPlotter extends AbstractMonitor { messageBuffer = new StringBuffer(); graphs = new ArrayList<>(); + + graphWidth.addChangeListener(cl -> {setNewBufferCapacity((int)graphWidth.getValue()); } ); } protected void onCreateWindow(Container mainPane) { @@ -249,21 +255,45 @@ public class SerialPlotter extends AbstractMonitor { serialRates.setMaximumSize(serialRates.getMinimumSize()); + graphWidth = new JSpinner(new SpinnerNumberModel( + BUFFER_CAPACITY_DEFAULT, //initial value + BUFFER_CAPACITY_MIN, //min + BUFFER_CAPACITY_MAX, //max + 1)); //step + graphWidth.setMaximumSize(graphWidth.getMinimumSize()); + JSpinner.NumberEditor editor = new JSpinner.NumberEditor(graphWidth); + editor.getFormat().setGroupingUsed(false); + graphWidth.setEditor(editor); + pane.add(Box.createHorizontalGlue()); pane.add(Box.createRigidArea(new Dimension(8, 0))); pane.add(serialRates); + pane.add(graphWidth); mainPane.add(pane, BorderLayout.SOUTH); } protected void onEnableWindow(boolean enable) { serialRates.setEnabled(enable); + graphWidth.setEnabled(enable); } private void onSerialRateChange(ActionListener listener) { serialRates.addActionListener(listener); } + private void setNewBufferCapacity(int capacity){ + if(buffer_capacity != capacity) { + if(capacity > BUFFER_CAPACITY_MAX) capacity = BUFFER_CAPACITY_MAX; + else if(capacity < BUFFER_CAPACITY_MIN) capacity = BUFFER_CAPACITY_MIN; + buffer_capacity = capacity; + for(int i = 0; i < graphs.size(); i++) { + graphs.get(i).buffer.newCapacity(capacity); + } + xCount=0; + } + } + public void message(final String s) { messageBuffer.append(s); while (true) { @@ -286,7 +316,7 @@ public class SerialPlotter extends AbstractMonitor { try { double value = Double.valueOf(parts[i]); if(validParts >= graphs.size()) { - graphs.add(new Graph(validParts)); + graphs.add(new Graph(validParts, buffer_capacity)); } graphs.get(validParts).buffer.add(value); validParts++; diff --git a/app/src/processing/app/helpers/CircularBuffer.java b/app/src/processing/app/helpers/CircularBuffer.java index 8396c8fd2..b4a2bada8 100644 --- a/app/src/processing/app/helpers/CircularBuffer.java +++ b/app/src/processing/app/helpers/CircularBuffer.java @@ -4,10 +4,10 @@ import java.util.NoSuchElementException; public class CircularBuffer { - private final double[] elements; + private double[] elements; private int start = -1; private int end = -1; - private final int capacity; + private int capacity; public void add(double num) { end = (end + 1) % capacity; @@ -37,6 +37,12 @@ public class CircularBuffer { elements = new double[capacity]; } + public void newCapacity(int capacity) { + elements = new double[capacity]; + this.capacity = capacity; + start = end = 0; + } + public double min() { if (size() == 0) { throw new NoSuchElementException(); From 0ab8440ca4d86c6387f0bf825ca999239b379a5e Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Thu, 12 Apr 2018 22:38:54 +0200 Subject: [PATCH 3/6] Add remote commands to SerialPlotter to cler the plot and set plot width --- app/src/processing/app/SerialPlotter.java | 41 +++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index 7b81c14bf..28427e9e2 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -258,9 +258,8 @@ public class SerialPlotter extends AbstractMonitor { serialRates.setMaximumSize(serialRates.getMinimumSize()); - clearButton = new JButton(tr("Clear output")); + clearButton = new JButton(tr("Clear output")); - graphWidth = new JSpinner(new SpinnerNumberModel( BUFFER_CAPACITY_DEFAULT, //initial value BUFFER_CAPACITY_MIN, //min @@ -321,15 +320,37 @@ public class SerialPlotter extends AbstractMonitor { int validParts = 0; for(int i = 0; i < parts.length; ++i) { - try { - double value = Double.valueOf(parts[i]); - if(validParts >= graphs.size()) { - graphs.add(new Graph(validParts, buffer_capacity)); + // all commands start with # + if(parts[i].startsWith("#") && parts[i].length() > 1) { + String command = parts[i].substring(1, parts[i].length()).trim(); + if(command.equals("CLEAR")) { + graphs.clear(); + } + else if(command.startsWith("SIZE:")) { + String[] subString = parts[i].split("[:]+"); + int newSize = BUFFER_CAPACITY_DEFAULT; + if(subString.length > 1) { + try { + newSize = Integer.parseInt(subString[1]); + } catch (NumberFormatException e) { + // Ignore + } + } + if((int)graphWidth.getValue() != newSize) { + graphWidth.setValue(newSize); + } + } + } else { + try { + double value = Double.valueOf(parts[i]); + if(validParts >= graphs.size()) { + graphs.add(new Graph(validParts, buffer_capacity)); + } + graphs.get(validParts).buffer.add(value); + validParts++; + } catch (NumberFormatException e) { + // ignore } - graphs.get(validParts).buffer.add(value); - validParts++; - } catch (NumberFormatException e) { - // ignore } } } From 4663941bd9a8dc3cbb79734d364bd63ecd9e567e Mon Sep 17 00:00:00 2001 From: Wilhelm Wiens Date: Thu, 9 Apr 2020 14:22:14 +0200 Subject: [PATCH 4/6] Do not modify parameter in setNewBufferCapacity Position literals first in String comparisons in message --- app/src/processing/app/SerialPlotter.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index 28427e9e2..58522fc11 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -291,12 +291,14 @@ public class SerialPlotter extends AbstractMonitor { private void setNewBufferCapacity(int capacity){ if(buffer_capacity != capacity) { - if(capacity > BUFFER_CAPACITY_MAX) capacity = BUFFER_CAPACITY_MAX; - else if(capacity < BUFFER_CAPACITY_MIN) capacity = BUFFER_CAPACITY_MIN; - buffer_capacity = capacity; + if(capacity > BUFFER_CAPACITY_MAX) buffer_capacity = BUFFER_CAPACITY_MAX; + else if(capacity < BUFFER_CAPACITY_MIN) buffer_capacity = BUFFER_CAPACITY_MIN; + else buffer_capacity = capacity; + for(int i = 0; i < graphs.size(); i++) { - graphs.get(i).buffer.newCapacity(capacity); + graphs.get(i).buffer.newCapacity(buffer_capacity); } + xCount=0; } } @@ -323,7 +325,7 @@ public class SerialPlotter extends AbstractMonitor { // all commands start with # if(parts[i].startsWith("#") && parts[i].length() > 1) { String command = parts[i].substring(1, parts[i].length()).trim(); - if(command.equals("CLEAR")) { + if("CLEAR".equals(command)) { graphs.clear(); } else if(command.startsWith("SIZE:")) { From 450c40d9f2edddd22d4dca924d72341e80700d76 Mon Sep 17 00:00:00 2001 From: Wilhelm Wiens Date: Thu, 9 Apr 2020 17:05:57 +0200 Subject: [PATCH 5/6] SerialPlotter: reset xCount when clear the graph --- app/src/processing/app/SerialPlotter.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index 1e537109b..1a8103404 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -263,7 +263,7 @@ public class SerialPlotter extends AbstractMonitor { graphWidth.addChangeListener(cl -> {setNewBufferCapacity((int)graphWidth.getValue()); } ); - clearButton.addActionListener(ae -> {graphs.clear();}); + clearButton.addActionListener(ae -> {CommandClearGraph();}); } protected void onCreateWindow(Container mainPane) { @@ -396,7 +396,7 @@ public class SerialPlotter extends AbstractMonitor { sendButton.addActionListener(listener); } - public void appyPreferences() { + public void applyPreferences() { // Apply line endings. if (PreferencesData.get("serial.line_ending") != null) { lineEndings.setSelectedIndex(PreferencesData.getInteger("serial.line_ending")); @@ -429,6 +429,12 @@ public class SerialPlotter extends AbstractMonitor { } } + private void CommandClearGraph() + { + graphs.clear(); + xCount=0; + } + public void message(final String s) { messageBuffer.append(s); while (true) { @@ -457,7 +463,7 @@ public class SerialPlotter extends AbstractMonitor { if(parts[i].startsWith("#") && parts[i].length() > 1) { String command = parts[i].substring(1, parts[i].length()).trim(); if("CLEAR".equals(command)) { - graphs.clear(); + CommandClearGraph(); } else if(command.startsWith("SIZE:")) { String[] subString = parts[i].split("[:]+"); @@ -522,14 +528,14 @@ public class SerialPlotter extends AbstractMonitor { if(value != null) { if(validParts >= graphs.size()) { - graphs.add(new Graph(validParts)); + graphs.add(new Graph(validParts, buffer_capacity)); } graphs.get(validParts).buffer.add(value); validParts++; } if(label != null) { if(validLabels >= graphs.size()) { - graphs.add(new Graph(validLabels)); + graphs.add(new Graph(validLabels, buffer_capacity)); } graphs.get(validLabels).label = label; validLabels++; @@ -538,10 +544,11 @@ public class SerialPlotter extends AbstractMonitor { else if(validLabels > validParts) validParts = validLabels; } } - + } SwingUtilities.invokeLater(SerialPlotter.this::repaint); } + public void open() throws Exception { super.open(); From 945f542ed53583dc8cac0b12beeb4b05d8e4f473 Mon Sep 17 00:00:00 2001 From: Wilhelm Wiens Date: Thu, 9 Apr 2020 17:41:51 +0200 Subject: [PATCH 6/6] fixed method name use also for size command a seperate function --- app/src/processing/app/SerialPlotter.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index 1a8103404..0d52cca85 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -261,9 +261,9 @@ public class SerialPlotter extends AbstractMonitor { messageBuffer = new StringBuffer(); graphs = new ArrayList<>(); - graphWidth.addChangeListener(cl -> {setNewBufferCapacity((int)graphWidth.getValue()); } ); + graphWidth.addChangeListener(cl -> {commandNewSize((int)graphWidth.getValue()); } ); - clearButton.addActionListener(ae -> {CommandClearGraph();}); + clearButton.addActionListener(ae -> {commandClearGraph();}); } protected void onCreateWindow(Container mainPane) { @@ -429,12 +429,20 @@ public class SerialPlotter extends AbstractMonitor { } } - private void CommandClearGraph() + private void commandClearGraph() { graphs.clear(); xCount=0; } + private void commandNewSize(int newSize) + { + setNewBufferCapacity(newSize); + if((int)graphWidth.getValue() != newSize) { + graphWidth.setValue(newSize); + } + } + public void message(final String s) { messageBuffer.append(s); while (true) { @@ -463,7 +471,7 @@ public class SerialPlotter extends AbstractMonitor { if(parts[i].startsWith("#") && parts[i].length() > 1) { String command = parts[i].substring(1, parts[i].length()).trim(); if("CLEAR".equals(command)) { - CommandClearGraph(); + commandClearGraph(); } else if(command.startsWith("SIZE:")) { String[] subString = parts[i].split("[:]+"); @@ -475,9 +483,7 @@ public class SerialPlotter extends AbstractMonitor { // Ignore } } - if((int)graphWidth.getValue() != newSize) { - graphWidth.setValue(newSize); - } + commandNewSize(newSize); } } else { try {