mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-18 07:52:14 +01:00
Serial flushing now works (added Processing's Serial library as found in the
Wiring repository).
This commit is contained in:
parent
30999fdcfd
commit
0837e89f15
627
app/Serial.java
Executable file
627
app/Serial.java
Executable file
@ -0,0 +1,627 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
PSerial - class for serial port goodness
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004 Ben Fry & Casey Reas
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
//import processing.core.*;
|
||||
|
||||
import gnu.io.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class Serial implements SerialPortEventListener {
|
||||
|
||||
//PApplet parent;
|
||||
|
||||
// properties can be passed in for default values
|
||||
// otherwise defaults to 9600 N81
|
||||
|
||||
// these could be made static, which might be a solution
|
||||
// for the classloading problem.. because if code ran again,
|
||||
// the static class would have an object that could be closed
|
||||
|
||||
SerialPort port;
|
||||
|
||||
int rate;
|
||||
int parity;
|
||||
int databits;
|
||||
int stopbits;
|
||||
boolean monitor = false;
|
||||
|
||||
// read buffer and streams
|
||||
|
||||
InputStream input;
|
||||
OutputStream output;
|
||||
|
||||
byte buffer[] = new byte[32768];
|
||||
int bufferIndex;
|
||||
int bufferLast;
|
||||
|
||||
|
||||
// defaults
|
||||
|
||||
static String dname = Preferences.get("serial.port"); //"COM1";
|
||||
static int drate = 9600;
|
||||
static char dparity = 'N';
|
||||
static int ddatabits = 8;
|
||||
static float dstopbits = 1;
|
||||
|
||||
/*
|
||||
public void setProperties(Properties props) {
|
||||
dname =
|
||||
props.getProperty("serial.port", dname);
|
||||
drate =
|
||||
Integer.parseInt(props.getProperty("serial.rate", "9600"));
|
||||
dparity =
|
||||
props.getProperty("serial.parity", "N").charAt(0);
|
||||
ddatabits =
|
||||
Integer.parseInt(props.getProperty("serial.databits", "8"));
|
||||
dstopbits =
|
||||
new Float(props.getProperty("serial.stopbits", "1")).floatValue();
|
||||
}
|
||||
*/
|
||||
|
||||
public void setProperties() {
|
||||
//System.out.println("setting serial properties");
|
||||
dname = Preferences.get("serial.port");
|
||||
drate = Preferences.getInteger("serial.debug_rate");
|
||||
dparity = Preferences.get("serial.parity").charAt(0);
|
||||
ddatabits = Preferences.getInteger("serial.databits");
|
||||
dstopbits = new Float(Preferences.get("serial.stopbits")).floatValue();
|
||||
}
|
||||
|
||||
public Serial(boolean monitor) {
|
||||
this(dname, drate, dparity, ddatabits, dstopbits);
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public Serial() {
|
||||
//setProperties();
|
||||
this(dname, drate, dparity, ddatabits, dstopbits);
|
||||
}
|
||||
|
||||
public Serial(int irate) {
|
||||
this(dname, irate, dparity, ddatabits, dstopbits);
|
||||
}
|
||||
|
||||
public Serial(String iname, int irate) {
|
||||
this(iname, irate, dparity, ddatabits, dstopbits);
|
||||
}
|
||||
|
||||
public Serial(String iname) {
|
||||
this(iname, drate, dparity, ddatabits, dstopbits);
|
||||
}
|
||||
|
||||
public Serial(String iname, int irate,
|
||||
char iparity, int idatabits, float istopbits) {
|
||||
//if (port != null) port.close();
|
||||
//this.parent = parent;
|
||||
//parent.attach(this);
|
||||
|
||||
this.rate = irate;
|
||||
|
||||
parity = SerialPort.PARITY_NONE;
|
||||
if (iparity == 'E') parity = SerialPort.PARITY_EVEN;
|
||||
if (iparity == 'O') parity = SerialPort.PARITY_ODD;
|
||||
|
||||
this.databits = idatabits;
|
||||
|
||||
stopbits = SerialPort.STOPBITS_1;
|
||||
if (istopbits == 1.5f) stopbits = SerialPort.STOPBITS_1_5;
|
||||
if (istopbits == 2) stopbits = SerialPort.STOPBITS_2;
|
||||
|
||||
try {
|
||||
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
|
||||
while (portList.hasMoreElements()) {
|
||||
CommPortIdentifier portId =
|
||||
(CommPortIdentifier) portList.nextElement();
|
||||
|
||||
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
|
||||
//System.out.println("found " + portId.getName());
|
||||
if (portId.getName().equals(iname)) {
|
||||
//System.out.println("looking for "+iname);
|
||||
port = (SerialPort)portId.open("serial madness", 2000);
|
||||
input = port.getInputStream();
|
||||
output = port.getOutputStream();
|
||||
port.setSerialPortParams(rate, databits, stopbits, parity);
|
||||
port.addEventListener(this);
|
||||
port.notifyOnDataAvailable(true);
|
||||
//System.out.println("opening, ready to roll");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
errorMessage("<init>", e);
|
||||
//exception = e;
|
||||
//e.printStackTrace();
|
||||
port = null;
|
||||
input = null;
|
||||
output = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setup() {
|
||||
//parent.registerCall(this, DISPOSE);
|
||||
}
|
||||
|
||||
|
||||
//public void size(int w, int h) { }
|
||||
|
||||
//public void pre() { }
|
||||
|
||||
//public void draw() { }
|
||||
|
||||
//public void post() { }
|
||||
|
||||
//public void mouse(java.awt.event.MouseEvent event) { }
|
||||
|
||||
//public void key(java.awt.event.KeyEvent e) { }
|
||||
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
// do io streams need to be closed first?
|
||||
if (input != null) input.close();
|
||||
if (output != null) output.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
input = null;
|
||||
output = null;
|
||||
|
||||
try {
|
||||
if (port != null) port.close(); // close the port
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
port = null;
|
||||
}
|
||||
|
||||
|
||||
synchronized public void serialEvent(SerialPortEvent serialEvent) {
|
||||
//System.out.println("serial port event"); // " + serialEvent);
|
||||
//System.out.flush();
|
||||
//System.out.println("into");
|
||||
//System.out.flush();
|
||||
//System.err.println("type " + serialEvent.getEventType());
|
||||
//System.err.println("ahoooyey");
|
||||
//System.err.println("ahoooyeysdfsdfsdf");
|
||||
if (serialEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
|
||||
//System.out.println("data available");
|
||||
//System.err.flush();
|
||||
try {
|
||||
while (input.available() > 0) {
|
||||
//if (input.available() > 0) {
|
||||
//serial = input.read();
|
||||
//serialEvent();
|
||||
//buffer[bufferCount++] = (byte) serial;
|
||||
synchronized (buffer) {
|
||||
if (bufferLast == buffer.length) {
|
||||
byte temp[] = new byte[bufferLast << 1];
|
||||
System.arraycopy(buffer, 0, temp, 0, bufferLast);
|
||||
buffer = temp;
|
||||
}
|
||||
//buffer[bufferLast++] = (byte) input.read();
|
||||
if(monitor == true)
|
||||
System.out.print((char) input.read());
|
||||
|
||||
/*
|
||||
System.err.println(input.available() + " " +
|
||||
((char) buffer[bufferLast-1]));
|
||||
*/ //}
|
||||
}
|
||||
}
|
||||
//System.out.println("no more");
|
||||
|
||||
} catch (IOException e) {
|
||||
errorMessage("serialEvent", e);
|
||||
//e.printStackTrace();
|
||||
//System.out.println("angry");
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
//System.out.println("out of");
|
||||
//System.err.println("out of event " + serialEvent.getEventType());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that have been read from serial
|
||||
* and are waiting to be dealt with by the user.
|
||||
*/
|
||||
public int available() {
|
||||
return (bufferLast - bufferIndex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ignore all the bytes read so far and empty the buffer.
|
||||
*/
|
||||
public void clear() {
|
||||
bufferLast = 0;
|
||||
bufferIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a number between 0 and 255 for the next byte that's
|
||||
* waiting in the buffer.
|
||||
* Returns -1 if there was no byte (although the user should
|
||||
* first check available() to see if things are ready to avoid this)
|
||||
*/
|
||||
public int read() {
|
||||
if (bufferIndex == bufferLast) return -1;
|
||||
|
||||
synchronized (buffer) {
|
||||
int outgoing = buffer[bufferIndex++] & 0xff;
|
||||
if (bufferIndex == bufferLast) { // rewind
|
||||
bufferIndex = 0;
|
||||
bufferLast = 0;
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the next byte in the buffer as a char.
|
||||
* Returns -1, or 0xffff, if nothing is there.
|
||||
*/
|
||||
public char readChar() {
|
||||
if (bufferIndex == bufferLast) return (char)(-1);
|
||||
return (char) read();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a byte array of anything that's in the serial buffer.
|
||||
* Not particularly memory/speed efficient, because it creates
|
||||
* a byte array on each read, but it's easier to use than
|
||||
* readBytes(byte b[]) (see below).
|
||||
*/
|
||||
public byte[] readBytes() {
|
||||
if (bufferIndex == bufferLast) return null;
|
||||
|
||||
synchronized (buffer) {
|
||||
int length = bufferLast - bufferIndex;
|
||||
byte outgoing[] = new byte[length];
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grab whatever is in the serial buffer, and stuff it into a
|
||||
* byte buffer passed in by the user. This is more memory/time
|
||||
* efficient than readBytes() returning a byte[] array.
|
||||
*
|
||||
* Returns an int for how many bytes were read. If more bytes
|
||||
* are available than can fit into the byte array, only those
|
||||
* that will fit are read.
|
||||
*/
|
||||
public int readBytes(byte outgoing[]) {
|
||||
if (bufferIndex == bufferLast) return 0;
|
||||
|
||||
synchronized (buffer) {
|
||||
int length = bufferLast - bufferIndex;
|
||||
if (length > outgoing.length) length = outgoing.length;
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex += length;
|
||||
if (bufferIndex == bufferLast) {
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads from the serial port into a buffer of bytes up to and
|
||||
* including a particular character. If the character isn't in
|
||||
* the serial buffer, then 'null' is returned.
|
||||
*/
|
||||
public byte[] readBytesUntil(int interesting) {
|
||||
if (bufferIndex == bufferLast) return null;
|
||||
byte what = (byte)interesting;
|
||||
|
||||
synchronized (buffer) {
|
||||
int found = -1;
|
||||
for (int k = bufferIndex; k < bufferLast; k++) {
|
||||
if (buffer[k] == what) {
|
||||
found = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == -1) return null;
|
||||
|
||||
int length = found - bufferIndex + 1;
|
||||
byte outgoing[] = new byte[length];
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads from the serial port into a buffer of bytes until a
|
||||
* particular character. If the character isn't in the serial
|
||||
* buffer, then 'null' is returned.
|
||||
*
|
||||
* If outgoing[] is not big enough, then -1 is returned,
|
||||
* and an error message is printed on the console.
|
||||
* If nothing is in the buffer, zero is returned.
|
||||
* If 'interesting' byte is not in the buffer, then 0 is returned.
|
||||
*/
|
||||
public int readBytesUntil(int interesting, byte outgoing[]) {
|
||||
if (bufferIndex == bufferLast) return 0;
|
||||
byte what = (byte)interesting;
|
||||
|
||||
synchronized (buffer) {
|
||||
int found = -1;
|
||||
for (int k = bufferIndex; k < bufferLast; k++) {
|
||||
if (buffer[k] == what) {
|
||||
found = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == -1) return 0;
|
||||
|
||||
int length = found - bufferIndex + 1;
|
||||
if (length > outgoing.length) {
|
||||
System.err.println("readBytesUntil() byte buffer is" +
|
||||
" too small for the " + length +
|
||||
" bytes up to and including char " + interesting);
|
||||
return -1;
|
||||
}
|
||||
//byte outgoing[] = new byte[length];
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex += length;
|
||||
if (bufferIndex == bufferLast) {
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return whatever has been read from the serial port so far
|
||||
* as a String. It assumes that the incoming characters are ASCII.
|
||||
*
|
||||
* If you want to move Unicode data, you can first convert the
|
||||
* String to a byte stream in the representation of your choice
|
||||
* (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
|
||||
*/
|
||||
public String readString() {
|
||||
if (bufferIndex == bufferLast) return null;
|
||||
return new String(readBytes());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Combination of readBytesUntil and readString. See caveats in
|
||||
* each function. Returns null if it still hasn't found what
|
||||
* you're looking for.
|
||||
*
|
||||
* If you want to move Unicode data, you can first convert the
|
||||
* String to a byte stream in the representation of your choice
|
||||
* (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
|
||||
*/
|
||||
public String readStringUntil(int interesting) {
|
||||
byte b[] = readBytesUntil(interesting);
|
||||
if (b == null) return null;
|
||||
return new String(b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This will handle both ints, bytes and chars transparently.
|
||||
*/
|
||||
public void write(int what) { // will also cover char
|
||||
try {
|
||||
output.write(what & 0xff); // for good measure do the &
|
||||
output.flush(); // hmm, not sure if a good idea
|
||||
|
||||
} catch (Exception e) { // null pointer or serial port dead
|
||||
errorMessage("write", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void write(byte bytes[]) {
|
||||
try {
|
||||
output.write(bytes);
|
||||
output.flush(); // hmm, not sure if a good idea
|
||||
|
||||
} catch (Exception e) { // null pointer or serial port dead
|
||||
//errorMessage("write", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a String to the output. Note that this doesn't account
|
||||
* for Unicode (two bytes per char), nor will it send UTF8
|
||||
* characters.. It assumes that you mean to send a byte buffer
|
||||
* (most often the case for networking and serial i/o) and
|
||||
* will only use the bottom 8 bits of each char in the string.
|
||||
* (Meaning that internally it uses String.getBytes)
|
||||
*
|
||||
* If you want to move Unicode data, you can first convert the
|
||||
* String to a byte stream in the representation of your choice
|
||||
* (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
|
||||
*/
|
||||
public void write(String what) {
|
||||
write(what.getBytes());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this just hangs and never completes on Windows,
|
||||
* it may be because the DLL doesn't have its exec bit set.
|
||||
* Why the hell that'd be the case, who knows.
|
||||
*/
|
||||
static public String[] list() {
|
||||
Vector list = new Vector();
|
||||
try {
|
||||
//System.err.println("trying");
|
||||
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
|
||||
//System.err.println("got port list");
|
||||
while (portList.hasMoreElements()) {
|
||||
CommPortIdentifier portId =
|
||||
(CommPortIdentifier) portList.nextElement();
|
||||
//System.out.println(portId);
|
||||
|
||||
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
|
||||
String name = portId.getName();
|
||||
list.addElement(name);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
//System.err.println("1");
|
||||
errorMessage("ports", e);
|
||||
|
||||
} catch (Exception e) {
|
||||
//System.err.println("2");
|
||||
errorMessage("ports", e);
|
||||
}
|
||||
//System.err.println("move out");
|
||||
String outgoing[] = new String[list.size()];
|
||||
list.copyInto(outgoing);
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General error reporting, all corraled here just in case
|
||||
* I think of something slightly more intelligent to do.
|
||||
*/
|
||||
static public void errorMessage(String where, Throwable e) {
|
||||
System.err.println("Error inside Serial." + where + "()");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
class SerialMenuListener implements ItemListener {
|
||||
//public SerialMenuListener() { }
|
||||
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
int count = serialMenu.getItemCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
((CheckboxMenuItem)serialMenu.getItem(i)).setState(false);
|
||||
}
|
||||
CheckboxMenuItem item = (CheckboxMenuItem)e.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getLabel();
|
||||
//System.out.println(item.getLabel());
|
||||
PdeBase.properties.put("serial.port", name);
|
||||
//System.out.println("set to " + get("serial.port"));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
protected Vector buildPortList() {
|
||||
// get list of names for serial ports
|
||||
// have the default port checked (if present)
|
||||
Vector list = new Vector();
|
||||
|
||||
//SerialMenuListener listener = new SerialMenuListener();
|
||||
boolean problem = false;
|
||||
|
||||
// if this is failing, it may be because
|
||||
// lib/javax.comm.properties is missing.
|
||||
// java is weird about how it searches for java.comm.properties
|
||||
// so it tends to be very fragile. i.e. quotes in the CLASSPATH
|
||||
// environment variable will hose things.
|
||||
try {
|
||||
//System.out.println("building port list");
|
||||
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
|
||||
while (portList.hasMoreElements()) {
|
||||
CommPortIdentifier portId =
|
||||
(CommPortIdentifier) portList.nextElement();
|
||||
//System.out.println(portId);
|
||||
|
||||
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
|
||||
//if (portId.getName().equals(port)) {
|
||||
String name = portId.getName();
|
||||
//CheckboxMenuItem mi =
|
||||
//new CheckboxMenuItem(name, name.equals(defaultName));
|
||||
|
||||
//mi.addItemListener(listener);
|
||||
//serialMenu.add(mi);
|
||||
list.addElement(name);
|
||||
}
|
||||
}
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
e.printStackTrace();
|
||||
problem = true;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception building serial menu");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//if (serialMenu.getItemCount() == 0) {
|
||||
//System.out.println("dimming serial menu");
|
||||
//serialMenu.setEnabled(false);
|
||||
//}
|
||||
|
||||
// only warn them if this is the first time
|
||||
if (problem && PdeBase.firstTime) {
|
||||
JOptionPane.showMessageDialog(this, //frame,
|
||||
"Serial port support not installed.\n" +
|
||||
"Check the readme for instructions\n" +
|
||||
"if you need to use the serial port. ",
|
||||
"Serial Port Warning",
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
@ -105,6 +105,7 @@ public class Uploader implements MessageConsumer {
|
||||
commandDownloader.add((!Base.isMacOS() ? "" : userdir) + "tools/avr/bin/uisp");
|
||||
commandDownloader.add("-dprog=" + Preferences.get("upload.programmer"));
|
||||
commandDownloader.add("-dpart=" + Preferences.get("build.mcu"));
|
||||
//commandDownloader.add("-v=4"); // extra verbosity for help debugging.
|
||||
if (Preferences.get("upload.programmer").equals("dapa"))
|
||||
commandDownloader.add("-dlpt=" + Preferences.get("parallel.port"));
|
||||
else {
|
||||
@ -126,7 +127,7 @@ public class Uploader implements MessageConsumer {
|
||||
}*/
|
||||
|
||||
// Cleanup the serial buffer
|
||||
serialPort = new Serial();
|
||||
Serial serialPort = new Serial();
|
||||
byte[] readBuffer;
|
||||
while(serialPort.available() > 0) {
|
||||
readBuffer = serialPort.readBytes();
|
||||
|
Loading…
x
Reference in New Issue
Block a user