고급 예제

다양한 도구들을 가지고 마음껏 응용해보세요.

시리얼통신으로 자바와 아두이노 연동하기

2016-03-08 11:44:57

개요

 

오래전에 C++와 아두이노간에 시리얼통신을 하는 튜토리얼을 올린적이 있었는데요.

(링크 : http://kocoafab.cc/tutorial/view/255)

 

시리얼통신은 오래된 통신 방법이지만 아두이노에서는 아직도 유용하게 쓰이고 있는 방법이기 때문에 여러 툴들과 시리얼통신으로 연동하는 방법만 익힌다면 그 확장성은 엄청나다고 볼 수 있습니다.

대표적으로 아두이노와 프로세싱간에 시리얼 통신을 들 수 있고, 지금 쓰고자 하는 자바와의 시리얼 통신 또한 많이 쓰일 수 있는 기능입니다.

 

<시리얼 통신 방법>

 

 

이번 글에서는 간단하게 시리얼 통신에 대해 알아보고 자바와 아두이노간에 시리얼통신(Serial Communication)을 하는 법에 대해 알아보겠습니다.

 

 

시리얼 통신에 대한 간단한 소개

 

시리얼 통신(Serial Communication)에서 시리얼(Serial)의 사전적 의미를 찾아보면 아래와 같습니다.

 

 

 

 

사전을 찾아보면 Serial은 순차적인, 연속되는 등의 뭔가 똑같은 일을 계속 반복한다는 의미를 가지고 있는 단어입니다.

통신에서의 시리얼 통신이란 패러럴 통신(병렬 통신)에 반대되는 말로써 한번의 통신의 한 비트의 데이터를 보내는 방식을 말합니다.

 

아래 사진은 패러럴(Parallel)통신에 관한 간략도 입니다.

사진을 보시면 알겠지만 여러개의 입출력 핀과 하나의 클럭핀을 사용하여 한번에 여러개의 데이터를 전송하는 것을 볼 수 있습니다.

 

 

 

 

위의 패러럴 통신에 반대되는 시리얼통신은 아래와 같은 방법으로 이루어집니다.

 

입출력핀이 각각 1개씩 필요한 대신에 데이터는 하나의 입출력핀에서 나와 일렬로 나란히 클럭에 따라 전송됩니다.

이렇게 한번에 하나의 데이터를 전송하는 일을 여러번 반복하기 때문에 시리얼 통신이라고 불립니다.

시리얼 통신을 다른 말로 부르면 병렬 통신에 반대되는 직렬 통신이라고 합니다. 아래 그림과 같이 시리얼 통신에서 데이터는 직렬로 전송되기 때문이죠.

 

 

 

 

위의 그림을 보더라도 한번에 클럭에 병렬통신은 다수의 데이터가 전송되는 반면에 시리얼통신은 오직 하나의 데이터만 전송되는 것을 볼 수 있습니다.

 

이렇게 시리얼통신은 병렬통신에 비해 속도는 느리지만 그 대신 적은 수의 입출력핀을 가지고 통신을 할 수 있다는 장점이 있습니다.

이러한 장점은 핀의 개수가 제한적인 아두이노에서 부각됩니다. 속도를 제한하더라도 핀의 개수를 살리는 방법을 택했기 때문에 아두이노에서는 시리얼 통신을 사용합니다.

 

 

시리얼통신은 크게 동기식비동기식으로 나눌 수 있습니다. 

위의 사진에서는 클럭(CLK)핀이 존재하여 클럭핀에 맞추어 데이터가 전송되는 것을 볼 수 있는데 이렇게 클럭핀에 맞춰서 데이터가 전송되는 방식을 동기식이라 합니다. 동기식의 대표적인 예를 들면 아두이노에서 쓰이는 I2C나 SPI통신을 들 수 있습니다.

 

동기식과 반대로 클럭핀이 없는 대신에 통신속도를 서로 맞추어서 데이터를 전송하는 방법이 있는데 이를 비동기식 통신이라 합니다. 대표적인 방식이 역시 아두이노에서 쓰이는 UART통신을 들 수 있습니다.

UART통신의 경우 CLK핀 없이 Tx핀과 Rx핀 2개만을 사용하며 아두이노UNO의 경우 1개의 UART가 통신하고 Mega의 경우 4개의 UART가 존재합니다.

 

 

 

자바 RxTx라이브러리 다운받기

 

자바에서 RxTx라이브러리를 사용하기 위해서는 역시 라이브러리를 웹에서 내려받아야 합니다.

RxTx라이브러리의 경우 RxTx위키에서 자세한 내용을 다루고 있고 이 곳에서 내려받을 수 있습니다.

 

RxTx WiFi페이지 : http://rxtx.qbang.org/wiki/index.php/Main_Page

RxTx라이브러리 내려받기 : http://rxtx.qbang.org/pub/rxtx/rxtx-2.2pre2-bins.zip​

 

 

 

 

TxRx라이브러리를 받고난 뒤 압축을 풀고

RXTXcomm.jar는 %JAVAHOME%lib에 넣어주시고

rxtxSerial.dll는 %JAVAHOME%bin에 넣어주시면 됩니다.

 

라이브러리 파일 이동 후에 Java프로젝트를 생성하고 프로젝트 클릭 - properties - Java Build Path - Libraries에서 추가하신 RXTXcomm.jar를 추가하면 됩니다.

 

 

 

 

소프트웨어 coding

 

 

자바 코드

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Serial
{
    public Serial()
    {
        super();
    }
    
    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.out.println("Error: Port is currently in use");
        }
        else
        {
            //클래스 이름을 식별자로 사용하여 포트 오픈
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
            
            if ( commPort instanceof SerialPort )
            {
                //포트 설정(통신속도 설정. 기본 9600으로 사용)
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
                
                //Input,OutputStream 버퍼 생성 후 오픈
                InputStream in = serialPort.getInputStream();
                OutputStream out = serialPort.getOutputStream();
                
                 //읽기, 쓰기 쓰레드 작동
                (new Thread(new SerialReader(in))).start();
                (new Thread(new SerialWriter(out))).start();

            }
            else
            {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }     
    }
    
    /** */
    //데이터 수신
    public static class SerialReader implements Runnable 
    {
        InputStream in;
        
        public SerialReader ( InputStream in )
        {
            this.in = in;
        }
        
        public void run ()
        {
            byte[] buffer = new byte[1024];
            int len = -1;
            try
            {
                while ( ( len = this.in.read(buffer)) > -1 )
                {
                    System.out.print(new String(buffer,0,len));
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }

    /** */
    //데이터 송신
    public static class SerialWriter implements Runnable 
    {
        OutputStream out;
        
        public SerialWriter ( OutputStream out )
        {
            this.out = out;
        }
        
        public void run ()
        {
            try
            {
                int c = 0;
                while ( ( c = System.in.read()) > -1 )
                {
                    this.out.write(c);
                }                
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }
    
    public static void main ( String[] args )
    {
        try
        {
            (new Serial()).connect("COM3"); //입력한 포트로 연결
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

 

 

 

아두이노의 포트를 입력하고 아두이노와의 시리얼 통신속도를 맞춘 후 실행시키면 콘솔창에서 아두이노에서 보내는 값이 출력되는 것을 확인할 수 있습니다.

반대로 입력한 값 또한 아두이노로 전달되는것도 확인이 가능합니다.(아두이노의 값 전달의 경우 간단하게 LED 깜빡이기를 통해 확인해 볼 수 있습니다.)

 

 

 

kocoafabeditor

항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!

아두이노, Arduino, 시리얼 통신, Java, 자바, TxRx

장세현 2016-03-15 19:25:23

감사합니다.

kocoafab 2016-04-07 18:51:04

https://github.com/scream3r/java-simple-serial-connector/ 이런 라이브러리도 있다합니다. 참고하세요

김진만 2016-04-13 10:36:44

잘보았습니다. 감사합니다.

강상호 2016-09-12 14:13:53

감사합니다.