jSSC — Работаем с COM-портом из Java на Raspberry Pi, Orange Pi, Banana Pi и тп

jSSC (Java Simple Serial Connector) — библиотека для работы с последовательными (COM) портами ПК. Библиотека создавалась как простая и надёжная замена уже имеющимся средствам. Своё официальное, публичное начало она берёт в 2010 году и распространяется под лицензией LGPL.

С помощью jSSC можно получать имена портов, читать и писать данные, получать ивенты о произошедших событиях ну и т.д. В отличии от javax.comm, с jSSC можно управлять линиями RTS и DTR. Библиотека разрабатывалась для работы в режиме 24/7 в многопоточных системах и на данный момент успешно используется в системах автоматизации, сбора и регистрации данных.

Библиотеку можно использовать на таких платформах, как:

  • Windows x86 и x64;
  • Linux x86, x64, armhf и armsf (т.е. Raspberry Pi, Orange Pi, Banana Pi, NanoPi и тп);
  • Solaris x86 и x64;
  • Mac OS X ppc, ppc64, x86 и x64.

jSSC можно разделить на несколько основных частей:

  • SerialNativeInterface – класс, который предоставляет доступ ко всем «нативным» методам jSSC.
  • SerialPort – класс, с помощью которого мы уже будем непосредственно работать с нужным нам портом.
  • SerialPortEventListener – интерфейс, который необходимо реализовать, если мы хотим использовать ивенты.

jSSC предоставляет следующий ряд возможностей:

  • Чтение и запись данных;
  • Управление линиями RTS, DTR;
  • Получение статуса линий CTS, DSR, RING, RLSD;
  • Получение количества байт в буферах;
  • Очистка буферов порта;
  • Отправка сигнала Break;
  • Управление потоком;
  • Получение списка com-портов в системе;

Где скачать jSSC

Последнюю версию скачать можно тут, на этой странице можно найти и исходный код. На данный момент доступна версия 2.8.0: jSSC-2.8.0-Release.zip, в архиве вы найдёте файл jssc.jar, его и добавьте в свои проекты. Если вам удобнее работать в Maven, тогда можете добавить следующую зависимость:

<!-- https://mvnrepository.com/artifact/org.scream3r/jssc -->
<dependency>
    <groupId>org.scream3r</groupId>
    <artifactId>jssc</artifactId>
    <version>2.8.0</version>
</dependency>

Примеры программ с jSSC

Получение имён последовательных портов

Получить список последовательных портов очень просто с помощью метода getPortNames(). Метод возвращает массив отсортированы строк.

import jssc.SerialPortList;

public class SerialPortListExample {
  public static void main(String[] args) {
    String[] portNames = SerialPortList.getPortNames();
    for (String portName : portNames) {
      System.out.println(portName);
    }
  }
}

Проверяем код:

  1. создаём java файл и вставляем код:
    nano SerialPortListExample.java
  2. компилируем файл:
    javac -classpath .:classes:jssc.jar SerialPortListExample.java
  3. запускаем программу:
    java -classpath .:classes:jssc.jar SerialPortListExample

Результат

Примеры программ с jSSC - Получение имён последовательных портов Orange Pi PC (Результат)

Запись строки

Записывать данные в последовательный порт можно при помощи следующих методов:

  • writeByte — Запись одного байта в порт;
    public boolean writeByte(byte singleByte)
  • writeBytes — Запись массива байтов в порт;
    public boolean writeBytes(byte[] buffer)
  • writeInt — Запись INT значение (в диапазоне от 0 до 255 (0x00 — 0xFF)) в порт;
    public boolean writeInt(int singleInt)
  • writeIntArray — Запись массива int (в диапазоне от 0 до 255 (0x00 — 0xFF)) в порт;
    public boolean writeIntArray(int[] buffer)
  • writeString — Запись строки в порт;
    public boolean writeString(String string)
    public boolean writeString(String string, String charsetName)

Ниже приведённый пример кода будет запускаться на Windows 10 x64 и будет передавать привет Orange Pi PC, который и будет принимать приветы.

import java.io.UnsupportedEncodingException;
import jssc.SerialPort;
import jssc.SerialPortException;

public class SerialTxExample {

