ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 시리얼 통신 기본 설정
    Arduino/Java Serial통신 2020. 11. 17. 17:50

    아두이노는 pc와 유선으로 연결되어 있다.
    통신은 선을 통해서 한다.
    아두이노와 pc가 서로 통신을 하려면 
    아두이노와 pc(자바)가 서로서로 시리얼 통신을 지원해야 한다.
    이를 tx,rx라 한다. tx, rx는 모두 선이다.
    Tx는 전송이므로 out 객체이고 Rx는 in 객체이다.
    이를 COM포트에 연결해야 한다.

    자바에서는 Serial을 바로 사용하지 못한다.

    그래서 자바가 하드웨어적으로 단독적으로 사용하지 못해서 C언어의 도움을 받아야 한다.

    자바는 순수하게 하드웨어 통신을 할 수 없다.
    그러므로  C를 이용해서 하드웨어에 접근해야 한다.
    정확하게는 dll파일이 필요하다.
    JAVA(DLL라이브러리(C파일)와 JAR(JAVA 파일) 라이브러리를 이용)

     

    아래의 사이트에서 다운을 받는다. 

    rxtx.qbang.org/wiki/index.php/Download#x64_Binaries

    위의 사이트에서 Binary로 다운을 받으면 된다.

    압축을 풀고, RXTXcomm.jar 파일과 rxtxSerial.dll파일이 있는지 확인하자.

    압축을 푼 경로를 기억하고 있자.

     

    만약 위의 파일로 진행하다가 문제가 생기면 아래의 파일을 사용하자.

    지우는 방법은 

    프로젝트 선택하고 우클릭해서 Build Path에서 Configure Build Path를 선택한다.

    그리고 Libraries 탭을 선택하고 Modulepath에서 RXTXcomm.jar파일을 remove한다.

    그리고 lib폴더에서 RXTXcomm.jar 파일과 rxtxSerial.dll 파일을 제거하고

    아래의 파일을 다운로드한다.

    (지우는 과정은 설정하는 과정의 역순이다.)

     

    RXTXcomm.jar
    0.06MB
    rxtxSerial.dll
    0.37MB

     

    다운 받은 파일들을 한 곳에 저장한다. 

     

    자바에서 새로운 자바 프로젝트를 하나 생성하고 이름은 SerialCom이라고 하자. 그리고 Next를 선택.

     

    그리고 아래와 같이 Create module-info.java file은 체크 해제하고 Finish를 선택한다.

     

    현재 프로젝트의 하위에 lib라는 폴더를 하나 생성한다.

    RXTXcomm.jar 파일과 rxtxSerial.dll 파일을 CTRL + C 해서 복사한 다음에

    src/lib에 CTRL + V해서 붙여넣는다.

    그러면 다음과 같다.

    그리고 현재의 프로젝트를 선택한 다음 우클릭해서 Properties 를 선택한다.

    아래와 같이 왼쪽 탭에서 Java Build Path를 선택한다.

    그러고 나서 오른쪽 탭에서 Libraries 탭을 선택한다.

    Classpath를 선택하고 Add JARs를 선택한다. 아래의 그림과 같다.

     

    현재 프로젝트의 lib폴더에 있는 RXTXcomm.jar파일을 선택하고 OK를 선택한다.

    그리고 창을 닫지 말자. 한 가지 더 설정해야 한다. 위에서 OK버튼을 선택하면

    아래와 같이 Classpath에 jar파일이 추가가 된 것을 볼 수 있다.

     

    그리고, RXTXcomm.jar 파일을 확장하면 Native library location: (None)이 보일 것이다.

    Native library location은 dll을 선택하는 것이다.
    dll은 lib폴더에 들어있다.

     

    Native library location: (None)을 더블 클릭하면 다음과 같은 창이 뜬다.

     

    Workspace를 눌러서 현재 프로젝트의 lib폴더를 찾아서 추가를 하면 된다.

     

    그리고 아래의 창과 같이 뜬다. 그리고 OK를 선택한다.

     

    그러면 아래와 같이 된다. Apply and Close를 선택한다.

     

    그리고, 간혹 프로젝트 아이콘에 X로 떠 있는 경우를 볼 수있는데, 이는 자바 버전이 낮은 경우이다.

    이 경우에 자바 버전을 변경할 수 있다.

    현재 프로젝트를 우클릭해서 Properties를 선택하고 왼쪽 탭에서 Project Facets를 선택하고
    java를 선택해서 버전을 1.8로 높여준다. 아래의 그림을 보자.

     

    그리고 src폴더에 자바 파일을 하나 만든다. Class 파일을 선택하면 된다.

    이름은 Serial이라 하자.

    InputStream in = serialPort.getInputStream();  // 해당하는 시리얼 포트에대해서 입력 스트림을 만든다.

    OutputStream out = serialPort.getOutputStream(); // 해당하는 시리얼 포트에 대해서 출력 스트림을 만든다.

     

    위의 문장은 rxtxcom.jar파일에서 가지고 오는 문장이다. 에러가 난다면 라이브러리가 없다는 의미이다.

    열기가 성공한 시리얼 포트에 대해서 들어오고 나오는 입구를 만들었다.

    Serial.java

    더보기
    import gnu.io.CommPort;
    import gnu.io.CommPortIdentifier;
    import gnu.io.SerialPort;
    
    public class Serial 
    {
    	void connect(String port) 
    	{
    		CommPort commPort = null;
    		SerialPort serialPort = null;
    		
    		try 
    		{
    			CommPortIdentifier com = CommPortIdentifier.getPortIdentifier(port);
    			
    			//	com포트를 확인하는 작업
    			if (com.isCurrentlyOwned())
    				System.out.println("Error : "+port +"포트를 사용중입니다.");
    			
    			//	포트가 열려있으면
    			else
    			{
    				commPort = com.open(this.getClass().getName(),2000);
    				
    				//	획득한 포트를 객체가 사용할 수 있는지 여부 확인
    				if (commPort instanceof SerialPort)	//	commPort가 SerialPort로 사용할 수 있는지 확인
    				{
    					serialPort = (SerialPort)commPort;
    					
    					//	정상적으로 포트를 사용할 수 있을 경우
    					//	포트에 필요한 정보를 입력해 준다.
    					serialPort.setSerialPortParams(
    							9600,						//	바운드레이트 
    							SerialPort.DATABITS_8, 
    							SerialPort.STOPBITS_1, 
    							SerialPort.PARITY_NONE);	//	오류제어 비트
    				}
    				System.out.println("comport성공");
    			}
    		}	//	end try
    		catch(Exception e) {}
    	}
    }

     

     

     

     

    그리고, src폴더에 java 파일을 만드는데, 클래스 명을 Main이라고 한다.

    그리고 아래에서 connect함수에 COM6의 의미는 나중에 아두이노와의 연결에 필요한 포트번호이다.

    이 포트번호가 전부 다를 수 있으므로 나중에 포트번호를 확인하도록 하자.

    다른 방법으로 포트번호를 확인할 수 있다.

    내 PC를 우클릭해서 속성에 들어가서 장치관리자로 들어가서 포트를 선택해서 알아낼 수 있다.

    시리얼 통신시에 포트 번호를 알아내는 것은 중요하다.

    만약 동작이 안되면 꼭 포트 번호를 확인하자.

    Main.java

    더보기
    public class Main {
    	public static void main(String[] args) 
    	{
    		try {
    			
    			(new Serial()).connect("COM6");
    		}
    		catch(Exception e) 
    		{
    			e.printStackTrace();
    		}
    	}
    }

     

    반드시 실행을 하기 전에 아두이노와 컴퓨터가 서로 연결이 되어 있어야 한다.

    만약 연결하지 않고 살행하면 comport성공이라는 문구가 보이지 않는다.

    그리고 Main.java파일을 실행하자.

    아래와 같은 콘솔 창의 결과를 볼 수 있을 것이다.

     

    아래는 아두이노를 연결하지 않은 상태에서 실행한 결과이다.

     

    아두이노와 통신을 할 때, 위와 같이 프로그램이 실행 중인 상태에서는 아두이노에 소스 파일을 업로드를 할 수 없다.

    그 이유는 포트를 사용하고 있기 때문이다.

    그래서 콘솔 화면 창에서 마우스 우클릭해서 Terminate/Disconnected All하고 아두이노에 업로드를 해야 한다.

     

    기본 설정을 했다면 아래의 페이지로 이동해서 아두이노와 통신을 해보자.

    designatedroom87.tistory.com/316?category=903927

     

    아두이노와 자바의 시리얼 통신(아두이노에서 자바로 0과 1을 전송)

    자바에서 시리얼 통신을 설정하지 않았다면 아래의 글을 참고하자. designatedroom87.tistory.com/315 Java 시리얼 통신 기본 설정 아래의 사이트에서 다운을 받는다. rxtx.qbang.org/wiki/index.php/Download#x64..

    designatedroom87.tistory.com

     

     

    아래의 내용은 하나의 부록이라고 보자.

    이어지는 내용에서는 아래의 내용이 필요 없다.

    그리고, 동적 라이브러리 링크(DLL) 를 만들 수 있다.

    우선 src폴더에 jni 패키지를 만들고, 패키지에 JNI.java 파일을 만든다.

    JNI.java

    더보기
    package jni;
    
    public class JNI {
    	static	{
    		//	라이브러리를 가지고 온다.
    		System.loadLibrary("JavaNative");
    	}
    	
    	//	getNumber, printHelloWorld함수는 외부 라이브러리에 있는 함수로,
    	//	native는 외부 라이브러리로부터 함수를 가지고 와서 쓰기 위해 선언 
    	private native int getNumber();
    	private native void printHelloWorld();
    	
    	public static void main(String[] args) {
    		JNI jni = new JNI();
    		
    		//	객체를 사용
    		jni.printHelloWorld();
    		System.out.println(jni.getNumber());
    	}
    }

     

     

    jni_JNI.h
    0.00MB

    jni 패키지의 JNI.java 파일을 헤더파일로 우선 만들어야 한다.

    만드는 과정을 일단 생략하고 위의 파일이 그 헤더 파일이다.

     

    우선 비주얼 스튜디오를 실행해서 프로젝트 폴더를 만들도록 하자. ( 일반 C/C++ 프로젝트 생성 )

    새 프로젝트 만들기 -> 빈 프로젝트 -> 프로젝트 이름을 JavaNative 라고 하고 만들기를 한다.

    그리고 위의 헤더 파일을 다운 받아서 프로젝트 폴더인 JavaNative에 저장한다.

    그리고 위의 jni_JNI.h 파일을 인클루드하는 방법은

    솔루션 탐색기 내의 헤더 파일을 선택하고 우클릭해서 추가 -> 기존 항목을 선택하고 jni_JNI.h 파일을 추가한다.

    아래의 그림을 보자.

     

    그리고 아래의 jni_JNI.h파일을 추가하면 된다.

    그리고 JNI.c 파일을 하나 만들자. 소스 파일을 선택하고 우클릭해서 추가 -> 새 항목을 선택한다.

     

    아래와 같이 이름은 JNI.c 라고 적는다. 그리고 추가를 선택한다.

    JNI.c 에 들어갈 내용은 나중에 적도록 한다.

     

     

    먼저 환경 설정부터 해줘야 한다.

    다음과 같이 솔루션 탐색기를 선택한다.

    그리고 우클릭을 해서 속성을 선택한다.

    일반탭을 선택하면 아래와 같은 화면이 뜬다.

    일반탭에서 구성 형식을 더블 클릭하면 그 값이 변경이 된다.

    일반탭에서 구성 형식을 동적 라이브러리로 변경하고 플랫폼을 x64로 변경한다. 아래의 두 그림을 보자.

     

    플랫폼은 아래의 위치에서 변경한다.

     

    그리고, 아래와 같이 고급 탭으로 이동하자.

     

    대상 파일 확장명이 .dll인지 확인을 한다.

    아마 아래와 같이 .exe로 되어 있을 것이다.

    위의 그림에서 맨 오른쪽의 아래쪽 모양의 단추를 클릭하면 아래와 같은 모습이 된다.

    그리고 편집을 선택한다.

    그리고 .dll이라 적고 확인 버튼을 선택한다.

     

    그러면 아래와 같이 대상 파일 확장명이 .dll로 변경 된다.

     

    그리고, C/C++ 탭의 하위의 일반 탭을 클릭한다. 

     

    C/C++ 탭의 하위의 일반 탭의 내용은 아래와 같다.

     

    추가 포함 디렉터리를 선택하면 아래와 같이 오른쪽에 아래쪽 화살표 버튼이 나타나는데, 이 버튼을 선택한다.

    아래와 같이 편집 칸이 나타나는데, 이를 선택한다.

    그러면 다음과 같인 창이 하나 뜬다.

    위의 창에 아래와 같이 두 줄을 적는다.

    C:\Program Files\Java\jdk-13.0.2\include 

    C:\Program Files\Java\jdk-13.0.2\include\win32

     

    그런데 위의 두 경로는 버전마다 변경될 수 있다.

    우선 윈도우 탐색기를 열고 C:\Program Files\Java로 이동하자.

    위의 내용과 다름을 알 수 있다. 우선 위의 폴더로 들어가면 아래와 같이 폴더와 파일이 있다.

    그리고 다시 include 폴더로 들어가자. 그러면 아래와 같은 모습이 나온다.

    여기까지의 주소를 복사한다.

    C:\Program Files\Java\jdk-15.0.1\include

     

    그리고 여기에서 위의 win32폴더로 들어가자. 그러면 아래와 같은 모습이 나타난다.

    여기까지의 주소를 복사한다.

    C:\Program Files\Java\jdk-15.0.1\include\win32

     

    그러면 추가할 주소는 위의 붉은 색 두 문장이다.

    아래와 같이 한 줄씩 추가를 해주면 된다.

    첫 번째 줄 추가

    두 번째 출 추가

    추가를 했으면, 확인 버튼을 선택한다.

    그리고 적용 버튼을 선택하고 확인을 선택한다.

    여기까지가 환경설정의 끝이다.

     

    JNI.c 파일을 연 상태에서 빌드 탭 바로 아래에 Debug로 두고 x64로 설정을 한다.

    아래와 같이 x64로 선택이 되었음을 볼 수 있다.

    그리고 JNI.c 에 아래의 내용을 적어보자.

    jni_JNI.h 내용

    더보기
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class jni_JNI */
    
    #ifndef _Included_jni_JNI
    #define _Included_jni_JNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     jni_JNI
     * Method:    getNumber
     * Signature: ()I
     */
    JNIEXPORT jint JNICALL Java_jni_JNI_getNumber
      (JNIEnv *, jobject);
    
    /*
     * Class:     jni_JNI
     * Method:    printHelloWorld
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_jni_JNI_printHelloWorld
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

     

     

    JNI.c 파일 내용

    더보기
    #include <stdio.h>
    #include <jni.h>
    #include "jni_JNI.h"
    
    /*
     * Class:     jni_JNI
     * Method:    getNumber
     * Signature: ()I
     */
    JNIEXPORT jint JNICALL Java_jni_JNI_getNumber
    (JNIEnv* env, jobject jobj)
    {
    	return 100;
    }
    
    /*
     * Class:     jni_JNI
     * Method:    printHelloWorld
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_jni_JNI_printHelloWorld
    (JNIEnv* env, jobject jobj)
    {
    	printf("Hello World!");
    }

     

    그리고 JNI.c에 내용을 모두 적었다면 빌드 탭을 선택하고 "JavaNative 다시 빌드"를 선택한다.

     

    아래의 컴파일 결과를 볼 수 있다.

     

    그리고나서 프로젝트를 닫고, 프로젝트가 있는 폴더를 들어가면 아래와 같은 파일 구조가 되어있음을 볼 수 있다.

     

    x64폴더에 들어가면 Debug폴더가 있고 이 Debug폴더에 들어가보자. 그러면 JavaNative.dll 파일이 보일 것이다.

     

     

    JavaNative.dll을 CTRL + C로 복사를 한다.

    그리고 자바로 넘어와서 현재 프로젝트의 SerialCom의 lib폴더에 CTRL + V로 붙여넣는다.

    위의 그림과 같다.

    그리고 마지막 한가지만 수정하면 된다.

    위의 lib폴더에 있는 javaNative 파일 이름을 복사한다. 

    JNI.java 파일로 이동해서 System.loadLibrary("JavaNative"); 에서 함수의 매개변수를 파일의 이름과 같도록 설정한다.

     

     

    그리고 JNI.java 파일로 이동해서, main함수를 실행하자.

    마우스 우클릭해서 아래와 같이 Java Application을 선택한다.

     

    다음과 같은 실행결과를 얻는다.

     

    위와 같은 결과값이 출력되는 이유는 JNI.c의 내용을 보면 알 수 있다. 아래의 그림을 보자.

     

    댓글

Designed by Tistory.