1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-02 22:52:12 +01:00

331 lines
9.9 KiB
Java
Raw Normal View History

/*
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 static processing.app.I18n._;
2009-06-13 20:26:21 +00:00
2013-10-04 11:30:45 +02:00
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
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;
2013-10-04 11:30:45 +02:00
public Serial() throws SerialException {
this(PreferencesData.get("serial.port"),
PreferencesData.getInteger("serial.debug_rate"),
PreferencesData.get("serial.parity").charAt(0),
PreferencesData.getInteger("serial.databits"),
new Float(PreferencesData.get("serial.stopbits")).floatValue());
}
public Serial(int irate) throws SerialException {
this(PreferencesData.get("serial.port"), irate,
PreferencesData.get("serial.parity").charAt(0),
PreferencesData.getInteger("serial.databits"),
new Float(PreferencesData.get("serial.stopbits")).floatValue());
}
public Serial(String iname, int irate) throws SerialException {
this(iname, irate, PreferencesData.get("serial.parity").charAt(0),
PreferencesData.getInteger("serial.databits"),
new Float(PreferencesData.get("serial.stopbits")).floatValue());
}
public Serial(String iname) throws SerialException {
this(iname, PreferencesData.getInteger("serial.debug_rate"),
PreferencesData.get("serial.parity").charAt(0),
PreferencesData.getInteger("serial.databits"),
new Float(PreferencesData.get("serial.stopbits")).floatValue());
}
public static boolean touchForCDCReset(String iname) throws SerialException {
2013-10-04 11:30:45 +02:00
SerialPort serialPort = new SerialPort(iname);
try {
2013-10-04 11:30:45 +02:00
serialPort.openPort();
serialPort.setParams(1200, 8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
serialPort.setDTR(false);
2013-10-04 11:30:45 +02:00
serialPort.closePort();
return true;
} catch (SerialPortException e) {
throw new SerialException(I18n.format(_("Error touching serial port ''{0}''."), iname), e);
} finally {
if (serialPort.isOpened()) {
try {
serialPort.closePort();
} catch (SerialPortException e) {
// noop
}
}
}
}
2013-10-04 11:30:45 +02:00
public Serial(String iname, int irate, char iparity, int idatabits, float istopbits) throws SerialException {
//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 {
2013-10-04 11:30:45 +02:00
port = new SerialPort(iname);
port.openPort();
port.setParams(rate, databits, stopbits, parity, true, true);
port.addEventListener(this);
} catch (Exception e) {
2013-10-04 11:30:45 +02:00
throw new SerialException(I18n.format(_("Error opening serial port ''{0}''."), iname), e);
}
2013-10-04 11:30:45 +02:00
if (port == null) {
2013-10-04 11:30:45 +02:00
throw new SerialNotFoundException(I18n.format(_("Serial port ''{0}'' not found. Did you select the right one from the Tools > Serial Port menu?"), iname));
}
}
public void setup() {
//parent.registerCall(this, DISPOSE);
}
public void dispose() throws IOException {
2013-10-04 11:30:45 +02:00
if (port != null) {
try {
if (port.isOpened()) {
port.closePort(); // close the port
}
} catch (SerialPortException e) {
throw new IOException(e);
} finally {
port = null;
}
}
}
2013-10-04 11:30:45 +02:00
public synchronized void serialEvent(SerialPortEvent serialEvent) {
if (serialEvent.isRXCHAR()) {
try {
byte[] buf = port.readBytes(serialEvent.getEventValue());
2013-10-04 11:30:45 +02:00
if (buf.length > 0) {
String msg = new String(buf);
char[] chars = msg.toCharArray();
message(chars, chars.length);
}
2013-10-04 11:30:45 +02:00
} catch (SerialPortException e) {
errorMessage("serialEvent", e);
}
}
}
/**
* This method is intented to be extended to receive messages
* coming from serial port.
*
* @param chars
* @param length
*/
protected void message(char[] chars, int length) {
// Empty
}
/**
* This will handle both ints, bytes and chars transparently.
*/
public void write(int what) { // will also cover char
try {
2013-10-04 11:30:45 +02:00
port.writeInt(what & 0xff);
} catch (SerialPortException e) {
errorMessage("write", e);
}
}
public void write(byte bytes[]) {
try {
2013-10-04 11:30:45 +02:00
port.writeBytes(bytes);
} catch (SerialPortException e) {
errorMessage("write", e);
}
}
/**
* Write a String to the output. Note that this doesn't account
2013-10-04 11:30:45 +02:00
* 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)
2013-10-04 11:30:45 +02:00
* <p/>
* 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());
}
public void setDTR(boolean state) {
2013-10-04 11:30:45 +02:00
try {
port.setDTR(state);
} catch (SerialPortException e) {
errorMessage("setDTR", e);
}
}
public void setRTS(boolean state) {
2013-10-04 11:30:45 +02:00
try {
port.setRTS(state);
} catch (SerialPortException e) {
errorMessage("setRTS", e);
}
}
static public List<String> list() {
2013-10-04 11:30:45 +02:00
return Arrays.asList(SerialPortList.getPortNames());
}
/**
* 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(I18n.format(_("Error inside Serial.{0}()"), 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;
}
*/