  public static void main(String[] args) {
    /*
     * Передаём в конструктор имя порта
     */
    SerialPort serialPort = new SerialPort("COM13");
    try {
      /*
       * Открываем порт
       */
      serialPort.openPort();
      /*
       * Выставляем параметры
       */
      serialPort.setParams(SerialPort.BAUDRATE_9600,
          SerialPort.DATABITS_8,
          SerialPort.STOPBITS_1,
          SerialPort.PARITY_NONE);
      /*
       * Передаём привет
       */
      serialPort.writeString("Привет", "UTF-8");
    } catch (SerialPortException ex) {
      ex.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
  }
}

Чтение данных с использованием интерфейса SerialPortEventListener

Чтение данных из последовательного порта можно при помощи следующих методов:

public byte[] readBytes()
public byte[] readBytes(int byteCount)
public byte[] readBytes(int byteCount, int timeout)
public String readHexString()
public String readHexString(int byteCount)
public String readHexString(int byteCount, int timeout)
public String readHexString(int byteCount, String separator)
public String readHexString(int byteCount, String separator, int timeout)
public String readHexString(String separator)
public String[] readHexStringArray()
public String[] readHexStringArray(int byteCount)
public String[] readHexStringArray(int byteCount, int timeout)
public int[] readIntArray()
public int[] readIntArray(int byteCount)
public int[] readIntArray(int byteCount, int timeout)
public String readString()
public String readString(int byteCount)
public String readString(int byteCount, int timeout)

Ниже приведённый пример кода будет запускаться на Orange Pi PC и принимать приветы, отправленные через последовательный порт. Все сообщения будут выводиться в терминал.

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;

public class SerialPorRxTxSerialPortEventListenerExample {

  public static void main(String[] args) {
    /*
     * Передаём в конструктор имя порта
     */
    SerialPort serialPort = new SerialPort("/dev/ttyS1");
    try {
      /*
       * Открываем порт
       */
      serialPort.openPort();
      /*
       * Выставляем параметры
       */
      serialPort.setParams(SerialPort.BAUDRATE_9600,
          SerialPort.DATABITS_8,
          SerialPort.STOPBITS_1,
          SerialPort.PARITY_NONE);
      /*
       * Готовим маску, на основании неё мы будем получать сообщения о событиях,
       * которые произошли. Ну например, нам необходимо знать что пришли
       * какие-то данные, т.о. в маске должна присутствовать следующая величина:
       * MASK_RXCHAR. Если нам, например, ещё нужно знать об изменении состояния
       * линий CTS и DSR, то маска уже будет выглядеть так:
       * SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR
       */
      int mask = SerialPort.MASK_RXCHAR;
      /*
       * Выставляем подготовленную маску
       */
      serialPort.setEventsMask(mask);
      /*
       * Добавляем собственно интерфейс через который мы и будем узнавать о
       * нужных нам событиях
       */
      serialPort.addEventListener(new SerialPortReader(serialPort));
    } catch (SerialPortException ex) {
      ex.printStackTrace();
    }
  }

  static class SerialPortReader implements SerialPortEventListener {

    private SerialPort serialPort;

    public SerialPortReader(SerialPort serialPort) {
      this.serialPort = serialPort;
    }

    public void serialEvent(SerialPortEvent event) {
      /*
       * Объект типа SerialPortEvent несёт в себе информацию о том какое событие
       * произошло и значение. Так например если пришли данные то метод
       * event.getEventValue() вернёт нам количество байт во входном буфере.
       */
      if (event.isRXCHAR()) {
        if (event.getEventValue() > 0) {
          try {
            String buffer = serialPort.readString();
            System.out.println(buffer);
          } catch (SerialPortException ex) {
            ex.printStackTrace();
          }
        }
      } else if (event.isCTS()) {
        /*
         * Если изменилось состояние линии CTS, то метод event.getEventValue()
         * вернёт 1 если линия включения и 0 если выключена.
         */
        if (event.getEventValue() == 1) {
          System.out.println("CTS - ON");
        } else {
          System.out.println("CTS - OFF");
        }
      } else if (event.isDSR()) {
        if (event.getEventValue() == 1) {
          System.out.println("DSR - ON");
        } else {
          System.out.println("DSR - OFF");
        }
      }
    }
  }
}

Проверяем код:

  1. создаём java файл и вставляем код:
    nano SerialExample.java
  2. компилируем файл:
    javac -classpath .:classes:jssc.jar SerialExample.java
  3. запускаем программу:
    java -classpath .:classes:jssc.jar SerialExample

Результат

jSSC - чтение данных с использованием интерфейса SerialPortEventListener (Результат)

Материалы

java-simple-serial-connector
Releases · scream3r/java-simple-serial-connector · GitHub
Работаем с COM-портом из Java при помощи jSSC / Хабр
Maven Repository: org.scream3r » jssc

Похожие записи

Комментарии 158

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *