четвер, 11 жовтня 2012 р.

Робота з COM-портом на Java

Для робот з портами Java в JDK немає стандартного пакету. Тому необхідно встановити додаткову бібліотеку для роботи з послідовними та паралельними портами. Послідовний (COM-порт) доволі поширений в даний час, багато апаратного обладнання працює на ньому. Навіть в сучасному він використовується доволі часто. Сучасні прилади підключаються до USB, проте в багатьох використовується перехідник USB-COM, що дозволяють розробникам програмного забезпечення працювати з приладом через добре знайомий і легкий інтерфейс RS232 (COM).

Тож, що нам потрібно? Існує декілька java бібліотек для роботи з COM-портом , які побудовані з використанням Native-методів. Свого часу була популярна javax.Comm, її можна використовувати до цих пір, проте в даний час бібліотеку ніхто не підтримує, її розвиток не відбувається. На зміну javax.Comm прийшла інша java бібліотека – RXTX (http://rxtx.qbang.org/wiki/index.php/Main_Page). Методи в RXTX для роботи з COM-портом ідентичні до методів javax.Comm.

Встановлення

Встановлення бібліотеки можна здійснити декількома способами. Їх можна знайти в документації на сайтах підтримки RXTX.

1. Найпростіший спосіб:

• Знайти де у вас встановлене JDK, наприклад:  c:\Program Files\Java\jdk1.6.0_01\
• Скопіювати rxtxParallel.dll до c:\Program Files\Java\jdk1.6.0_01\jre\bin\
• Скопіювати rxtxSerial.dll до c:\Program Files\Java\jdk1.6.0_01\jre\bin\
 • Скопіювати RXTXcomm.jar до c:\Program Files\Java\jdk1.6.0_01\jre\lib\ext\

Якщо у вас JRE і вам просто необхідно виконати необхідну програму, яка використовує RXTX, то зробити теж саме але для відповідних каталогів JRE. Звичайно даний спосіб поганий для кінцевих користувачів вашого продукту. Оскільки не всі користувачі зможуть легко зробити необхідні маніпуляції з файлами.

2.Тому другий спосіб - це включити бібліотеку у jar файл вашого продукту. Якщо ви використовуєте NetBeans, то у проекті де знаходяться java файли необхідно створити каталог resources і помістити туди rxtxSerial.dll. .

Другий крок – це додавання власне java файлів, для цього можна завантажити джерельний код(source) бібліотеки з офіційного сайту і з папки src взяти усі .java файли і закинути в src-папку проекту по структурі каталогів gnu/io.

Детальніше можна знайти в різноманітній документації. Зокрема як підключити rxtx у Eclipse написано тут: http://rxtx.qbang.org/wiki/index.php/Using_RXTX_In_Eclipse

Для початку можете спробувати перший спосіб.



Програмування

Перейдемо власне до програмування. В інтернеті я знайшов хорошу реалізацію класу SerialPortHandler, який спрощує роботу з RXTX. Тому наведу дещо перероблений варіант далі (Оригінал: http://embeddedfreak.wordpress.com/2008/08/08/how-to-open-serial-port-using-rxtx/)

Для роботи необхідно перш за все, отримати ідентифікатор послідовного порту:

CommPortIdentifier portId =
  CommPortIdentifier.getPortIdentifier("COM4");

Далі необхідно відкрити порт, тобто вказати системі, що ви з ним працюєте:

SerialPort serialPort =(SerialPort) portId.open("Name of program", 5000);

У вищенаведеному рядочку ми відсилаємо назву програми і задаємо інтервал очікування відповіді. В даному випадку 5000 мс – 5 секунд. Якщо відповідь не приходить, то отримуємо виняток IOException.

Якщо пройшло все добре, порт знайдено в системі і вам надано ID для роботи з ним, то далі необхідно налаштувати порт для роботи з ним:

int baudRate = 9600; // 9600bps
try {
  serialPort.setSerialPortParams(
    baudRate,
    SerialPort.DATABITS_8,
    SerialPort.STOPBITS_1,
    SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException ex) {
  System.err.println(ex.getMessage());
}

Незабуваємо задати контроль потоку:

try {
  serialPort.setFlowControlMode(
        SerialPort.FLOWCONTROL_NONE);
  // OR
  // If CTS/RTS is needed
  //serialPort.setFlowControlMode(
  //      SerialPort.FLOWCONTROL_RTSCTS_IN | 
  //      SerialPort.FLOWCONTROL_RTSCTS_OUT);
} catch (UnsupportedCommOperationException ex) {
  System.err.println(ex.getMessage());
}

Для того щоб записувати і отримувати дані з порта, необхідно отримати потоки вводу-виводу.

OutputStream outStream = serialPort.getOutputStream();
InputStream inStream = serialPort.getInputStream();

Далі наведено повний текст методів для роботи з COM-портом. Наводиться без змін з оригінальної статті. Для використання необхідно вказати свій ідентифікатор порту та швидкість роботи з ним.



public class SerialPortHandler {
    private SerialPort serialPort;
    private OutputStream outStream;
    private InputStream inStream;

    public void connect(String portName) throws IOException {
        try {
            // Obtain a CommPortIdentifier object for the port you want to open
            CommPortIdentifier portId =
                    CommPortIdentifier.getPortIdentifier(portName);

            // Get the port's ownership
            serialPort =
                    (SerialPort) portId.open("Demo application", 5000);

            // Set the parameters of the connection.
            setSerialPortParameters();

            // Open the input and output streams for the connection. If they won't
            // open, close the port before throwing an exception.
            outStream = serialPort.getOutputStream();
            inStream = serialPort.getInputStream();
        } catch (NoSuchPortException e) {
            throw new IOException(e.getMessage());
        } catch (PortInUseException e) {
            throw new IOException(e.getMessage());
        } catch (IOException e) {
            serialPort.close();
            throw e;
        }
    }

    /**
     * Get the serial port input stream
     * @return The serial port input stream
     */
    public InputStream getSerialInputStream() {
        return inStream;
    }

    /**
     * Get the serial port output stream
     * @return The serial port output stream
     */
    public OutputStream getSerialOutputStream() {
        return outStream;
    }

    /**
     * Sets the serial port parameters
     */
    private void setSerialPortParameters() throws IOException {
        int baudRate = 57600; // 57600bps

        try {
            // Set serial port to 57600bps-8N1..my favourite
            serialPort.setSerialPortParams(
                    baudRate,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);

            serialPort.setFlowControlMode(
                    SerialPort.FLOWCONTROL_NONE);
        } catch (UnsupportedCommOperationException ex) {
            throw new IOException("Unsupported serial port parameter");
        }
    }
}
Ряд прикладів по використанню RXTX можна знайти тут: http://rxtx.qbang.org/wiki/index.php/Examples