NEO-M8N GPS 모듈이 탑재된 ESP32: GPS 로거 및 Google Earth 디스플레이
Arduino IDE로 프로그래밍된 ESP32와 NEO-M8N GPS 모듈을 연결하여 위도, 경도, 고도, UTC 시간, 가시 위성 수 등의 GPS 데이터를 가져오는 방법을 알아봅니다. 마지막으로, GPS 데이터를 microSD 카드의 파일에 기록하고, 이 데이터를 처리하여 Google Earth에 경로를 표시하는 방법을 알아봅니다.

NEO-8M GPS 모듈이 탑재된 ESP32: GPS 로거 및 Google Earth 디스플레이
요약하자면, 이 튜토리얼에서는 다음 내용을 배우게 됩니다.
- 직렬로 NEO-M8N GPS 모듈을 ESP32에 연결합니다.
- 원시 GPS 데이터를 얻으세요.
- 원시 데이터를 분석하여 선택되고 읽을 수 있는 GPS 정보를 얻습니다.
- 현재 위치를 확인하세요.
- 위치를 microSD 카드의 파일에 기록합니다.
- Google Earth에서 읽을 수 있는 .kml 파일 로 데이터를 변환합니다 .
- 경로를 표시하려면 .kml 파일을 Google Earth에 업로드하세요 .
목차
다음 주제를 다루겠습니다.
- NEO-M8N GPS 모듈 소개
- NEO-M8N GPS 모듈을 ESP32에 연결
- 원시 GPS 데이터 가져오기 – ESP32를 사용하여 NEO-M8N GPS 모듈 테스트
- TinyGPSPlus 라이브러리를 사용한 NMEA 문장 구문 분석
- Google Earth에서 GPS 로거 및 경로 표시
필수 조건
이 튜토리얼은 아두이노 코어를 사용하여 ESP32를 프로그래밍하는 데 중점을 둡니다. 진행하기 전에 아두이노 IDE에 ESP32 아두이노 코어가 설치되어 있어야 합니다. 아직 아두이노 IDE에 ESP32를 설치하지 않았다면 다음 튜토리얼을 따라 설치하세요.
Arduino IDE에 ESP32 보드 설치(Windows, Mac OS X 및 Linux 지침)
NEO-M8N GPS 모듈 소개
NEO-M8N GPS 모듈은 내비게이션 및 추적 프로젝트에서 마이크로컨트롤러와 함께 사용되는 가장 널리 사용되는 GPS 수신기 중 하나입니다. 위도, 경도, 고도 및 시간 데이터를 수신할 수 있습니다.
GPS, Galileo, GLONASS, BeiDou 등 다양한 위성 시스템을 지원합니다. NEO-6M 보다 향상된 위성 추적 기능을 제공하여 까다로운 환경에서도 더욱 안정적으로 작동합니다.
지금 제가 가지고 있는 모듈은 판매 제품입니다. 이미지는 이렇습니다.


NEO-M8N-GPS 모듈
데이터시트에 따르면, 수평 위치 정확도는 2.5~4m이고 시작 시간은 빠릅니다(핫 스타트 시 1초, 콜드 스타트 시 26~57초. 건물 근처에 있는 경우 시간이 더 오래 걸릴 수 있음).
이 모듈에는 백업 배터리, 내장 EEPROM, 위치 결정이 완료되면 깜박이는 LED 표시등이 포함되어 있습니다.
이 모듈에는 일반적으로 세라믹 GPS 안테나가 함께 제공됩니다. 하지만 프로젝트에 더 적합한 다른 호환 안테나로 교체할 수 있습니다. 예를 들어, 저는 아래 사진의 오른쪽 안테나를 사용하는 것을 선호하는데, 방수 기능이 있고 안테나에 긴 케이블이 포함되어 있어 더욱 유연하게 사용할 수 있기 때문입니다.

