본문 바로가기
Embedded

[Arduino]아두이노 GPS 모듈 사용하기

by 다봄이 2020. 8. 6.

원본 글: 내 네이버 블로그, 포스팅 날짜 2020-01-19

 

개발 환경 : Arduino, Android studio, node.js

이전 포스팅에서 아두이노 프로젝트의 하드웨어에는 GPS모듈, 블루투스 모듈을 사용하였고 하드웨어의 소형화를 위해 보드는 아두이노 나노를 사용했다고 했었다. 이번에는 아두이노 GPS 모듈 사용법에 대해 알아보자.


아두이노 GPS

아두이노 NEO-6M GPS 모듈, 가격 : 9,300

우선 이 가격에 좋은 성능을 기대하면 안 된다... GPS때문에 프로젝트 진행에 애를 많이 먹었다....

우리처럼 GPS가 핵심 정보인 프로젝트를 진행할 때는 무조건 핵비싼 GPS 모듈을 쓰는 것을 추천한다.

우선 아두이노 GPS에는 PIN이 없어서 납땜을 해줘야 한다.

단자는 각각 VCC, GND, RX, TX이며 납땜한 모듈을 보드의 각각 맞는 PIN과 연결해야 하는데, 아두이노 GPS 모듈의 경우 모듈과 보드의 RX, TX를 바꿔서 연결해야 한다.

GPS 모듈

아두이노 보드

VCC

5V

GND

GND

RX

D5

TX

D6



아두이노 GPS에 간단한 테스트 코드를 업로드하고 동작을 확인하면, 알 수 없는 값들만 시리얼 모니터로 확인할 수 있다.

$GPRMC,082608.00,A,3730.67773,N,12694.42632,E,0.048,,110516,,,D*78 
$GPVTG,,T,,M,0.048,N,0.089,K,D*2B 
$GPGGA,082608.00,3730.67773,N,12694.42632,E,2,08,1.54,49.8,M,18.5,M,,0000*6D 
$GPGSA,A,3,08,42,01,07,11,16,50,10,,,,,2.95,1.54,2.51*01 
$GPGSV,3,1,09,01,44,188,40,07,57,267,41,08,64,024,45,10,12,063,36*7A

위도/경도 값을 받기 위해 아두이노 GPS 모듈을 사용하는 건데 이게 무슨 일이람


NMEA(National Marine Electronics Association)

NMEA는 해양 기자재들간 통신을 위한 전기적 인터페이스 및 데이터 프로토콜이다.

아두이노 GPS로 얻은 데이터를 분석해보자.

$GPRMC,082608.00,A,3730.67773,N,12694.42632,E,0.048,,110516,,,D*78
$GPVTG,,T,,M,0.048,N,0.089,K,D*2B 
$GPGGA,082608.00,3730.67773,N,12694.42632,E,2,08,1.54,49.8,M,18.5,M,,0000*6D 
$GPGSA,A,3,08,42,01,07,11,16,50,10,,,,,2.95,1.54,2.51*01 
$GPGSV,3,1,09,01,44,188,40,07,57,267,41,08,64,024,45,10,12,063,36*7A
  • GP : talker ID, GPS에서는 보통 GP를 사용함.
  • GGA : sentence ID, 여러 항목으로 구성되어 있고 위 항목의 데이터에 따라 메세지가 달라진다.

이처럼 많은 GPS 수신기에서는 GPGGA, GPRMC, GPGSA, GPGSV 등을 포함하고 있으며, GPGGA는 모든 GPS 수신기에서 지원한다.

 

GPRMC의 경우에는 GPGGA에서는 지원하지 않는 속도, 방향, 날짜에 대한 데이터를 지원하며, GPGSA는 GPS의 수신상태를 점검하는데 주로 이용되고 GPGSV는 보이는 위성의 개수 등 위성 정보에 대한 데이터를 지원한다.

따라서 보통은 tiny GPS 라이브러리를 이용하여 GPS값을 우리에게 익숙한 데이터의 형태로 변환하는데, 이렇게 변환한 값은 위도, 경도 뿐만 아니라 날짜, 시간, 고도, 속도 등 상당히 많은 정보를 포함하기 때문에, 나는 GPGGA를 이용하여 기본적인 위도 경도 값만 parsing해서 가져와 보겠다.

GPGGA

$GPGGA,082608.00,3730.67773,N,12694.42632,E,2,08,1.54,49.8,M,18.5,M,,0000*6D

 

Field

Example

Notes

1

Sentence ID

GPGGA

Global Positioning System fixed data

2

UTC time

082608.00

hhmmss.sss

3

Latitude

3730.67773

ddmm.mmmm

4

N/S indicator

N

N : North, S : South

5

Longtitude

12694.42632

dddmm.mmmm

6

E/W indicator

E

E : East, W : West

위의 표를 보면, 우리가 필요한 위도/경도 정보는 3번째, 5번째에 위치한 데이터임을 알 수 있다.

