홍창민정보·인공지능 교사

움직임·거리·위치 · 난이도 어려움

GY-GPS6MV2(NEO-6M) GPS로 위도·경도·이동 속도·고도를 읽고 정확도 확인하기

GY-GPS6MV2는 u-blox NEO-6M을 쓴 GPS 모듈이에요. 9600bps UART 배선, NMEA 문장과 체크섬, micropyGPS로 위도·경도·속도·고도를 꺼내는 코드, 처음 위치를 잡는 시간과 제자리 흔들림 탐구, 위치 정보를 다룰 때 지킬 것을 정리했어요.

글 홍창민 · 갱신 2026-10-31 · 읽는 데 약 8분 · 가상 실행 확인 (실물 미확인)

이 센서로 무엇을 잴 수 있나

GY-GPS6MV2는 u-blox의 NEO-6M 수신기와 세라믹 안테나를 붙인 GPS 모듈이에요. NEO-6 데이터시트에 따르면 NEO-6M은 GPS L1 신호를 받는 50채널 수신기이고, 수평 위치 정확도는 2.5m(위성 보정 SBAS를 쓰면 2.0m), 속도 정확도는 0.1m/s예요. 이 숫자는 24시간 움직이지 않고, 신호가 아주 센 조건에서 50%가 들어오는 범위(CEP)라서 교실 밖 실제 측정에서는 더 커져요.

피코로 읽을 수 있는 것은 위도·경도, 땅 위를 움직이는 속도(km/h), 평균 해수면 기준 고도, 계산에 쓴 위성 수, 정확도의 지표인 HDOP, 그리고 협정 세계시예요. 실내에서는 위성 신호가 약해 위치를 거의 잡지 못하니, 탐구는 운동장이나 창가에서 해요.

원리

수신기는 여러 위성이 보낸 신호가 도착한 시각의 차이로 자기 위치를 계산해요. 위도·경도·고도와 수신기 시계의 오차까지 풀어야 하므로 3차원 위치에는 위성이 4개 이상 필요해요.

계산 결과는 NMEA라는 글자 문장으로 나와요. 데이터시트의 기본 설정은 9600bps, 8비트, 패리티 없음, 정지 비트 1이고, GGA·GLL·GSA·GSV·RMC·VTG·TXT 문장을 내보내요. 설명용으로 널리 쓰이는 GGA 예시 문장을 보면 구조를 알 수 있어요.

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

쉼표로 나뉜 칸은 차례로 세계시 12시 35분 19초, 북위 48° 07.038′, 동경 11° 31.000′, 위치 품질 1(GPS로 잡음), 위성 8개, HDOP 0.9, 고도 545.4m, 지오이드 높이 46.9m예요. 맨 끝 *47은 체크섬이에요. $와 * 사이 글자들의 코드값을 모두 XOR 한 값이 16진수 47과 같으면 문장이 깨지지 않고 도착한 거예요. 속도는 RMC 문장에 노트 단위로 들어 있어요. 1노트는 1.852km/h예요.

준비물

  • 라즈베리파이 피코와 USB 케이블, 노트북(밖에서 기록할 때)
  • GY-GPS6MV2 모듈과 세라믹 안테나, 암-수 점퍼선 4개
  • 라이브러리 micropyGPS.py(시나브로 PICO가 자동으로 넣어 줘요)
  • 탐구용: 50m 줄자나 운동장 트랙, 스톱워치

배선

GY-GPS6MV2(NEO-6M) GPS로 위도·경도·이동 속도·고도를 읽고 정확도 확인하기: 브레드보드에 피코와 센서를 꽂은 배선 그림
시나브로 PICO 브레드보드 작업대와 같은 계산으로 그린 배선이에요. 위 + 줄은 3.3V, 아래 + 줄은 5V예요.
브레드보드 따라 꽂기 순서 (9단계)
  1. 피코를 브레드보드 가운데 홈에 걸쳐 꽂아요. USB 단자가 왼쪽을 보게 하고, 1번 핀이 f2, 40번 핀이 e2에 들어가요. 다리가 홈 양쪽에 모두 들어갔는지 옆에서 봐요.
  2. 주황 선: 피코 36번 핀(3V3(OUT)) 옆 칸 a6 → 위쪽 + 줄(3.3V). 이제 이 줄 전체가 3.3V예요.
  3. 검은 선: 피코 38번 핀(GND) 옆 칸 a4 → 위쪽 − 줄(GND). 이제 이 줄 전체가 GND예요.
  4. 경위도 위치 GPS NEO-6M 꽂기: 다리 VCC · RX · TX · GND를 위쪽 a24 · a25 · a26 · a27에 차례로 꽂아요. 다리가 브레드보드에 바로 안 들어가면 암-수 점퍼선으로 같은 칸에 이어요.
  5. 주황 선(3.3V 전원): 경위도 위치 VCC 줄 b24 → 위쪽 + 줄(3.3V)
  6. 보라 선(신호): 경위도 위치 RX 줄 b25 → 피코 6번 핀(GP4) 옆 칸 j7
  7. 보라 선(신호): 경위도 위치 TX 줄 b26 → 피코 7번 핀(GP5) 옆 칸 j8
  8. 검은 선(GND): 경위도 위치 GND 줄 b27 → 위쪽 − 줄(GND)
  9. 마지막 확인: ① 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)이 서로 이어지지 않았나요? ② 모든 부품의 GND가 − 줄에 이어졌나요? ③ 5V 신호 다리는 저항을 거쳐 피코에 이어졌나요? ④ 긴 브레드보드는 + − 줄이 가운데에서 끊긴 것도 있어요(빨간·파란 선이 끊겨 있으면 짧은 선으로 이어요). ⑤ 그림과 한 칸씩 비교한 뒤 USB를 꽂아요.
