Skip to content

Commit 63f5d26

Browse files
committed
Improved Serial input processing.
Before this patch every byte received from Serial invokes a String allocation, not really efficient. Moreover a InputStreamReader is chained on the serial InputStream to correctly convert bytes into UTF-8 characters.
1 parent 391d338 commit 63f5d26

File tree

2 files changed

+26
-52
lines changed

2 files changed

+26
-52
lines changed

app/src/processing/app/Serial.java

+16-41
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
package processing.app;
2626
//import processing.core.*;
2727

28-
import processing.app.debug.MessageConsumer;
2928
import static processing.app.I18n._;
30-
3129
import gnu.io.*;
3230

3331
import java.io.*;
@@ -55,15 +53,13 @@ public class Serial implements SerialPortEventListener {
5553

5654
// read buffer and streams
5755

58-
InputStream input;
56+
InputStreamReader input;
5957
OutputStream output;
6058

6159
byte buffer[] = new byte[32768];
6260
int bufferIndex;
6361
int bufferLast;
6462

65-
MessageConsumer consumer;
66-
6763
public Serial(boolean monitor) throws SerialException {
6864
this(Preferences.get("serial.port"),
6965
Preferences.getInteger("serial.debug_rate"),
@@ -158,7 +154,7 @@ public Serial(String iname, int irate,
158154
if (portId.getName().equals(iname)) {
159155
//System.out.println("looking for "+iname);
160156
port = (SerialPort)portId.open("serial madness", 2000);
161-
input = port.getInputStream();
157+
input = new InputStreamReader(port.getInputStream());
162158
output = port.getOutputStream();
163159
port.setSerialPortParams(rate, databits, stopbits, parity);
164160
port.addEventListener(this);
@@ -237,62 +233,41 @@ public void dispose() {
237233
port = null;
238234
}
239235

236+
char serialBuffer[] = new char[4096];
240237

241-
public void addListener(MessageConsumer consumer) {
242-
this.consumer = consumer;
243-
}
244-
245-
246238
synchronized public void serialEvent(SerialPortEvent serialEvent) {
247-
//System.out.println("serial port event"); // " + serialEvent);
248-
//System.out.flush();
249-
//System.out.println("into");
250-
//System.out.flush();
251-
//System.err.println("type " + serialEvent.getEventType());
252-
//System.err.println("ahoooyey");
253-
//System.err.println("ahoooyeysdfsdfsdf");
254239
if (serialEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
255-
//System.out.println("data available");
256-
//System.err.flush();
257240
try {
258-
while (input.available() > 0) {
259-
//if (input.available() > 0) {
260-
//serial = input.read();
261-
//serialEvent();
262-
//buffer[bufferCount++] = (byte) serial;
241+
while (input.ready()) {
263242
synchronized (buffer) {
264243
if (bufferLast == buffer.length) {
265244
byte temp[] = new byte[bufferLast << 1];
266245
System.arraycopy(buffer, 0, temp, 0, bufferLast);
267246
buffer = temp;
268247
}
269-
//buffer[bufferLast++] = (byte) input.read();
270-
if(monitor == true)
271-
System.out.print((char) input.read());
272-
if (this.consumer != null)
273-
this.consumer.message("" + (char) input.read());
274-
275-
/*
276-
System.err.println(input.available() + " " +
277-
((char) buffer[bufferLast-1]));
278-
*/ //}
248+
int n = input.read(serialBuffer);
249+
message(serialBuffer, n);
279250
}
280251
}
281-
//System.out.println("no more");
282-
283252
} catch (IOException e) {
284253
errorMessage("serialEvent", e);
285-
//e.printStackTrace();
286-
//System.out.println("angry");
287254
}
288255
catch (Exception e) {
289256
}
290257
}
291-
//System.out.println("out of");
292-
//System.err.println("out of event " + serialEvent.getEventType());
293258
}
294259

295260

261+
/**
262+
* This method is intended to be redefined by users of Serial class
263+
*
264+
* @param buff
265+
* @param n
266+
*/
267+
protected void message(char buff[], int n) {
268+
// Empty
269+
}
270+
296271
/**
297272
* Returns the number of bytes that have been read from serial
298273
* and are waiting to be dealt with by the user.

app/src/processing/app/SerialMonitor.java

+10-11
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@
1818

1919
package processing.app;
2020

21-
import processing.app.debug.MessageConsumer;
2221
import processing.app.debug.TextAreaFIFO;
2322
import processing.core.*;
2423
import static processing.app.I18n._;
2524

2625
import java.awt.*;
2726
import java.awt.event.*;
27+
2828
import javax.swing.*;
2929
import javax.swing.border.*;
3030
import javax.swing.text.*;
3131

32-
public class SerialMonitor extends JFrame implements MessageConsumer,ActionListener {
32+
public class SerialMonitor extends JFrame implements ActionListener {
3333
private Serial serial;
3434
private String port;
3535
private TextAreaFIFO textArea;
@@ -210,8 +210,12 @@ private void send(String s) {
210210

211211
public void openSerialPort() throws SerialException {
212212
if (serial != null) return;
213-
serial = new Serial(port, serialRate);
214-
serial.addListener(this);
213+
serial = new Serial(port, serialRate) {
214+
@Override
215+
protected void message(char buff[], int n) {
216+
addToUpdateBuffer(buff, n);
217+
}
218+
};
215219
updateTimer.start();
216220
}
217221

@@ -226,13 +230,8 @@ public void closeSerialPort() {
226230
}
227231
}
228232

229-
public void message(String s) {
230-
// TODO: can we pass a byte array, to avoid overhead of String
231-
addToUpdateBuffer(s);
232-
}
233-
234-
private synchronized void addToUpdateBuffer(String s) {
235-
updateBuffer.append(s);
233+
private synchronized void addToUpdateBuffer(char buff[], int n) {
234+
updateBuffer.append(buff, 0, n);
236235
}
237236

238237
private synchronized String consumeUpdateBuffer() {

0 commit comments

Comments
 (0)