jSSC不向Arduino发送数据

我在编写jSSC函数时遇到问题。 我的Arduino Uno板似乎没有从我的Java程序中获取数据。

我有一个由Arduino Uno板控制的步进电机。 我做了一个简单的程序,有2个按钮。 一个用于CW旋转,另一个用于CCW旋转。 CW按钮发送’H’字符,CCW按钮发送’L’char。 我现在有:

  1. 我从Arduino IDE串口控制台检查了我的Arduino程序是否正常。 当我发送’H’时,电机转为CW,而’L’则电机转为CCW。
  2. 我在Processing中创建了一个程序,其中两个按钮发送’H’和’L’。 有效。
  3. 我用JSSC制作了一个Java程序,两个按钮发送’H’和’L’。 它失败了。 当我按下程序中的一个按钮时,我看到电路板上的“L”灯闪烁3-4次,但没有任何反应。
  4. 我尝试从JSSC获取数据并且它有效。 似乎问题在于写作function。
  5. 我检查了另一个Arduino Uno板但结果是一样的。

我的Java程序使用serialPort.writeByte((byte)'H');serialPort.writeByte((byte)'L');

有任何想法吗?

您是否尝试设置流量控制参数 。 因为在写入界面时,它需要一个权限。

 serialPort.setParams(SerialPort.BAUDRATE_9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE,false,true);//Set params. Also you can set params by this string: serialPort.setParams(9600, 8, 1, 0,RTSEnable,DTSEnable); serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); 

这可能是与重置相关的问题吗? 也许你的java函数使用DTR引脚,它连接到RESET引脚; 因此,当您尝试发送数据时,您只需重置电路板。

如果你想测试你可以在启动时使另一个LED闪烁或在安装时通过串行接口发送一些东西。 如果您收到反馈,请尝试查看禁用DTR的方法;)