GPS 모듈용 안테나
NEO-M8N GPS 모듈은 직렬 통신 프로토콜을 사용하여 마이크로컨트롤러와 통신하며, 표준 NMEA 문장으로 작동합니다. NMEA는 National Marine Electronics Association의 약자로, GPS 분야에서는 GPS 제조업체가 지원하는 표준 데이터 형식입니다.
어디서 구매하나요?
Maker Advisor Tools 페이지에서 다양한 매장의 NEO-M8N GPS 수신기 모듈 가격을 비교해 보세요.
NEO-M8N GPS 수신기 모듈
NEO-M8N GPS 모듈을 ESP32에 연결
ESP32 기본 UART2 핀을 사용하여 NEO-M8N GPS 모듈을 연결합니다 . 다음 그림과 표를 참고하시기 바랍니다.

ESP32를 M8N에 배선
| NEO-M8N GPS Module | ESP32 |
| VCC | 3V3 |
| RX | TX2 (GPIO 17) |
| TX | RX2 (GPIO 16) |
| GND | GND |
원시 GPS 데이터 가져오기 – ESP32를 사용하여 NEO-M8N GPS 모듈 테스트
원시 GPS 데이터를 얻으려면 GPS 모듈과 직렬 통신을 시작하고 사용 가능한 데이터를 읽어야 합니다.
다음 코드는 GPS 모듈과 직렬 통신을 설정하고 사용 가능한 데이터를 읽습니다.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete instructions at https://RandomNerdTutorials.com/esp32-neo-m8n-gps-logger-google-earth/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
// Define the RX and TX pins for Serial 2
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
void setup(){
// Serial Monitor
Serial.begin(115200);
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
void loop(){
while (gpsSerial.available() > 0){
// get the byte data from the GPS
char gpsData = gpsSerial.read();
Serial.print(gpsData);
}
delay(1000);
Serial.println("-------------------------------");
}
코드는 어떻게 작동하나요? 아래 설명에 코드를 코드 블럭에 넣어야 하지만 시간이 걸려서 그냥 텍스트로 표기합니다.
이 스케치는 당신이 다음을 사용한다고 가정합니다.GPIO 16그리고GPIO 17GPS 모듈과 직렬 통신을 설정하기 위해 RX 및 TX 직렬 핀을 사용합니다. 다른 핀을 사용하는 경우 다음 줄을 수정해야 합니다.
// Define the RX and TX pins for Serial 2
#define RXD2 16
#define TXD2 17
또한, 모듈이 9600bps가 아닌 다른 기본 통신 속도를 사용하는 경우 다음 줄의 코드를 수정해야 합니다.
#define GPS_BAUD 9600
그런 다음 UART 2를 사용하기 위해 HardwareSerial의 인스턴스를 생성하며, 이를 gpsSerial이라고 명명합니다.
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
setup() 함수에서 시리얼 모니터를 초기화합니다.
// Serial Monitor
Serial.begin(115200);
그런 다음 GPS 모듈과 직렬 통신을 초기화합니다.
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
loop() 함수 내에서 코드는 GPS 시리얼 포트를 수신 대기하며, 모듈로부터 데이터가 수신되면 시리얼 모니터에 출력됩니다.
void loop(){
while (gpsSerial.available() > 0){
// get the byte data from the GPS
char gpsData = gpsSerial.read();
Serial.print(gpsData);
}
delay(1000);
Serial.println("-------------------------------");
}
코드 테스트
다음 아이콘을 클릭하여 컴파일과 업로드(플래싱)을 실행하세요. 코드를 보드에 업로드하세요.

Arduino IDE 2 업로드 버튼
안테나가 연결되어 있고, 모듈이나 안테나가 창문 밖이나 옆에 놓여 위성에서 데이터를 받을 수 있는지 확인하세요.

만약 이런 형태라면요. NEO-6M용 액티브 GPS 안테나
모듈의 파란색 LED는 위치가 고정되면 깜박이기 시작합니다.
직렬 모니터는 GPS 데이터가 포함된 NMEA 문장을 표시합니다.
중요: 이 스케치를 처음 실행하는 경우 모듈이 위치를 확인하는 데 몇 분 정도 걸릴 수 있습니다. 심지어 10분 정도 소요되는 경우도 있습니다. 인내심을 가지세요. 파란색 LED가 깜박이기 시작하면 실제 데이터를 수신하기 시작합니다. 건물 내부에 있는 경우 GPS 데이터를 수신할 가능성이 매우 낮습니다. 위성 신호를 수신할 가능성을 높이려면 실외로 나가거나 안테나를 실외에 설치하세요.

ESP32 및 NEO-M8N을 사용하여 원시 GPS 데이터 가져오기
GPS 표준 언어인 NMEA로 많은 정보를 얻을 수 있을 겁니다. 직렬 모니터에 표시되는 각 줄은 NMEA 문장입니다.
NMEA는 National Marine Electronics Association의 약자로, GPS 분야에서는 GPS 제조업체가 지원하는 표준 데이터 형식입니다.
NMEA 문장
NMEA 문장은 $ 문자로 시작하고, 각 데이터 필드는 쉼표로 구분됩니다.
$GNRMC,115209.00,A,4114.5500,N,00861.4900,W,0.129,,160125,,,D*XX
$GNVTG,,T,,M,0.129,N,0.239,K,D*XX
$GNGGA,115209.00,4114.5500,N,00861.4900,W,2,10,0.93,130.6,M,50.1,M,,0000*XX
$GNGSA,A,3,24,25,28,32,29,,,,,,,,1.65,0.93,1.37*XX
$GNGSA,A,3,78,66,67,77,,86,26,083,20*XX
$GLGSV,3,3,09,87,13,131,*XX
$GNGLL,4114.5500,N,00861.4900,W,115209.00,A,D*XX
NMEA 문장에는 여러 유형이 있습니다. 메시지 유형은 첫 번째 쉼표 앞의 문자로 표시됩니다.
$ 뒤의 GN 은 GPS 위치임을 나타냅니다. $GNGGA는 3D 위치 및 정확도 데이터를 제공하는 기본 GNSS NMEA 메시지입니다.
다음 문장에서:
$GNGGA , 110827.00, 4114.32485, N, 00831.79799, W, 1, 10, 0.93, 130.6, M, 50.1, M,, *5F
M8N의 필드 모양은 다음과 같습니다.
- $GNGGA: 글로벌 GNSS 위치 데이터.
- 110827.00: UTC 시간(11:08:27).
- 4114.32485,N: 위도.
- 00831.79799,W: 경도.
- 1: 품질 수정(1 = GPS 수정, 2 = DGPS 등).
- 10: 추적된 위성 수(NEO-6M에 비해 M8N이 더 높음).
- 0.93: 정밀도의 수평 희석(낮을수록 좋음).
- 130.6,M: 해발 고도(미터)
- 50.1,M: WGS84 타원체 위의 지오이드 높이.
- *5F: NEO-M8N에 대한 체크섬을 재계산했습니다.
다른 NMEA 문장은 추가 정보를 제공합니다.
- $GNRMC – 필수 GNSS PVT(위치, 속도, 시간) 데이터
- $GNVTG – 속도 및 트랙 정보
- $GNGGA – GNSS 수정 정보
- $GNGSA – GNSS DOP 및 활성 위성
- $GLGSV – 상세 위성 정보(GLONASS)
- $GNGLL – 지리적 위도와 경도.
NMEA 문장에 대한 자세한 내용을 알고 싶은 경우, 매우 자세한 정보를 제공하는 이 웹사이트를 찾아가세요 .
이 온라인 NME 분석기를 사용하여 문장을 붙여넣어 GPS 데이터를 해석할 수 있습니다.
하지만 원하는 GPS 데이터를 얻고 해석하는 가장 쉬운 방법은 코드에서 NMEA 문장을 직접 파싱하는 것입니다. 이를 위해 NMEA 문장에서 데이터를 쉽게 추출하는 메서드를 제공하는 TinyGPSPlus 라이브러리를 사용할 수 있습니다.
TinyGPSPlus 라이브러리를 사용한 NMEA 문장 구문 분석, 파싱 방법
TinyGPSPlus 라이브러리를 사용하면 GPS 데이터를 이해하기 쉬운 형식으로 쉽게 얻을 수 있습니다. TinyGPSPlus 라이브러리에 대한 자세한 내용은 여기를 클릭하세요.
TinyGPSPlus 라이브러리 설치
Arduino IDE에서 스케치 > 라이브러리 포함 > 라이브러리 관리 로 이동 하거나 왼쪽 사이드바에서 라이브러리 관리자 아이콘을 클릭합니다.
TinyGPSPlus 를 검색하여 Mikal Hart의 라이브러리를 설치하세요.

TinyGPSPlus 라이브러리 Arduino IDE 설치
NEO-M8N GPS 모듈과 TinyGPSPlus 라이브러리를 사용하여 GPS 데이터 가져오기
다음 코드는 다음을 사용하여 GPS 데이터를 가져오는 방법을 보여줍니다.타이니GPS플러스라이브러리. 날짜, 시간, 속도, 고도, 가시 위성 수, 그리고 HDOP(신호 정확도 측정 단위)를 얻을 수 있습니다.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete instructions at https://RandomNerdTutorials.com/esp32-neo-m8n-gps-logger-google-earth/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include <TinyGPS++.h>
// Define the RX and TX pins for Serial 2
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600
// The TinyGPS++ object
TinyGPSPlus gps;
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
void setup() {
// Serial Monitor
Serial.begin(115200);
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
void loop() {
// This sketch displays information every time a new sentence is correctly encoded.
unsigned long start = millis();
while (millis() - start < 1000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated()) {
Serial.print("LAT: ");
Serial.println(gps.location.lat(), 6);
Serial.print("LONG: ");
Serial.println(gps.location.lng(), 6);
Serial.print("SPEED (km/h) = ");
Serial.println(gps.speed.kmph());
Serial.print("ALT (min)= ");
Serial.println(gps.altitude.meters());
Serial.print("HDOP = ");
Serial.println(gps.hdop.value() / 100.0);
Serial.print("Satellites = ");
Serial.println(gps.satellites.value());
Serial.print("Time in UTC: ");
Serial.println(String(gps.date.year()) + "/" + String(gps.date.month()) + "/" + String(gps.date.day()) + "," + String(gps.time.hour()) + ":" + String(gps.time.minute()) + ":" + String(gps.time.second()));
Serial.println("");
}
}
}
코드는 어떻게 작동하나요? 마찬가지로 코드 블럭으로 작성하면 알아보기 쉽겠지만 시간이 아까워 전체 코드를 참고하시고, 저는 문장으로 입력합니다. 길면 당연히 코드 블럭으로 처리합니다. ^^
먼저 TinyGPSPlus 라이브러리를 임포트합니다.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
그런 다음 UART 2 RX 및 TX 핀과 GPS 통신 속도를 정의합니다. 보드에서 다른 UART 2 핀을 사용하거나 GPS 모듈에서 다른 통신 속도를 사용하는 경우, 다음 줄에서 해당 값을 수정할 수 있습니다.
// Define the RX and TX pins for Serial 2
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600
그런 다음 TinyGPSPlus 객체를 생성합니다:
TinyGPSPlus gps;
Serial 2에 대한 HardwareSerial 클래스의 인스턴스를 생성하고 gpsSerial이라고 명명합니다.
HardwareSerial gpsSerial(2);
setup() 함수에서 시리얼 모니터와 GPS 모듈과의 시리얼 통신을 초기화합니다.
void setup() {
// Serial Monitor
Serial.begin(115200);
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
루프() 함수 내에서 정보를 요청합니다. 다음과 같이 encode() 메서드를 사용하여 GPS 모듈의 데이터를 TinyGPSPlus 객체로 파싱합니다.
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
그런 다음 다음을 쿼리할 수 있습니다.GPS데이터 필드가 업데이트되었는지 확인하려면 객체를 사용하세요.
if (gps.location.isUpdated()) {
새로운 데이터가 있는 경우 다음과 같이 얻을 수 있습니다.
| Latitude | gps.location.lat() |
| Longitude | gps.location.lng() |
| Speed (km/h) | gps.speed.kmph() |
| Altitude (meters) | gps.altitude.meters() |
| HDOP | gps.hdop.value() |
| The number of visible satellites | gps.satellites.value() |
| Year | gps.date.year() |
| Month | gps.date.month() |
| Day | gps.date.day() |
| Hour | gps.time.hour() |
| Minutes | gps.time.minute() |
| Seconds | gps.time.second() |
위도 gps.위치.위도()
경도 gps.위치.lng()
속도(km/h) gps.속도.kmph()
고도(미터) gps.고도.미터()
HDOP gps.hdop.value()
눈에 보이는 위성의 수 gps.위성.값()
년도 gps.날짜.년()
월 gps.날짜.월()
낮 gps.날짜.요일()
시간 gps.시간.시간()
분 gps.시간.분()
초 gps.시간.초()
코드에서는 데이터를 가져와서 모든 정보를 직렬 모니터에 출력합니다.
Serial.print("LAT: ");
Serial.println(gps.location.lat(), 6);
Serial.print("LONG: ");
Serial.println(gps.location.lng(), 6);
Serial.print("SPEED (km/h) = ");
Serial.println(gps.speed.kmph());
Serial.print("ALT (min)= ");
Serial.println(gps.altitude.meters());
Serial.print("HDOP = ");
Serial.println(gps.hdop.value() / 100.0);
Serial.print("Satellites = ");
Serial.println(gps.satellites.value());
Serial.print("Time in UTC: ");
Serial.println(String(gps.date.year()) + "/" + String(gps.date.month()) + "/" + String(gps.date.day()) + "," + String(gps.time.hour()) + ":" + String(gps.time.minute()) + ":" + String(gps.time.second()));
Serial.println("");
코드 테스트
ESP32 보드에 코드를 업로드하세요. 시리얼 모니터를 115200 통신 속도로 실행하세요. 위성에서 데이터를 수신하려면 GPS 모듈이 창문 밖이나 창문 옆에 있어야 합니다.
참고: 모듈이 위치를 확정할 때까지 몇 초 또는 몇 분 정도 기다려야 할 수도 있습니다.

ESP32와 NEO-M8N을 사용하여 TinyGPSPlus로 파싱된 데이터 가져오기
현재 위치, 속도, 고도, 가시 위성 수(HDOP) 및 시간에 대한 데이터가 직렬 모니터에 표시됩니다.
HDOP는 수평 정밀도 희석(Horizontal Dilution of Precision)의 약자입니다. 이는 위치 결정 정확도를 측정하는 기준입니다. HDOP 값이 높을수록 위치 결정 정확도가 떨어집니다. 이상적으로는 2보다 낮은 값을 얻어야 합니다. 값이 낮을수록 정확도가 높아집니다.
Google Earth에서 GPS 로거 및 경로 표시
이제 ESP32와 함께 NEO-M8N GPS 모듈을 사용하는 방법에 익숙해졌으니, 시간 경과에 따른 위치를 microSD 카드의 파일에 기록하는 GPS 로거를 만들어 보겠습니다. 그런 다음 해당 파일을 수정하여 Google Earth에서 위치의 시간 경과에 따른 변화(경로)를 시각화할 수 있습니다.

ESP32 GPS 로거 M8N microSD 카드
프로젝트 개요
이 프로젝트가 어떻게 진행되는지 간략하게 살펴보겠습니다.
- ESP32는 NEO-M8N GPS 모듈에 연결되어 위치에 대한 데이터를 가져옵니다.
- 위치가 1미터 이상 변경되면 위치 데이터(위도, 경도, 고도)를 microSD 카드의 파일에 저장합니다.
- Google Earth에서 데이터를 시각화하기 위해 위치 좌표가 포함된 .txt 파일을 Google Earth에서 읽을 수 있는 .kml 파일로 수동으로 변환하는 방법을 보여드리겠습니다 .
- Google Earth에 .kml 파일을 업로드하여 해당 경로를 시각화하는 방법을 알려드리겠습니다 .
필요한 부품
이 프로젝트에 필요한 부품 목록은 다음과 같습니다.
- ESP32 보드 - 최고의 ESP32 개발 보드를 읽어보세요
- NEO-M8N GPS 모듈
- MicroSD 카드 모듈
- 마이크로SD 카드
- 브레드보드
- 점퍼 와이어
회로 연결
GPS 모듈을 ESP32 기본 UART2 핀에 연결하고(이전처럼), microSD 카드 모듈을 ESP32 기본 SPI 핀에 연결합니다 . 다음 다이어그램이나 표를 참고할 수 있습니다.

ESP32 GPS 로거 회로 NEO-8M GPS 모듈 회로도
다음 글도 읽어보시면 좋을 것 같습니다: ESP32: Arduino IDE를 사용한 MicroSD 카드 모듈 가이드.
| NEO-M8N GPS Module | ESP32 |
| VCC | 3V3 |
| RX | TX2 (GPIO 17) |
| TX | RX2 (GPIO 16) |
| GND | GND |
| MicroSD Card Module | ESP32 |
| 3V3* | 3V3 |
| CS | GPIO 5 |
| MOSI | GPIO 23 |
| CLK | GPIO 18 |
| MISO | GPIO 19 |
| GND | GND |
* 일부 microSD 카드 모듈에는 3V3 대신 5V가 필요합니다.
Code
다음 코드는 microSD 카드와 GPS 모듈을 초기화하고, 데이터 포인트가 사용 가능해지고 새로운 포인트가 이전 포인트에서 1미터 이상 떨어지면 GPS 데이터를 저장합니다.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete instructions at https://RandomNerdTutorials.com/esp32-neo-m8n-gps-logger-google-earth/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include <TinyGPS++.h>
#include <FS.h>
#include <SD.h>
#include <SPI.h>
// Define the RX and TX pins for Serial 2
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600
// The TinyGPS++ object
TinyGPSPlus gps;
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
String GPSdataToAppend;
// Previous GPS coordinates
double lastLat = 0.0;
double lastLng = 0.0;
// Initialize SD card
void initSDCard() {
if (!SD.begin()) {
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
}
// Append data to the SD card
void appendFile(fs::FS &fs, const char *path, const char *message) {
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file) {
Serial.println("Failed to open file for appending");
return;
}
if (file.print(message)) {
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void setup() {
// Serial Monitor
Serial.begin(115200);
// Initialize the microSD card
initSDCard();
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
void loop() {
unsigned long start = millis();
while (millis() - start < 1000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated()) {
double currentLat = gps.location.lat();
double currentLng = gps.location.lng();
// Check if the distance from the last point is at least 1 meter
double distance = TinyGPSPlus::distanceBetween(lastLat, lastLng, currentLat, currentLng);
if (distance >= 1.0) {
lastLat = currentLat;
lastLng = currentLng;
// Prepare data to append
GPSdataToAppend = String(currentLng, 6) + "," + String(currentLat, 6) + "," + String(gps.altitude.meters());
Serial.println(GPSdataToAppend);
// Append to file
appendFile(SD, "/data.txt", GPSdataToAppend.c_str());
}
}
}
}
Google Earth에서 읽을 수 있는 형식으로 데이터를 저장하려면 경도, 위도, 고도를 쉼표로 구분하여 이 순서대로 저장해야 합니다. 이 예제에서는 그렇게 합니다. 이후 해당 정보를 .kml 파일로 변환해야 합니다.
코드는 어떻게 작동하나요?
먼저 필요한 라이브러리를 가져오는 것부터 시작합니다.
#include <TinyGPS++.h>
#include <FS.h>
#include <SD.h>
#include <SPI.h>
그런 다음, 직렬 통신 프로토콜을 통해 GPS 모듈과 통신하는 데 사용할 핀을 정의합니다. 앞서 살펴본 것처럼 UART2 기본 핀을 사용합니다.
// Define the RX and TX pins for Serial 2
#define RXD2 16
#define TXD2 17
GPS 전송 속도를 정의하고 생성합니다.타이니GPS플러스인스턴스라고 함GPS, 하드웨어 직렬 2를 시작합니다.
#define GPS_BAUD 9600
// The TinyGPS++ object
TinyGPSPlus gps;
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
microSD 카드에 저장할 모든 정보(경도, 위도, 고도 순서)를 보관하는 문자열 변수를 생성합니다.
String GPSdataToAppend;
그런 다음, 마지막 위도와 경도 값을 저장하기 위해 다음 변수들을 초기화합니다. 이 변수들은 현재 위치와 마지막 위치를 비교하는 데 필요합니다.
// Previous GPS coordinates
double lastLat = 0.0;
double lastLng = 0.0;
initSDCard() 함수는 microSD 카드를 초기화하는 데 필요한 모든 메서드를 호출합니다.
// Initialize SD card
void initSDCard() {
if (!SD.begin()) {
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
}
appendFile() 함수는 마이크로 SD 카드의 파일에 데이터를 추가합니다. 해당 파일이 아직 존재하지 않으면 생성합니다.
// Append data to the SD card
void appendFile(fs::FS &fs, const char *path, const char *message) {
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file) {
Serial.println("Failed to open file for appending");
return;
}
if (file.print(message)) {
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
microSD 카드 기능에 대한 자세한 내용은 이 튜토리얼을 확인하세요: ESP32: Arduino IDE를 사용한 MicroSD 카드 모듈 가이드
setup() 함수에서 시리얼 모니터, 마이크로 SD 카드, GPS 모듈을 초기화합니다.
void setup() {
// Serial Monitor
Serial.begin(115200);
// Initialize the microSD card
initSDCard();
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
루프() 함수 내에서 매초마다 GPS 모듈로부터 새로운 데이터가 있는지 확인합니다. 데이터가 있으면 사용 가능한 데이터를 인코딩하여 현재 위도와 경도를 얻습니다.
unsigned long start = millis();
while (millis() - start < 1000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated()) {
double currentLat = gps.location.lat();
double currentLng = gps.location.lng();
그런 다음 현재 위치가 이전 위치와 최소 1미터 이상 차이가 있는지 확인합니다.
// Check if the distance from the last point is at least 1 meter
double distance = TinyGPSPlus::distanceBetween(lastLat, lastLng, currentLat, currentLng);
그렇다면 lastLat 및 lastLng 변수를 현재 위치로 업데이트합니다.
if (distance >= 1.0) {
lastLat = currentLat;
또한 microSD 카드에 저장할 문자열 형식의 데이터도 준비합니다.
GPSdataToAppend = String(currentLng, 6) + "," + String(currentLat, 6) + "," + String(gps.altitude.meters());
직렬 모니터에 데이터를 출력합니다.
Serial.println(GPSdataToAppend);
마지막으로, microSD 카드에 있는 data.txt 라는 파일에 데이터를 추가합니다 .
appendFile(SD, "/data.txt", GPSdataToAppend.c_str());
프로젝트 테스트
코드를 보드에 업로드하세요. microSD 카드가 초기화되고 몇 초 후에 microSD 카드에 데이터가 추가되기 시작합니다(실외에 있거나 창문 가까이에 있는지 확인하세요).

ESP32 GPS 데이터를 microSD 카드에 추가
모든 것이 예상대로 작동하는 것 같으면 ESP32를 컴퓨터에서 분리하고 휴대용 충전기나 배터리를 사용하여 전원을 공급하세요. 회로를 가지고 산책을 하면 시간이 지남에 따라 좌표가 기록되어 경로를 설계하는 데 필요한 상당한 양의 지점을 얻을 수 있습니다.
데이터를 기록한 후, microSD 카드를 모듈에서 분리하여 컴퓨터에 연결하세요. microSD 카드에는 경로 좌표가 저장된 data.txt 파일이 있습니다.
해당 데이터를 Google Earth에 업로드하고 경로를 설계하려면 해당 파일을 .kml 형식으로 변환해야 합니다.
KML 파일
KML은 Google Earth와 같은 어스 브라우저에서 지리 데이터를 표시하는 데 사용되는 파일 형식입니다. KML은 중첩된 요소와 속성을 가진 태그 기반 구조를 사용하며 XML 표준을 기반으로 합니다. 이 파일의 구조에 대해서는 자세히 설명하지 않겠습니다. 더 자세한 내용은 Google의 KML 파일 튜토리얼을 참조하세요 .
data.txt 파일을 .kml 형식으로 변환
1) GPS 모듈에서 수집한 GPS 데이터가 있는 data.txt 파일 을 엽니다 .
2) 좌표가 다음 사이에 있도록 파일을 편집합니다.<좌표></좌표>태그는 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Style id="yellowPoly">
<LineStyle>
<color>7f00ffff</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7f00ff00</color>
</PolyStyle>
</Style>
<Placemark><styleUrl>#yellowPoly</styleUrl>
<LineString>
<extrude>1</extrude>
<tesselate>1</tesselate>
<altitudeMode>absolute</altitudeMode>
<coordinates>
YOUR COORDINATES GO HERE
</coordinates>
</LineString></Placemark>
</Document></kml>
3) 해당 파일을 저장합니다.
4) 파일 이름을 data.txt 에서 data.kml 로 변경하세요 . 파일 형식을 변경하라는 경고 메시지가 표시됩니다. 수락하세요. 이제 파일을 Google Earth에 업로드할 수 있습니다.
Google Earth에 경로 표시
이제 다음 단계에 따라 Google Earth에서 경로를 표시하고 시각화해 보세요.
1) Google Earth 웹사이트 로 이동합니다 .
2) 새로운 프로젝트를 만들고 이름을 지정합니다.

Google Earth - 프로젝트 만들기
3) 파일 > 프로젝트로 파일 가져오기 > 장치 에서 업로드로 이동합니다 .

Google Earth에 파일 업로드
4) 이전에 만든 .kml 파일을 선택합니다 .
5) 귀하의 경로는 노란색 윤곽선으로 Google Earth에 표시됩니다.

Google Earth의 ESP32 표시 경로
마무리하기
이 가이드에서는 ESP32와 함께 NEO-M8N GPS 모듈을 사용하는 방법과 위치 및 시간에 대한 정보를 얻는 방법을 알아보았습니다.
또한 GPS 데이터를 microSD 카드에 기록하는 방법과 Google Earth에서 경로를 표시하기 위해 해석할 수 있는 형식으로 해당 데이터를 편집하는 방법도 알려드렸습니다.
여기까지 고생하셨습니다. 즐거운 개발 되세요. 마지막 인사는 여기까지 읽어주셔서 감사합니다.
'ESP32' 카테고리의 다른 글
| ESP32 유용한 Wi-Fi 라이브러리 함수(Arduino IDE) (1) | 2025.12.04 |
|---|---|
| ESP32 SIM800L 및 NEO-6M 모듈을 사용한 GPS 추적기 (1) | 2025.12.04 |
| ESP32 MFRC522 RFID 쓰기 읽기 Arduino IDE (0) | 2025.12.03 |
| Arduino IDE와 ESP-IDF 개발 환경 비교 (0) | 2025.12.02 |
| ESP32 L298N 모터 드라이버 인터페이스법 (0) | 2025.11.30 |
| GPS 데이터 지도에 그려주는 사이트 (0) | 2025.11.29 |
| ESP32 NEO-6M GPS 모듈 문제 해결 가이드 (0) | 2025.11.28 |
| ESP32 NEO-6M GPS 모듈 인터페이스 (0) | 2025.11.28 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
캐어랩