Skip to content

Commit

Permalink
Tame Serial Monitor Memory & CPU Usage (Arduino issue #2233)
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulStoffregen committed Dec 7, 2014
1 parent d8984e7 commit 03cb017
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 11 deletions.
50 changes: 39 additions & 11 deletions app/src/processing/app/SerialMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package processing.app;

import processing.app.debug.MessageConsumer;
import processing.app.debug.TextAreaFIFO;
import processing.core.*;
import static processing.app.I18n._;

Expand All @@ -32,17 +33,19 @@
import java.net.*;
import java.util.*;

public class SerialMonitor extends JFrame implements MessageConsumer {
public class SerialMonitor extends JFrame implements MessageConsumer,ActionListener {
private Serial serial;
private String port;
private JTextArea textArea;
private TextAreaFIFO textArea;
private JScrollPane scrollPane;
private JTextField textField;
private JButton sendButton;
private JCheckBox autoscrollBox;
private JComboBox lineEndings;
private JComboBox serialRates;
private int serialRate;
private javax.swing.Timer updateTimer;
private StringBuffer updateBuffer;

public SerialMonitor(String port) {
super(port);
Expand Down Expand Up @@ -70,7 +73,9 @@ public void actionPerformed(ActionEvent e) {
Font editorFont = Preferences.getFont("editor.font");
Font font = new Font(consoleFont.getName(), consoleFont.getStyle(), editorFont.getSize());

textArea = new JTextArea(16, 40);
textArea = new TextAreaFIFO(4000000);
textArea.setRows(16);
textArea.setColumns(40);
textArea.setEditable(false);
textArea.setFont(font);

Expand Down Expand Up @@ -174,6 +179,9 @@ public void actionPerformed(ActionEvent event) {
}
}
}

updateBuffer = new StringBuffer(1048576);
updateTimer = new javax.swing.Timer(33, this); // redraw serial monitor at 30 Hz
}

protected void setPlacement(int[] location) {
Expand Down Expand Up @@ -230,6 +238,7 @@ public void openSerialPort() throws SerialException {
}
}
serial.addListener(this);
updateTimer.start();
}

public void closeSerialPort() {
Expand All @@ -243,15 +252,34 @@ public void closeSerialPort() {
}
}

public void message(final String s) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(s);
if (autoscrollBox.isSelected()) {
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}});
public void message(String s) {
// TODO: can we pass a byte array, to avoid overhead of String
addToUpdateBuffer(s);
}

private synchronized void addToUpdateBuffer(String s) {
updateBuffer.append(s);
}

private synchronized String consumeUpdateBuffer() {
String s = updateBuffer.toString();
updateBuffer.setLength(0);
return s;
}

public void actionPerformed(ActionEvent e) {
final String s = consumeUpdateBuffer();
if (s.length() > 0) {
//System.out.println("gui append " + s.length());
boolean scroll = autoscrollBox.isSelected();
textArea.allowTrim(scroll);
textArea.append(s);
if (scroll) {
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}
}

}

class FakeSerial extends Serial {
Expand Down
55 changes: 55 additions & 0 deletions app/src/processing/app/debug/TextAreaFIFO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// adapted from https://community.oracle.com/thread/1479784

package processing.app.debug;

import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

public class TextAreaFIFO extends JTextArea implements DocumentListener
{
private int maxChars;
private int updateCount; // limit how often we trim the document
private boolean doTrim;

public TextAreaFIFO(int max) {
maxChars = max;
updateCount = 0;
doTrim = true;
getDocument().addDocumentListener( this );
}

public void allowTrim(boolean trim) {
doTrim = trim;
}

public void insertUpdate(DocumentEvent e) {
if (++updateCount > 150 && doTrim) {
updateCount = 0;
SwingUtilities.invokeLater( new Runnable() {
public void run() {
trimDocument();
}
});
}
}

public void removeUpdate(DocumentEvent e) {}
public void changedUpdate(DocumentEvent e) {}

public void trimDocument() {
int len = 0;
len = getDocument().getLength();
if (len > maxChars) {
int n = len - maxChars;
System.out.println("trimDocument: remove " + n + " chars");
try {
getDocument().remove(0, n);
} catch(BadLocationException ble) {
}
}
}
}

0 comments on commit 03cb017

Please sign in to comment.