如果你不打算在你的java项目中使用它,你可以重构Processing的Serial类(它运行得很好)以避免PApplet:

 /* PSerial - class for serial port goodness Part of the Processing project - http://processing.org Copyright (c) 2004-05 Ben Fry & Casey Reas Reworked by Gottfried Haider as part of GSOC 2013 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 */ import java.lang.reflect.Method; import java.util.Map; import jssc.SerialPort; import jssc.SerialPortEvent; import jssc.SerialPortEventListener; import jssc.SerialPortException; import jssc.SerialPortList; public class Serial implements SerialPortEventListener { Object parent; public SerialPort port; Method serialAvailableMethod; Method serialEventMethod; byte[] buffer = new byte[32768]; int inBuffer = 0; int readOffset = 0; int bufferUntilSize = 1; byte bufferUntilByte = 0; volatile boolean invokeSerialAvailable = false; // Things we are currently not exposing: // * hardware flow control // * state of the RING, RLSD line // * sending breaks public Serial(Object parent) { this(parent, "COM1", 9600, 'N', 8, 1); } public Serial(Object parent, int baudRate) { this(parent, "COM1", baudRate, 'N', 8, 1); } public Serial(Object parent, String portName) { this(parent, portName, 9600, 'N', 8, 1); } public Serial(Object parent, String portName, int baudRate) { this(parent, portName, baudRate, 'N', 8, 1); } public Serial(Object 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"); } private Method findCallback(final String name) { try { return parent.getClass().getMethod(name, this.getClass()); } catch (Exception e) { } // Permit callback(Object) as alternative to callback(Serial). try { return parent.getClass().getMethod(name, Object.class); } catch (Exception e) { } return null; } public void dispose() { stop(); } 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; } } } public int available() { return (inBuffer-readOffset); } public void buffer(int size) { bufferUntilSize = size; } public void bufferUntil(int inByte) { bufferUntilSize = 0; bufferUntilByte = (byte)inByte; } public void clear() { synchronized (buffer) { inBuffer = 0; readOffset = 0; } } public boolean getCTS() { try { return port.isCTS(); } catch (SerialPortException e) { throw new RuntimeException("Error reading the CTS line: " + e.getExceptionType()); } } public boolean getDSR() { try { return port.isDSR(); } catch (SerialPortException e) { throw new RuntimeException("Error reading the DSR line: " + e.getExceptionType()); } } public static Map getProperties(String portName) { return SerialPortList.getPortProperties(portName); } public int last() { if (inBuffer == readOffset) { return -1; } synchronized (buffer) { int ret = buffer[inBuffer-1] & 0xFF; inBuffer = 0; readOffset = 0; return ret; } } public char lastChar() { return (char)last(); } public static String[] list() { // returns list sorted alphabetically, thus cu.* comes before tty.* // this was different with RXTX return SerialPortList.getPortNames(); } public int read() { if (inBuffer == readOffset) { return -1; } synchronized (buffer) { int ret = buffer[readOffset++] & 0xFF; if (inBuffer == readOffset) { inBuffer = 0; readOffset = 0; } return ret; } } public byte[] readBytes() { if (inBuffer == readOffset) { return null; } synchronized (buffer) { byte[] ret = new byte[inBuffer-readOffset]; System.arraycopy(buffer, readOffset, ret, 0, ret.length); inBuffer = 0; readOffset = 0; return ret; } } public int readBytes(byte[] dest) { if (inBuffer == readOffset) { return 0; } synchronized (buffer) { int toCopy = inBuffer-readOffset; if (dest.length < toCopy) { toCopy = dest.length; } System.arraycopy(buffer, readOffset, dest, 0, toCopy); readOffset += toCopy; if (inBuffer == readOffset) { inBuffer = 0; readOffset = 0; } return toCopy; } } public byte[] readBytesUntil(int inByte) { if (inBuffer == readOffset) { return null; } synchronized (buffer) { // look for needle in buffer int found = -1; for (int i=readOffset; i < inBuffer; i++) { if (buffer[i] == (byte)inByte) { found = i; break; } } if (found == -1) { return null; } int toCopy = found-readOffset+1; byte[] dest = new byte[toCopy]; System.arraycopy(buffer, readOffset, dest, 0, toCopy); readOffset += toCopy; if (inBuffer == readOffset) { inBuffer = 0; readOffset = 0; } return dest; } } public int readBytesUntil(int inByte, byte[] dest) { if (inBuffer == readOffset) { return 0; } synchronized (buffer) { // look for needle in buffer int found = -1; for (int i=readOffset; i < inBuffer; i++) { if (buffer[i] == (byte)inByte) { found = i; break; } } if (found == -1) { return 0; } // check if bytes to copy fit in dest int toCopy = found-readOffset+1; if (dest.length < toCopy) { System.err.println( "The buffer passed to readBytesUntil() is to small " + "to contain " + toCopy + " bytes up to and including " + "char " + (byte)inByte); return -1; } System.arraycopy(buffer, readOffset, dest, 0, toCopy); readOffset += toCopy; if (inBuffer == readOffset) { inBuffer = 0; readOffset = 0; } return toCopy; } } public char readChar() { return (char) read(); } public String readString() { if (inBuffer == readOffset) { return null; } return new String(readBytes()); } public String readStringUntil(int inByte) { byte temp[] = readBytesUntil(inByte); if (temp == null) { return null; } else { return new String(temp); } } 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()); } } } 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()); } } public void setRTS(boolean state) { try { port.setRTS(state); } catch (SerialPortException e) { throw new RuntimeException("Error setting the RTS line: " + e.getExceptionType()); } } public void stop() { try { port.closePort(); } catch (SerialPortException e) { // ignored } inBuffer = 0; readOffset = 0; } 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 write(int src) { try { port.writeInt(src); } catch (SerialPortException e) { throw new RuntimeException("Error writing to serial port " + e.getPortName() + ": " + e.getExceptionType()); } } public void write(String src) { try { port.writeString(src); } catch (SerialPortException e) { throw new RuntimeException("Error writing to serial port " + e.getPortName() + ": " + e.getExceptionType()); } } } 

这是使用上面的示例类:

 public class SerialTest { public static void main(String[] args) { try{ Serial serial = new Serial(new SerialTest(),"/dev/tty.usbmodemfd121",115200); serial.write("H"); serial.write("L");//can also try serial.write((int)'L'); }catch(Exception e){ System.err.println("serial not connected!"); } } public void serialAvailable(Serial s){ System.out.println(s.toString()); } public void serialEvent(Serial s){ System.out.print("from serial:"); System.out.println(s.read()); } } 

请务必将端口和波特率更改为Arduino Uno正在使用的内容。

在Processing的串行库文件夹中,您还可以找到JNI本机库。 例如在Windows上:

 C:\Program Files\processing-2.1.2\modes\java\libraries\serial\library 

dll将驻留在windows32和windows64文件夹中的位置,具体取决于您计划使用的内容。 上面的Serial类与C:\Program Files\processing-2.1.2\modes\java\libraries\serial\src\processing\serial/Serial.java几乎相同,用Object替换PApplet。

此外,这是Processing Serial库参考