com.fazecast
diff --git a/src/main/java/org/firmata4j/firmata/FirmataMessageFactory.java b/src/main/java/org/firmata4j/firmata/FirmataMessageFactory.java
index f91cdcb..6effc35 100644
--- a/src/main/java/org/firmata4j/firmata/FirmataMessageFactory.java
+++ b/src/main/java/org/firmata4j/firmata/FirmataMessageFactory.java
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
- * Copyright (c) 2014 Oleg Kurbatov (o.v.kurbatov@gmail.com)
+ * Copyright (c) 2014-2021 Oleg Kurbatov (o.v.kurbatov@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -212,9 +212,9 @@ public static byte[] setMode(byte pinId, Pin.Mode mode) {
}
/**
- * Creates Firmata message to set digital values of port's pins.
+ * Creates Firmata message to set digital values of port's pins.
* Digital value should be assigned to a set of pins at once. A set of pins
- * is called port.
+ * is called port.
* A port contains 8 pins. Digital value of every pin in a set transfers in
* one byte. Every bit in the byte represents state of pin's output.
*
@@ -222,12 +222,23 @@ public static byte[] setMode(byte pinId, Pin.Mode mode) {
* @param value values of port's pins
* @return Firmata message to set digital output
*/
- public static byte[] setDigitalPinValue(byte portId, byte value) {
+ public static byte[] setDigitalPortValue(byte portId, byte value) {
return new byte[]{(byte) (DIGITAL_MESSAGE | (portId & 0x0F)), (byte) (value & 0x7F), (byte) ((value >>> 7) & 0x7F)};
}
+
+ /**
+ * Creates Firmata message to set digital values of a pin.
+ *
+ * @param pinId index of a pin
+ * @param value value of the pin (0 or 1)
+ * @return Firmata message to set the value of a digital output pin
+ */
+ public static byte[] setDigitalPinValue(byte pinId, byte value) {
+ return new byte[]{SET_DIGITAL_PIN_VALUE, pinId, value};
+ }
/**
- * Creates Firmata message to set value of an output pin in PWM mode.
+ * Creates Firmata message to set value of an output pin in PWM mode.
* If pin id is beyond 15th or value is greater than we can put into
* standard analog message, extended analog message is built.
*
@@ -255,7 +266,7 @@ public static byte[] setAnalogPinValue(byte pinId, long value) {
}
/**
- * Creates a message to set sampling interval.
+ * Creates a message to set sampling interval.
* The sampling interval sets how often analog data and i2c data is reported
* to the client. The default value is 19 milliseconds.
*
@@ -272,7 +283,7 @@ public static byte[] setSamplingInterval(int value) {
}
/**
- * Builds servo configuration message.
+ * Builds servo configuration message.
* The core idea is to just add a "config" message, then use
* {@link #setMode(byte, org.firmata4j.Pin.Mode)} to attach/detach Servo
* support to a pin. Then the normal {@link #setAnalogPinValue(byte, long)}
diff --git a/src/main/java/org/firmata4j/firmata/FirmataPin.java b/src/main/java/org/firmata4j/firmata/FirmataPin.java
index 4bf2f9b..2bfeac0 100644
--- a/src/main/java/org/firmata4j/firmata/FirmataPin.java
+++ b/src/main/java/org/firmata4j/firmata/FirmataPin.java
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
- * Copyright (c) 2014 Oleg Kurbatov (o.v.kurbatov@gmail.com)
+ * Copyright (c) 2014-2021 Oleg Kurbatov (o.v.kurbatov@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -132,28 +132,11 @@ public synchronized void setValue(long value) throws IOException, IllegalStateEx
byte[] message;
long newValue;
if (currentMode == Mode.OUTPUT) {
- //have to calculate the value of whole port (8-pin set) the pin sits in
- byte portId = (byte) (pinId / 8);
- byte pinInPort = (byte) (pinId % 8);
- byte portValue = 0;
- for (int i = 0; i < 8; i++) {
- Pin p = device.getPin(portId * 8 + i);
- if (p.getMode() == Mode.OUTPUT && p.getValue() > 0) {
- portValue |= 1 << i;
- }
- }
- byte bitmask = (byte) (1 << pinInPort);
- boolean val = value > 0;
- if (val) {
- portValue |= bitmask;
- } else {
- portValue &= ((byte) ~bitmask);
- }
- message = FirmataMessageFactory.setDigitalPinValue(portId, portValue);
- newValue = val ? 1 : 0;
+ newValue = value > 0 ? 1 : 0;
+ message = FirmataMessageFactory.setDigitalPortValue(pinId, (byte) newValue);
} else if (currentMode == Mode.ANALOG || currentMode == Mode.PWM || currentMode == Mode.SERVO) {
- message = FirmataMessageFactory.setAnalogPinValue(pinId, value);
newValue = value;
+ message = FirmataMessageFactory.setAnalogPinValue(pinId, newValue);
} else {
throw new IllegalStateException(String.format("Port %d is in %s mode and its value cannot be set.", pinId, currentMode));
}
diff --git a/src/main/java/org/firmata4j/transport/JSSCTransport.java b/src/main/java/org/firmata4j/transport/JSSCTransport.java
new file mode 100644
index 0000000..7be9d2e
--- /dev/null
+++ b/src/main/java/org/firmata4j/transport/JSSCTransport.java
@@ -0,0 +1,106 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2021 Oleg Kurbatov (o.v.kurbatov@gmail.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package org.firmata4j.transport;
+
+import java.io.IOException;
+import jssc.SerialPort;
+import jssc.SerialPortEvent;
+import jssc.SerialPortEventListener;
+import jssc.SerialPortException;
+import org.firmata4j.Parser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Transfers data via serial port using jssc library.
+ *
+ * @author Ali Kia
+ */
+public class JSSCTransport implements TransportInterface, SerialPortEventListener {
+ private Parser parser;
+
+ private final SerialPort port;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JSSCTransport.class);
+
+ public JSSCTransport(String portName) {
+ this.port = new SerialPort(portName);
+ }
+
+ @Override
+ public void start() throws IOException {
+ if (!port.isOpened()) {
+ try {
+ port.openPort();
+ port.setParams(
+ SerialPort.BAUDRATE_57600,
+ SerialPort.DATABITS_8,
+ SerialPort.STOPBITS_1,
+ SerialPort.PARITY_NONE);
+ port.setEventsMask(SerialPort.MASK_RXCHAR);
+ port.addEventListener(this);
+ } catch (SerialPortException ex) {
+ throw new IOException("Cannot start firmata device", ex);
+ }
+ }
+ }
+
+ @Override
+ public void stop() throws IOException {
+ try {
+ if (port.isOpened()) {
+ port.purgePort(SerialPort.PURGE_RXCLEAR | SerialPort.PURGE_TXCLEAR);
+ port.closePort();
+ }
+ } catch (SerialPortException ex) {
+ throw new IOException("Cannot properly stop firmata device", ex);
+ }
+ }
+
+ @Override
+ public void write(byte[] bytes) throws IOException {
+ try {
+ port.writeBytes(bytes);
+ } catch (SerialPortException ex) {
+ throw new IOException("Cannot send message to device", ex);
+ }
+ }
+
+ @Override
+ public void setParser(Parser parser) {
+ this.parser = parser;
+ }
+
+ @Override
+ public void serialEvent(SerialPortEvent event) {
+ // queueing data from input buffer to processing by FSM logic
+ if (event.isRXCHAR() && event.getEventValue() > 0) {
+ try {
+ parser.parse(port.readBytes());
+ } catch (SerialPortException ex) {
+ LOGGER.error("Cannot read from device", ex);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/firmata4j/transport/JSerialCommTransport.java b/src/main/java/org/firmata4j/transport/JSerialCommTransport.java
index b32b288..a991009 100644
--- a/src/main/java/org/firmata4j/transport/JSerialCommTransport.java
+++ b/src/main/java/org/firmata4j/transport/JSerialCommTransport.java
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
- * Copyright (c) 2014-2019 Oleg Kurbatov (o.v.kurbatov@gmail.com)
+ * Copyright (c) 2014-2021 Oleg Kurbatov (o.v.kurbatov@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -33,71 +33,57 @@
/**
* Implementation of {@link TransportInterface} based on {@link SerialPort}.
- *
+ *
* @author Norbert Sándor
*/
-public class JSerialCommTransport implements TransportInterface
-{
+public class JSerialCommTransport implements TransportInterface {
+
private final SerialPort serialPort;
private Parser parser;
- public JSerialCommTransport(String portDescriptor)
- {
+ public JSerialCommTransport(String portDescriptor) {
serialPort = SerialPort.getCommPort(portDescriptor);
}
@Override
- public void start() throws IOException
- {
- if (!serialPort.isOpen())
- {
- if (serialPort.openPort())
- {
- serialPort.setComPortParameters(jssc.SerialPort.BAUDRATE_57600, jssc.SerialPort.DATABITS_8,
- SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
- serialPort.addDataListener(new SerialPortDataListener()
- {
+ public void start() throws IOException {
+ if (!serialPort.isOpen()) {
+ if (serialPort.openPort()) {
+ serialPort.setComPortParameters(57600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
+ serialPort.addDataListener(new SerialPortDataListener() {
@Override
- public void serialEvent(SerialPortEvent event)
- {
- if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_RECEIVED)
- {
+ public void serialEvent(SerialPortEvent event) {
+ if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_RECEIVED) {
parser.parse(event.getReceivedData());
}
}
@Override
- public int getListeningEvents()
- {
+ public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
}
});
- } else
- {
+ } else {
throw new IOException("Cannot start firmata device: port=" + serialPort);
}
}
}
@Override
- public void stop() throws IOException
- {
- if (serialPort.isOpen() && !serialPort.closePort())
- {
+ public void stop() throws IOException {
+ if (serialPort.isOpen() && !serialPort.closePort()) {
throw new IOException("Cannot properly stop firmata device: port=" + serialPort);
}
}
@Override
- public void write(byte[] bytes) throws IOException
- {
+ public void write(byte[] bytes) throws IOException {
serialPort.writeBytes(bytes, bytes.length);
}
@Override
- public void setParser(Parser parser)
- {
+ public void setParser(Parser parser) {
this.parser = parser;
}
}
diff --git a/src/main/java/org/firmata4j/transport/SerialTransport.java b/src/main/java/org/firmata4j/transport/SerialTransport.java
index c764b19..86133d3 100644
--- a/src/main/java/org/firmata4j/transport/SerialTransport.java
+++ b/src/main/java/org/firmata4j/transport/SerialTransport.java
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
- * Copyright (c) 2014-2018 Oleg Kurbatov (o.v.kurbatov@gmail.com)
+ * Copyright (c) 2014-2021 Oleg Kurbatov (o.v.kurbatov@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,86 +23,75 @@
*/
package org.firmata4j.transport;
-import jssc.SerialPort;
-import jssc.SerialPortEvent;
-import jssc.SerialPortEventListener;
-import jssc.SerialPortException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import org.firmata4j.Parser;
/**
- * Allows connections over the serial interface.
+ * Transfers data over the serial interface.
+ *
+ * Using an instance of this transport requires one of the following libraries
+ * present in the classpath:
+ *
+ *
+ * <dependency>
+ <groupId>com.fazecast</groupId>
+ <artifactId>jSerialComm</artifactId>
+ <version>2.6.2</version>
+ </dependency>
+ * <dependency>
+ <groupId>org.scream3r</groupId>
+ <artifactId>jssc</artifactId>
+ <version>2.8.0</version>
+ </dependency>
+ *
*
- * @author Ali Kia
+ * @author Oleg Kurbatov <o.v.kurbatov@gmail.com>
*/
-public class SerialTransport implements TransportInterface, SerialPortEventListener {
+public class SerialTransport implements TransportInterface {
- private Parser parser;
-
- private final SerialPort port;
+ private TransportInterface delegate;
private static final Logger LOGGER = LoggerFactory.getLogger(SerialTransport.class);
public SerialTransport(String portName) {
- this.port = new SerialPort(portName);
+ try {
+ Class.forName("com.fazecast.jSerialComm.SerialPort", false, this.getClass().getClassLoader());
+ delegate = new JSerialCommTransport(portName);
+ LOGGER.debug("Using jSerialComm transport");
+ } catch (ClassNotFoundException e) {
+ try {
+ Class.forName("jssc.SerialPort", false, this.getClass().getClassLoader());
+ delegate = new JSerialCommTransport(portName);
+ LOGGER.debug("Using jssc transport");
+ } catch (ClassNotFoundException ex) {
+ throw new IllegalStateException(
+ "Serial communication library is not found in the classpath. "
+ + "Please make sure that there is at least one dependency "
+ + "as described in the javadoc of org.firmata4j.transport.SerialTransport");
+ }
+ }
}
@Override
public void start() throws IOException {
- if (!port.isOpened()) {
- try {
- port.openPort();
- port.setParams(
- SerialPort.BAUDRATE_57600,
- SerialPort.DATABITS_8,
- SerialPort.STOPBITS_1,
- SerialPort.PARITY_NONE);
- port.setEventsMask(SerialPort.MASK_RXCHAR);
- port.addEventListener(this);
- } catch (SerialPortException ex) {
- throw new IOException("Cannot start firmata device", ex);
- }
- }
+ delegate.start();
}
@Override
public void stop() throws IOException {
- try {
- if (port.isOpened()) {
- port.purgePort(SerialPort.PURGE_RXCLEAR | SerialPort.PURGE_TXCLEAR);
- port.closePort();
- }
- } catch (SerialPortException ex) {
- throw new IOException("Cannot properly stop firmata device", ex);
- }
+ delegate.stop();
}
@Override
public void write(byte[] bytes) throws IOException {
- try {
- port.writeBytes(bytes);
- } catch (SerialPortException ex) {
- throw new IOException("Cannot send message to device", ex);
- }
+ delegate.write(bytes);
}
@Override
public void setParser(Parser parser) {
- this.parser = parser;
- }
-
- @Override
- public void serialEvent(SerialPortEvent event) {
- // queueing data from input buffer to processing by FSM logic
- if (event.isRXCHAR() && event.getEventValue() > 0) {
- try {
- parser.parse(port.readBytes());
- } catch (SerialPortException ex) {
- LOGGER.error("Cannot read from device", ex);
- }
- }
+ delegate.setParser(parser);
}
}