/** * @generate serialEvent.xml * @webref serial:events * @usage web_application * @param event the port where new data is available */ public void serialEvent(SerialPortEvent event) { if (event.getEventType() == SerialPortEvent.RXCHAR) { int toRead; try { while (0 < (toRead = port.getInputBufferBytesCount())) { // this method can be called from the context of another thread synchronized (buffer) { // read one byte at a time if the sketch is using serialEvent if (serialEventMethod != null) { toRead = 1; } // enlarge buffer if necessary if (buffer.length < inBuffer + toRead) { byte temp[] = new byte[buffer.length << 1]; System.arraycopy(buffer, 0, temp, 0, inBuffer); buffer = temp; } // read an array of bytes and copy it into our buffer byte[] read = port.readBytes(toRead); System.arraycopy(read, 0, buffer, inBuffer, read.length); inBuffer += read.length; } if (serialEventMethod != null) { if ((0 < bufferUntilSize && bufferUntilSize <= inBuffer - readOffset) || (0 == bufferUntilSize && bufferUntilByte == buffer[inBuffer - 1])) { try { // serialEvent() is invoked in the context of the current (serial) thread // which means that serialization and atomic variables need to be used to // guarantee reliable operation (and better not draw() etc..) // serialAvailable() does not provide any real benefits over using // available() and read() inside draw - but this function has no // thread-safety issues since it's being invoked during pre in the context // of the Processing applet serialEventMethod.invoke(parent, this); } catch (Exception e) { System.err.println("Error, disabling serialEvent() for " + port.getPortName()); System.err.println(e.getLocalizedMessage()); serialEventMethod = null; } } } invokeSerialAvailable = true; } } catch (SerialPortException e) { throw new RuntimeException( "Error reading from serial port " + e.getPortName() + ": " + e.getExceptionType()); } } }
/** Set the RTS line */ public void setRTS(boolean state) { try { port.setRTS(state); } catch (SerialPortException e) { throw new RuntimeException("Error setting the RTS line: " + e.getExceptionType()); } }
public boolean getDSR() { try { return port.isDSR(); } catch (SerialPortException e) { throw new RuntimeException("Error reading the DSR line: " + e.getExceptionType()); } }
/** * @generate Serial_write.xml * <h3>Advanced</h3> * 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) * <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. * @webref serial:serial * @usage web_application * @param src data to write */ public void write(String src) { try { port.writeString(src); } catch (SerialPortException e) { throw new RuntimeException( "Error writing to serial port " + e.getPortName() + ": " + e.getExceptionType()); } }
/** * @generate Serial_stop.xml * @webref serial:serial * @usage web_application */ public void stop() { try { port.closePort(); } catch (SerialPortException e) { // ignored } inBuffer = 0; readOffset = 0; }
/** Set the DTR line */ public void setDTR(boolean state) { // there is no way to influence the behavior of the DTR line when opening the serial port // this means that at least on Linux and OS X, Arduino devices are always reset try { port.setDTR(state); } catch (SerialPortException e) { throw new RuntimeException("Error setting the DTR line: " + e.getExceptionType()); } }
/** * @param parity 'N' for none, 'E' for even, 'O' for odd, 'M' for mark, 'S' for space ('N' is the * default) * @param dataBits 8 is the default * @param stopBits 1.0, 1.5, or 2.0 (1.0 is the default) */ public Serial( PApplet parent, String portName, int baudRate, char parity, int dataBits, float stopBits) { this.parent = parent; parent.registerMethod("dispose", this); parent.registerMethod("pre", this); // setup parity if (parity == 'O') { parity = SerialPort.PARITY_ODD; } else if (parity == 'E') { parity = SerialPort.PARITY_EVEN; } else if (parity == 'M') { parity = SerialPort.PARITY_MARK; } else if (parity == 'S') { parity = SerialPort.PARITY_SPACE; } else { parity = SerialPort.PARITY_NONE; } // setup stop bits int stopBitsIdx = SerialPort.STOPBITS_1; if (stopBits == 1.5f) { stopBitsIdx = SerialPort.STOPBITS_1_5; } else if (stopBits == 2) { stopBitsIdx = SerialPort.STOPBITS_2; } port = new SerialPort(portName); try { // the native open() call is not using O_NONBLOCK, so this might block for certain operations // (see write()) port.openPort(); port.setParams(baudRate, dataBits, stopBitsIdx, parity); // we could register more events here port.addEventListener(this, SerialPort.MASK_RXCHAR); } catch (SerialPortException e) { // this used to be a RuntimeException before, so stick with it throw new RuntimeException( "Error opening serial port " + e.getPortName() + ": " + e.getExceptionType()); } serialEventMethod = findCallback("serialEvent"); serialAvailableMethod = findCallback("serialAvailable"); }
/** @param src data to write */ public void write(byte[] src) { try { // this might block if the serial device is not yet ready (esp. tty devices under OS X) port.writeBytes(src); // we used to call flush() here } catch (SerialPortException e) { throw new RuntimeException( "Error writing to serial port " + e.getPortName() + ": " + e.getExceptionType()); } }
public void pre() { if (serialAvailableMethod != null && invokeSerialAvailable) { invokeSerialAvailable = false; try { serialAvailableMethod.invoke(parent, this); } catch (Exception e) { System.err.println("Error, disabling serialAvailable() for " + port.getPortName()); System.err.println(e.getLocalizedMessage()); serialAvailableMethod = null; } } }
/** Return true if this port is still active and hasn't run into any trouble. */ public boolean active() { return port.isOpened(); }