Работаем с COM-портом из Java при помощи jSSC

Уж много воды утекло с тех пор, как мы пользовались мышами на com-у, модемами, играли «по нему» в игры за неимением сети, перекидывали файлики и …, чего только мы с ним не делали.

Всё, на дворе 21 век, USB 3.0 подмял по себя всё и вся, com-ы вымерли и теперь «новорожденные» программисты смотрят на этот разъём с недоумением и укоризной. Но, умерли не все, кое-кто всё-таки остался… Эти бравые парни шлют байты по трём проводам и с со снисходительной улыбкой смотрят на «новорожденных». И о том, чем эти парни пользуются выполняя свою работу я и хочу поведать в этой небольшой статье. Речь в ней пойдёт о маленькой библиотечке по имени jSSC.

Судя по тому, как люди на Хабре отзываются о com-е видимо многие действительно считают что он уже не нужен и не понимают зачем кто-то до сих пор его использует, зачем пишут библиотеки и софт, производят оборудование с этим портом на борту. От себя могу сказать лишь одно, дабы не разводить холивар, как мне кажется, он пропал лишь для домашнего использования, а на производствах и в различных лабораториях он есть и чувствует себя просто отлично. На то есть много причин, но основная как мне кажется это простота и удобство в работе.

Но разговор сейчас не о том, так что не будем отвлекаться. Итак, jSSC это Java библиотека для простой работы с COM-портом (Java Simple Serial Connector). Своё официальное, публичное начало она берёт в 2010 году. Именно тогда было решено поделиться ей с разработчиками на Java (распространяется под лицензией LGPL). К написанию библиотеки привёл печальный факт – отсутствие адекватных инструментов для работы с этим портом. Многие скажут, и уже говорили, мол есть javax.comm, rxtx ну и ещё есть giovynet (но его нельзя серьёзно рассматривать ни при каких обстоятельствах), но к сожалению не всё так просто. Нашей основной ОС является Windows, и использовать javax.comm 3.0 не получится, rxtx-же не подошёл из-за своей нестабильности. В результате делать было нечего, пришлось писать свою библиотеку.

Во главу угла при разработке была поставлена простота использования, ведь каждый день приходится работать с оборудованием, и хочется, чтобы работа доставляла удовольствие. Но пусть это вас не вводит в заблуждение, простота это не серебряная пуля и не кнопка «сделать пи*дато», нужно понимать чего вы хотите получить от устройства, как оно работает и как вообще происходит взаимодействие устройств по com-у. При разработке больший уклон был сделан в сторону Windows стиля разработки под com-порт, в основном это выражается в именовании констант для установки маски ивентов, режима управления потоком, разбора ошибок и т.д.

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

Теперь можно набросать небольшой пример. Предположим, что у нас есть какой-то прибор, который использует аппаратное управление потоком, и мы хотим получать от него ответы на запросы. Вот пример реализации:

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

public class Test {

    private static SerialPort serialPort;

    public static void main(String[] args) {
        //Передаём в конструктор имя порта
        serialPort = new SerialPort("COM1");
        try {
            //Открываем порт
            serialPort.openPort();
            //Выставляем параметры
            serialPort.setParams(SerialPort.BAUDRATE_9600,
                                 SerialPort.DATABITS_8,
                                 SerialPort.STOPBITS_1,
                                 SerialPort.PARITY_NONE);
            //Включаем аппаратное управление потоком
            serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | 
                                          SerialPort.FLOWCONTROL_RTSCTS_OUT);
            //Устанавливаем ивент лисенер и маску
            serialPort.addEventListener(new PortReader(), SerialPort.MASK_RXCHAR);
            //Отправляем запрос устройству
            serialPort.writeString("Get data");
        }
        catch (SerialPortException ex) {
            System.out.println(ex);
        }
    }

    private static class PortReader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            if(event.isRXCHAR() && event.getEventValue() > 0){
                try {
                    //Получаем ответ от устройства, обрабатываем данные и т.д.
                    String data = serialPort.readString(event.getEventValue());
                    //И снова отправляем запрос
                    serialPort.writeString("Get data");
                }
                catch (SerialPortException ex) {
                    System.out.println(ex);
                }
            }
        }
    }
}


По-моему всё довольно просто. Помимо операций чтения/записи jSSC предоставляет следующий ряд возможностей:
  • Управление линиями RTS, DTR
  • Получение статуса линий CTS, DSR, RING, RLSD
  • Получение количества байт в буферах
  • Очистка буферов порта
  • Отправка сигнала Break
  • Управление потоком
  • Получение списка com-портов в системе

Здесь стоит отметить один важный момент: адаптеры USB->COM могут иногда вести себя не так, как вы того ожидаете, это понятное дело зависит от их драйвера, так что если вы собираетесь использовать такие адаптеры хорошенько протестируйте их работу в Linux и Windows, если конечно вам нужна поддержка разных ОС.

Спустя год после публикации jSSC было немало писем от разработчиков и фирм, и область применения оказалась довольно обширна. Вот небольшой список:
  • Irda управление для HTPC (проект одной фирмы из США)
  • Тюнинг Mitsubishi Eclipse (привет туда же – в США)
  • Серверное ПО в центре сетевых технологий (Польша)
  • Система взвешивания посылок (на сколько я понял) для какой-то службы доставки (для этих ребят я писал мостик из Java в JavaScript и они вознаградили мои труды прислав 100 USD, кстати тоже США)
  • Различные учебные проекты (Индия, Россия и может быть ещё кто-то)
  • и т.д.