모듈 핀 피코 핀 비고
VCC 3V3 (36번) 사이트 배선대로 3.3V. NEO-6M 칩의 전원 범위는 2.7~3.6V
RX GP4 (6번) 피코 UART1 TX가 보내는 신호를 받아요
TX GP5 (7번) 피코 UART1 RX로 보내요
GND GND (38번) 공통 접지
PPS(있는 기판) 연결 안 함 1초 펄스 출력

UART는 엇갈려 이어요. GPS의 TX(보내기)는 피코의 RX(GP5)에, GPS의 RX는 피코의 TX(GP4)에 연결해요. 데이터시트의 소비 전류는 위치를 추적할 때 약 39mA, 위성을 찾는 동안 약 47mA라서 피코의 3V3 출력으로 충분해요(전원 계산).

GP4·GP5는 기본 I²C 핀과도 겹쳐요. I²C 센서를 함께 쓰려면 UART를 GP8·GP9로 옮기고 코드의 핀 번호도 바꿔요(피코 핀 지도). 안테나는 세라믹 면이 하늘을 향하게 두고, 손이나 금속판으로 덮지 않아요.

코드

from machine import UART, Pin
import time
from micropyGPS import MicropyGPS

uart = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))   # GPS TX → GP5, GPS RX ← GP4
gps = MicropyGPS(9, 'dd')        # 한국 표준시(UTC+9), 위도·경도는 소수 도

# 자가 점검: 예시 GGA 문장의 $와 * 사이 글자를 XOR 하면 47이 나와야 해요
SAMPLE = "GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,"
cs = 0
for ch in SAMPLE:
    cs = cs ^ ord(ch)
print(f"자가 점검: 계산한 체크섬 {cs:02X}, 문장 끝에 적힌 값 47")

t0 = time.ticks_ms()
last = t0
first_fix = -1
while True:
    while uart.any():
        for b in uart.read():
            gps.update(chr(b))       # 한 글자씩 넣으면 라이브러리가 체크섬을 검사해요
    now = time.ticks_ms()
    if time.ticks_diff(now, last) >= 1000:
        last = now
        if gps.fix_stat > 0:
            if first_fix < 0:
                first_fix = time.ticks_diff(now, t0) / 1000
            lat = gps.latitude[0] if gps.latitude[1] == 'N' else -gps.latitude[0]
            lon = gps.longitude[0] if gps.longitude[1] == 'E' else -gps.longitude[0]
            print(f"DATA: lat={lat:.6f}, lon={lon:.6f}, kmh={gps.speed[2]:.1f}, alt={gps.altitude}, sats={gps.satellites_in_use}, hdop={gps.hdop}, ttff={first_fix:.0f}")
        else:
            print("위성 찾는 중: 하늘이 트인 곳에서 몇 분 기다려요")
    time.sleep_ms(50)
  • 시작할 때 예시 문장으로 체크섬 계산을 확인해요. "47"이 나오면 XOR 계산을 바르게 이해한 거예요.
  • uart.read()가 준 바이트를 한 글자씩 gps.update()에 넣어요. 라이브러리가 문장을 모으고, 체크섬이 맞는 문장만 해석해요.
  • MicropyGPS(9, 'dd')의 9는 시간대(UTC+9), 'dd'는 위도·경도를 소수 도(예: 35.5)로 달라는 뜻이에요. 기본값은 도와 분을 따로 주는 형식이라 지도 앱에 바로 넣기 어려워요.
  • 위치를 잡은 뒤에는 1초마다 위도·경도, 속도(km/h), 고도(m), 위성 수, HDOP, 처음 잡는 데 걸린 시간(ttff, 초)을 내보내요.

값 해석과 보정

위도 1°는 약 111km예요(지구 둘레 약 4만km ÷ 360). 경도 1°는 위도에 따라 줄어서, 북위 35도 남짓인 울산에서는 위도 1°의 약 0.8배예요. 그래서 소수 여섯째 자리(0.000001°)는 10cm 남짓이에요. 화면에 여섯 자리가 나와도 정확도가 10cm라는 뜻은 아니에요. 정확도는 데이터시트의 2.5m보다 나쁘다고 생각하고, 같은 자리에서 여러 번 재서 흩어진 정도로 직접 확인해요(탐구 2).

HDOP는 위성들이 하늘에 얼마나 고르게 흩어져 있는지를 나타내요. 작을수록 좋고, 건물 옆처럼 하늘 한쪽이 막히면 커져요. 탐구할 때는 HDOP와 위성 수를 함께 적어 두고, 위성이 4개보다 적은 줄은 빼요.

속도는 수신기가 계산해 RMC 문장에 노트로 넣은 값을 라이브러리가 km/h로 바꾼 거예요. 데이터시트의 속도 정확도 0.1m/s는 0.36km/h라서, 가만히 있어도 0.3km/h 같은 값이 나올 수 있어요. 걷기나 달리기처럼 그보다 충분히 큰 속도를 비교해요.

고도는 위치보다 오차가 커요. 데이터시트도 같은 조건의 3차원 오차(SEP)를 3.5m 미만으로, 수평보다 크게 적어요. 층 사이 높이처럼 작은 차이는 기압으로 재는 편이 나아요(BME280 기압 고도).

자주 하는 실수

  1. TX를 TX에 잇기. 아무 문장도 해석되지 않아 "위성 찾는 중"만 나와요. 엇갈려 이어요.
  2. 실내 책상에서 기다리기. 위성 신호가 약해 위치를 못 잡거나 아주 오래 걸려요. 창가나 운동장으로 나가요.
  3. I²C 센서를 GP4·GP5에 함께 꽂기. UART1과 핀이 겹쳐요. 한쪽을 다른 핀 묶음으로 옮겨요.
  4. 도·분 형식을 소수 도로 착각하기. 4807.038은 48.07038°가 아니라 48° 07.038′(약 48.1173°)이에요.
  5. 켜자마자 나온 위치를 바로 쓰기. 처음 몇 줄은 HDOP가 크고 위성이 적은 경우가 많아요. 위성 수와 HDOP를 보고 거를 줄을 정해요.

이 센서로 잴 수 있는 탐구

1. 처음 위치를 잡기까지 몇 초 걸릴까 - 질문: 운동장 가운데, 건물 바로 옆, 창가 안쪽에서 처음 위치를 잡는 시간이 얼마나 다를까? - 바꾸는 것: 장소 세 곳 - 재는 것: ttff(초), 그때의 위성 수와 HDOP - 방법: USB를 꽂아 GPS와 피코를 함께 켠 직후 코드를 실행해요. 시도 사이에는 전원을 같은 시간(예: 10분) 끊어 조건을 맞추고, 장소마다 3번 해요. 데이터시트의 콜드 스타트 27초, 핫 스타트 1초와 비교해요.

2. 가만히 둔 GPS의 위치는 얼마나 흔들릴까 - 질문: 같은 자리에 둔 GPS의 위치는 하늘이 트인 곳과 건물 옆에서 얼마나 다르게 흩어질까? - 바꾸는 것: 장소(운동장 가운데, 건물 벽에서 2m) - 재는 것: 10분 동안 각 점이 평균 위치에서 떨어진 거리(m)의 중앙값과 최댓값 - 방법: 받침 위에 모듈을 두고 10분 기록해요. 위도·경도 차이를 m로 바꿔(위도 1° ≈ 111km, 경도는 위도 1°의 약 0.8배) 계산하고, 장소마다 다른 날 2번 해요.

3. GPS 속도는 스톱워치와 맞을까 - 질문: 50m를 일정하게 걸을 때 GPS가 보여 주는 속도는 50m ÷ 걸린 시간과 얼마나 다를까? - 바꾸는 것: 걷는 빠르기(천천히, 보통, 빠르게) - 재는 것: 구간 동안 kmh의 평균과 스톱워치로 구한 속도(km/h)의 차이 - 방법: 트랙의 직선 50m에 출발선과 도착선을 표시해요. 노트북을 든 사람은 함께 걷고 다른 사람이 시간을 재요. 빠르기마다 3번 반복해요.

안전

  • 다른 사람의 위치를 몰래 기록하지 않아요. 친구의 가방에 넣거나 친구를 따라다니며 기록하는 일은 하지 않고, 기록은 자기 이동이나 허락을 받은 실험만 해요.
  • 집이나 학교처럼 사는 곳을 알 수 있는 좌표는 발표 자료에 그대로 싣지 않아요. 분석이 끝난 원본 기록은 지우거나, 소수점 셋째 자리 정도로 줄여서 남겨요.
  • 밖에서 걸으며 기록할 때는 화면을 보며 걷지 않아요. 차가 다니는 길이 아닌 운동장이나 트랙에서만 해요.
  • 이 장치를 길 안내나 사람의 안전을 판단하는 데 쓰지 마세요.

더 알아보기

글쓴이

홍창민 · 울산 학성고등학교 정보·인공지능 교사. 수업에 쓰는 도구(시나브로 PICO 웹 IDE, 학교 AI 서버 등)를 직접 만들어 운영해요. 소개 보기 · 고칠 곳 알려 주기