데이터 포맷에 따르면

  • 위도 : ddmm.mmmm
  • 경도 : dddmm.mmmm

GPS값을 위경도로 바꾸는 계산식은 mm부분을 60으로 나누고 dd부분과 더해주면 된다. 즉,

  • 위도 : dd + (mm.mmmm/60)= 37 + (30.67773/60) = 37.5112955
  • 경도 : ddd + (mm.mmmm/60)= 126 + (94.42632/60) = 127.573772

한국에서 GPS를 쓰는 경우 방위는 N, E가 나올 것이므로 패스하고, 이제 쉼표를 구분자로 데이터를 파싱하여 3번째, 5번째 데이터만 가져오면 된다. 아두이노에서도 구분자를 사용하여 파싱할 때 indexOf를 사용한다.

 

 

코드는 대략적으로 gpsSerial.read()를 이용하여 값을 읽어오고 GPGGA일 때만 그 값을 파싱하여 substring()을 이용하여 값을 저장하고 출력하도록 구성하면 된다.

필요한 정보는 3번째, 5번째에 등장하므로 각각 2번째 쉼표 뒤, 4번째 쉼표를 기준으로 파싱해야 한다.

//init 
char c = ""; 
String str = ""; 
String targetStr = "GPGGA" 
... 

void loop() { 
    if(gpsSerial.available() { 
        c=gpsSeral.read(); 
        ... 

        // 쉼표를 기준으로 파싱하기
        int firstData = str.indexOf(","); //첫 번째 콤마 전까지의 내용을 파싱 
        int secondData = str.indexOf(",", firstData+1); 
        int thirdData = str.indexOf(",", firstData+2); 
        int fourthData = str.indexOf(",", firstData+3); 
        int fivethData = str.indexOf(",", firstData+4); 

        //data 추출 
        String Lat = str.substring(seconData+1, thirdData); 
        String Long = str.substring(fourthData+1, fivethData); 
        ...

이처럼 indexOf를 이용하여 구분자를 기준으로 데이터를 파싱하고, substring 함수를 이용하여 해당 위치의 데이터를 index를 이용하여 추출하는 방식으로 tiny GPS 라이브러리를 사용하지 않고서도 필요한 데이터만 추출할 수 있을 것이다.(배열 등을 이용해서 코드를 깔끔하게 짜도 되지만 굉장히 간단한 코드라서 원시적인 방법으로 짰다.)

얻은 gps 좌표는 소수점 아래 7자리까지 출력하여 블루투스 모듈을 통해 안드로이드로 전송했다.




테스트 영상은 다음과 같다. (확인을 위해 원 GPS 데이터 값도 같이 띄움)

테스트를 할 경우, GPS 모듈에 불이 깜빡이는 것을 볼 수 있다.

이 불은 GPS 위성과 연결되어 신호를 받아올 경우에 들어오는데, 보통은 10분이 걸린다고 하지만 나는 신호를 잡기까지 1시간도 더 걸렸다....


아두이노 GPS 테스트 시에는 반드시!!

  1. 탁 트인 공간에서 해야한다. 아두이노 NEO-6M GPS는 감도가 낮아서 학교 운동장에서도 안 잡혀서 운동장 한가운데에 서 있었더니 신호가 잡혔었다.
  2. GPS 모듈의 안테나를 하늘로 향하게 둬야 한다.

반드시!!!!!!!!!!!!

완성된 하드웨어의 내부 구성은 다음과 같다. 여기 GPS 안테나의 동그란 부분이 하늘로 향해야 한다.

 


전반적으로 아두이노 프로젝트를 진행하며 아두이노 GPS가 정말 불편하다고 느꼈던 점이 이 신호를 잡는 과정에 걸리는 시간이었다. 아무리 구글링해도 대부분 10분정도 걸린다는 것 같은데 한시간도 넘는 동안 신호가 안 잡혀서 한밤중에 노트북 들고 온 사방팔방을 돌아다녔던 기억이 있다...

 

또, 이 GPS의 수신 신호가 굉장히 잘 끊긴다. 탁 트인 공간이나 탁 트인 대로변이 아닌 건물이 많은 골목 등으로 진입하면 금새 끊어져 버린다. 이는 GPS 정보가 핵심 기술인 우리 프로젝트에 있어 치명적인 결함으로 작용했기에 결국 아두이노 GPS 대신 핸드폰 GPS를 이용하게 되었다.(하드웨어와 사용자가 함께 움직이기에 가능했다. 현대인은 핸드폰을 몸에서 떨어트리지 않으니까)

혹시라도 GPS 기반의 프로젝트를 진행하시는 분들은 비싼 GPS 모듈을 사용하거나 핸드폰 GPS를 이용하는 방법을 추천드린다.

'Embedded' 카테고리의 다른 글

kakao 지도 api 사용을 위한 해쉬 키 생성  (0) 2020.05.14

댓글