Ну и отдельный привет передаю ребятам из Индии, для которых делал версию jSSC-CE (Windows CE). Если мне не изменяет память они заказали какое-то оборудование на WinCE не проверив а есть-ли под неё JVM от SUN/Oracle, и были очень удивлены когда узнали что её нет. Я для разработки использовал тогда CreMe JVM, ну надеюсь что у них всё получилось.

Ну что же, разрешите откланяться, прошу прощения за немного сумбурное повествование, и надеюсь, что кому-то из вас jSSC поможет в работе. Буду рад ответить на ваши вопросы.

А вот и ссылка на страницу проекта: http://code.google.com/p/java-simple-serial-connector
Поделиться публикацией
Комментарии 15
    0
    Да не факт что вымерли, к примеру сканеры штрих кодов хоть используют USB, в систему отдают виртуальный COM порт, либо работают как клавиатура.
      0
      Я знаю, и таких устройств довольно много. В данном случае я говорил о том что таких устройств для домашнего «употребления» мало и многие не знают что в этих устройствах грубо скажем встроен адаптер USB->COM, и от того довольно часто видишь высказывания о том что com — пережиток прошлого.
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          3G модема.Там тоже по последовательному интерфейсу идет обмен данными между ПК и модемом.
      +2
      Ещё как не вымерли, во многом спец.оборудовании живёт и здравствует. Так что тема актуальная, так как javax.comm уж совсем плох. В итоге используется у нас rxtx, в целом доволен, но есть проблема с поддержкой специфических систем, в том числе 64-битных. Плюс есть недоработки, которые напрягают слегка, пару раз приходилось дописывать, в т.ч. нативную часть.

      С адаптерами usb-com вообще песня отдельная, натерпелся я от них сполна, они почти всегда работают ну очень плохо, причём плохо работают совсем незаметно от библиотеки, т.е. понять, что идут битые байты совершенно невозможно. Причём программа нативная читает-пишет нормально (гляжу сниффером), совершенно то же самое пишу-читаю через rxtx — идёт битое. Во всех этих проблемах до конца так и не разобрался, ну и тем более все низкоуровневые параметры порта (таймауты некоторые, например) поставить там не получается. Интересно как с этими делами у вас, обязательно попробую. А то я уже от отчаяния написал совсем тонкую прослойку уровня «читать писать», но это тоже не дело.
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          USB-COM вы зря ругаете, это я вам как специалист по электронике говорю, если вы использовали не китайские адаптеры но все должно быть хорошо, микросхема FT232 которая считается эталоном качества(высокие скорости работы до 2 MBaud/С)

          Если у вас с ней буду проблемы то сир я съем свою шляпу. А если вы используете барахло то не жалуйтесь что с ним проблема.
            0
            Дело в том, что мы ничего не используем, мы софт пишем) Тот, что есть у меня работает нормально, кстати. Проблемы получаются, соответственно, когда клиенты используют плохие(?) переходники или дрова под них или настраивают их как-то не так, непонятно. Клиентов достаточно много, следовательно, проблемы возникают регулярно. Если происходит видимая беда с обменом с железками в 99% случаев оказывается, что работает через переходник. Отсюда и заключается моё мнение соответствующее, в общем случае я не прав, конечно. Просто за тем, какое «барахло» собрались использовать клиенты мы в таких мелочах проследить не можем, но почти всегда решается сменами переходников, перестановкой дров итд итп. Дело усложняется тем, что некоторые из них работают плохо, например, только в линуксе или фряхе или ещё где-то настроить невозможно, а поддержка всех систем обязательна. Так что как и что универсально порекомендовать тоже не очень понятно. Но вы правы, да, обязательно напишу в документацию предупреждение о проблемах с плохими переходниками.
              0
              Как дополнительный бизнес фирме можете продавать фирменные переходники.
          +2
          Эх, воткнутые проводочки с кучей скруток, 2->3 3->2 5->5 (DB-9), первая квака по нуль-модему, ностальгия…
            0
            Мне удавалось линк на 20 метров между двумя ПК через него завести, всего по 3-м проводам. Правда, 33600 всего было.
            0
            за последние полгода 3 типа весового обрудование коннектил для получения веса через com-порт
              0
              Не вымерли. Последних лет 5 постоянно работаю с Serial портами. Правда, у меня это больше RS-485.
              Но как правило с RS-232, если не требуется работа с линиями RTS, DTR, CTS, DSR, RING, RLSD, то работу с портом можно свести в работе с сокетом. Таких случаев большинство. В таком случае можно воспользоваться и преобразователем RS<->IP и абстрагироваться от COM порта совсем, а работать с TCP сервером.
                0
                Пожалуйста если кто может помогите. Когда использую библиотеку jssc выдает ошибку
                Exception in thread «EventThread COM4» java.lang.NullPointerException
                at TJFrame$REDPORTCOM$SerialPortReader.serialEvent(TJFrame.java:81)
                at jssc.SerialPort$EventThread.run(SerialPort.java:1112). Я новичок в программирование.Среда разработки NetBeans 8.1. Точно знаю, что данные отправляются так как срабатывает PortReader implements SerialPortEventListener. А на этой строке String data = serialPort.readString(event.getEventValue()) выдает ошибку.
                  0
                  Ubuntu 16 появилась ошибка:
                  Port name - /dev/ttyS0; Method name - openPort(); Exception type - Port busy.

                  Пользователь входит в группу dialout, другими инструментами порт открывается без проблем. В том числе, работает с библиотекой rxtx.
                  Причем, после исключения порт заблокирован и не доступен другим программам, но и не открыт в jssc.
                  От рута все работает без проблем.

                  Код не менялся и не пересобирался пару лет, ошибка вылезла недавно. Видимо, после обновлений убунты.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое