package com.rle.monitor; /* * RLE Surface Crack Detector Graphing Software * * Copyright (C) 2002 RLE Technologies * For more information visit http://www.rletech.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ /** * @author Andy Goth * @author Eric Peterson * @author Matt Lane * @version 0.1 */ import java.io.*; import java.lang.*; import java.util.*; import javax.comm.*; /** Serial connection to an actual scanner device. */ public class Serial extends ScannerAdapter implements SerialPortEventListener { private SerialPort port; /* Serial port device */ private InputStream input; /* Input stream from port */ private OutputStream output; /* Output stream to port */ private int cmdState = 0; /* State of an echo command */ private int cmdType = 0; /* Type of command being echoed */ private int buffer[] = new int[7]; private int bufIdx = 0; public void open(String portName) throws IOException { if (port != null) throw new IOException("Device already opened"); try { port = getSerialPort(portName); input = port.getInputStream(); output = port.getOutputStream(); port.addEventListener(this); port.notifyOnDataAvailable(true); beginDataTransfer(); } catch (PortInUseException e) { throw new IOException("Port in use: " + e.getMessage()); } catch (UnsupportedCommOperationException e) { throw new IOException("Unsupported operation: " + e.getMessage()); } catch (TooManyListenersException e) { throw new IOException("Too many port listeners: " + e.getMessage()); } catch (NoSuchPortException e) { throw new IOException("Port " + portName + " not found: " + e.getMessage()); } } public void close() throws IOException { if (port == null) throw new IOException("Device not opened"); reset(); port.close(); } public void beginDataTransfer() throws IOException {output.write("DT\r".getBytes());} public void reset() throws IOException {sendCommand(0x00, 0x00);} public void setOffset(int o) throws IOException {sendCommand(0x01, (byte)o);} public void setGain(int g) throws IOException {sendCommand(0x02, (byte)g);} public void setAutoOffset() throws IOException {sendCommand(0x03, 0x01);} public void setAlarm(boolean f) throws IOException {sendCommand(0x11, f ? 0x01 : 0x00);} public void setRedLED() throws IOException {sendCommand(0x21, 0x01);} public void setGreenLED() throws IOException {sendCommand(0x21, 0x02);} public void setLED(boolean f) throws IOException {sendCommand(0x21, f ? 0x03 : 0x00);} public void setThreshhold(int t) throws IOException {sendCommand(0x30, t);} public void queryOffset() throws IOException {sendCommand(0x40, 0x01);} public void queryGain() throws IOException {sendCommand(0x40, 0x02);} public void queryThreshhold() throws IOException {sendCommand(0x40, 0x30);} /** Finds, opens, configures, and returns the named port. */ private SerialPort getSerialPort(String portName) throws PortInUseException, UnsupportedCommOperationException, IOException, NoSuchPortException { /* Open and configure the port */ SerialPort port = (SerialPort)CommPortIdentifier. getPortIdentifier(portName).open("RLE Monitor", 2000); port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); port.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); return port; } /** Sends a command to the attached device. */ private void sendCommand(int cw1, int cw2) throws IOException { output.write(0x01); output.write(cw1); output.write(cw2); output.write(0x00); output.write(0xff); } /** Decodes a command echo received from the device. */ private int cmdDecode(int cw) { switch (cw) { case 0x01: return OFFSET; case 0x02: return GAIN; case 0x03: return AUTO_OFFSET; case 0x11: return ALARM; case 0x21: return LED; case 0x30: return THRESHHOLD; case 0x40: return QUERY; default: return 0; } } /** Returns the next filtered sample. */ private int filter(int value) { buffer[bufIdx++] = value; if (bufIdx == 7) bufIdx = 0; int out = buffer[bufIdx]; out += 6 * buffer[bufIdx - 6 < 0 ? bufIdx + 1 : bufIdx - 6]; out += 15 * buffer[bufIdx - 5 < 0 ? bufIdx + 2 : bufIdx - 5]; out += 20 * buffer[bufIdx - 4 < 0 ? bufIdx + 3 : bufIdx - 4]; out += 15 * buffer[bufIdx - 3 < 0 ? bufIdx + 4 : bufIdx - 3]; out += 6 * buffer[bufIdx - 2 < 0 ? bufIdx + 5 : bufIdx - 2]; out += value; return out / 64; } /** Serial event handler. */ public void serialEvent(SerialPortEvent event) { /* switch (event.getEventType()) { case SerialPortEvent.BI: case SerialPortEvent.OE: case SerialPortEvent.FE: case SerialPortEvent.PE: case SerialPortEvent.CD: case SerialPortEvent.CTS: case SerialPortEvent.DSR: case SerialPortEvent.RI: case SerialPortEvent.OUTPUT_BUFFER_EMPTY: break; case SerialPortEvent.DATA_AVAILABLE: */ if (event.getEventType() != SerialPortEvent.DATA_AVAILABLE) return; try { int count = input.available(); for (int i = 0; i < count; i++) { int val = input.read(); switch (cmdState) { case 0: if (val == 0) cmdState = 1; else sendSample(filter(val)); break; case 1: cmdType = cmdDecode(val); if (cmdType == 0) cmdState = 0; else cmdState = 2; break; case 2: sendEcho(cmdType, val); cmdState = 0; } } } catch (IOException e) { e.printStackTrace(); } } }