본문 바로가기

ESP32

ESP32 NEO-6M GPS 모듈 인터페이스

반응형

 

임베디드 엔지니어로서 전자 산업에 종사하고 있다면 움직이는 물체의 위치를 ​​파악하거나 특정 위치의 고도와 속도를 측정해야 하는 상황이 발생할 수 있습니다. 이러한 상황에서 GPS 모듈은 매우 유용할 수 있습니다. 따라서 이 글에서는 NEO-6M GPS GSM 모듈을 ESP32와 연동하는 방법을 살펴보겠습니다 . 또한 이 장치의 모든 장단점도 알려드릴 테니, 더 이상 미루지 않고 바로 시작해 보겠습니다.

 

 

ESP32와 NEO-6M GPS 모듈

 

 

NEO-6M GPS 모듈 핀아웃

 

NEO-6M GPS 모듈에는 GND, TxD, RxD, VCC의 네 개의 핀이 있습니다. TxD와 RxD 핀은 마이크로컨트롤러와 통신하는 데 사용됩니다.

 

 

NEO-6M GPS 모듈 핀아웃

 

  • GND: GPS 모듈의 접지 핀이며 ESP32의 접지 핀에 연결해야 합니다.
  • TXD: GPS 모듈의 송신 핀은 ESP32의 RX 핀에 연결해야 합니다.
  • RXD: GPS 모듈의 수신 핀은 ESP32의 TX 핀에 연결해야 합니다.
  • VCC: GPS 모듈의 전원 핀이며 ESP32의 3.3V 핀에 연결해야 합니다.

 

NEO-6M GPS 모듈 – 부품

 

NEO-6M 모듈은 다양한 용도로 사용할 수 있는 바로 사용 가능한 GSM 모듈입니다. NEO-6M GPS 모듈의 구성품은 다음과 같습니다.

 

 

 

NEO-6M GPS 모듈 구성 요소

 

NEO-6M GPS 모듈은 보드에 다섯 가지 주요 부품으로 구성되어 있습니다. 첫 번째 주요 부품은 PCB 중심부에 있는 NEO-6M GPS 칩입니다. 다음으로 충전식 배터리와 직렬 EEPROM 모듈이 있습니다. 배터리와 함께 제공되는 EEPROM은 시계 데이터, 최신 위치 데이터(GNSS 궤도 데이터), 그리고 모듈 구성을 유지하는 데 도움이 되지만, 영구적인 데이터 저장을 위한 것은 아닙니다. 배터리가 없으면 GPS가 항상 콜드 스타트(cold start) 상태로 시작되므로 초기 GPS 잠금에 더 많은 시간이 소요됩니다. 배터리는 전원이 공급되면 자동으로 충전되며, 전원 없이도 최대 2주 동안 데이터를 유지합니다. 다음으로 LDO(Low Dropout)가 있습니다. 온보드 LDO 덕분에 모듈은 5V 전원으로 전원을 공급받을 수 있습니다. 마지막으로 GPS가 제대로 작동하려면 외부 안테나를 연결해야 하는 UFL 커넥터가 있습니다.

 

NEO-6M GPS 모듈 개요

 

 

안테나가 있는 NEO-6M GPS 모듈

 

글로벌 위치 시스템(GPS)은 지구 궤도를 도는 31개의 위성으로 구성된 시스템입니다. 위성들은 무선 신호를 통해 시간에 따른 위치 정보를 지속적으로 전송하기 때문에 우리는 위성의 정확한 위치를 알 수 있습니다. 브레이크아웃 보드의 핵심에는 u-blox에서 설계 및 개발한 NEO-6M GPS 모듈이 있습니다. 이 모듈은 매우 작지만 많은 기능을 갖추고 있습니다. 50개 채널에 걸쳐 최대 22개의 위성을 추적할 수 있으며, 소비 전류는 45mA에 불과하고 작동 전압은 2.7V ~ 3.6V입니다. 이 모듈의 가장 흥미로운 기능 중 하나는 절전 모드입니다. 이를 통해 시스템 전력 소비를 줄일 수 있습니다. 절전 모드를 켜면 모듈의 전류 소비가 11MA로 줄어듭니다. NEO-6M GPS 모듈에 대한 자세한 내용은 아래 파일로 제공하는 NEO-6M 모듈 데이터시트를 확인하세요 .

 

 

NEO6MV2 GPS Module Datasheet.pdf
1.30MB

 

 

위치 고정 LED 표시기:

 

NEO-6M GPS 모듈 보드를 자세히 살펴보면 GPS 모듈이 위성과 통신할 수 있음을 나타내는 작은 LED를 찾을 수 있습니다.

 

  • 깜박이지 않으면, 위성을 찾고 있습니다.

 

NEO-6M GPS 모듈 LED 표시기

 

  • 1초마다 깜박임 – 위치 고정이 발견되었습니다(모듈이 충분한 위성을 볼 수 있음).

 

NEO-6M GPS 모듈 위치 고정 LED 표시기

 

안테나:

 

이 모듈에는 GPS 위성의 무선 신호를 수신할 수 있는 -161dBm 감도의 패치 안테나가 포함되어 있습니다. 이 안테나는 이 기사의 부품 표시 부분에서 언급한 소형 UFL 커넥터에 연결할 수 있습니다.

 

 

안테나

 

대부분의 실외 애플리케이션에서는 패치 안테나가 잘 작동하지만, 더 까다롭거나 실내 애플리케이션에서는 3V 능동 GPS 안테나를 사용하는 것이 좋습니다.

 

NEO-6M GPS 모듈에 대한 자주 묻는 질문

 

Q. NEO-6M의 정확도는 어느 정도인가요?

 

데이터시트에 따르면 NEO-6M 장치는 이상적인 조건에서 2.5m GPS 수평 위치 정확도를 제공합니다.

 

Q. GPS 모듈이 작동하는지 어떻게 알 수 있나요?

 

NEO-6M GPS 모듈에 전원과 UART 컨버터를 연결하고, 통신 속도를 9600으로 설정합니다. 모든 것이 올바르게 작동한다면 모듈에서 1초마다 데이터가 출력되어야 합니다.

 

Q. GPS 안테나란 무엇인가요?

 

GNSS 또는 GPS 안테나는 GNSS 위성에서 특정 주파수로 전송되는 무선 신호를 수신하고 증폭하여 GNSS 또는 GPS 수신기에서 사용할 수 있는 전자 신호로 변환하도록 설계된 장치입니다.

 

Q. GPS에 위성이 4개 필요한 이유는 무엇인가요?

 

마법의 숫자는 4입니다. GPS가 정확한 위치를 계산하는 방식 때문입니다. 각 위성은 1) 신호가 전송된 정확한 시간과 2) 지구 중심을 기준으로 한 위성의 정확한 위치를 포함하는 신호를 전송합니다.

 

Q. GPS는 어떤 주파수를 사용하나요?

 

모든 GPS 위성은 최소 2개의 반송 주파수, 즉 1575.42MHz의 L1과 1227.6MHz의 L2에서 방송합니다(최신 위성은 1176MHz의 L5에서도 방송합니다).

 

NEO-6M GSM 모듈 회로도

 

NEO-6M GPS 모듈의 회로는 매우 간단하고 이해하기 쉽습니다. 이 모듈에서는 모든 주요 작업이 GPS 모듈에 의해 처리되며, GPS 모듈 작동을 위해서는 두세 개의 부품이 더 필요합니다. NEO-6M GPS 모듈의 전체 회로도는 아래와 같습니다.

 

 

NEO-6M GPS 모듈 개략도

 

회로도에는 입력 전압을 5V에서 3.3V로 변환하는 3.3V 전압 레귤레이터와 AT24C33 EEPROM, 그리고 배터리가 있습니다. EEPROM과 배터리는 배터리로 백업되는 RAM을 유지하는 데 도움을 주며, RAM은 일정 시간 동안 클럭 데이터와 위치를 저장할 수 있습니다. 그 외에도 모듈의 정상 작동을 위해 외부 패치 안테나를 연결해야 하는 UFL 커넥터가 있습니다.

 

ESP32 NEO-6M GPS 모듈 회로도

 

이제 NEO-6M GPS 모듈에 대해 완전히 이해했으므로 필요한 모든 전선을 ESP32 보드에 연결하고 모듈이 제대로 작동하는지 또는 오류가 발생하는지 확인할 수 있습니다. 다음으로, 코드를 작성하고 수신된 GPS 데이터를 디코딩해 보겠습니다. NEO-6M GPS 모듈과 ESP32의 연결 다이어그램은 아래와 같습니다.

 

 

 

GPS 모듈 회로 연결을 갖춘 ESP32

 

 

 

NMEA 문장 이해

 

모듈을 USB-UART 변환기에 연결하고 직렬 모니터 창을 열면 NEO-6M GPS 모듈에서 출력되는 데이터를 확인할 수 있습니다. 이를 NMEA 문장이라고 하는데, NMEA는 National Marine Electronics Association의 약자로 , 거의 모든 GPS 수신기의 표준 메시지 형식입니다. 직렬 모니터 창의 스크린샷은 아래와 같습니다.

 

 

NMEA 문장

 

NMEA 문장은 $ 문자 로 시작하고 , 각 데이터 필드는 쉼표로 구분됩니다.

 

NMEA 문장에는 여러 유형이 있습니다. 이러한 유형은 첫 번째 쉼표 앞의 첫 글자로 구분됩니다. $ 기호 뒤의 GP는 GPS 위치 데이터 임을 나타냅니다 . $GPGGA 는 3D 위치 데이터를 제공하는 기본 NEMA 메시지입니다.

 

$GPGGA, 130113.00, 37XX.XXXX,N, 07XXX.XXXX, E,1,04,3.97,404.9,M,45.7,M,,*79

130113 - 데이터가 수집된 시간인 13:01:13 UTC를 나타냅니다.

37XX.XXXX,N - 위도 37도 XX.XXXX' N

07XXX.XXXX,E - 경도 007도 07XXX.XXXX,E

1 - 품질 수정(0 = 유효하지 않음; 1 = GPS 수정; 2 = DGPS 수정; 3 = PPS 수정; 4 = 실시간 운동학; 5 = 플로트 RTK; 6 = 추정(추정 항법); 7 = 수동 입력 모드; 8 = 시뮬레이션 모드)

04 – 추적 중인 위성 수

3.97 – 위치의 수평 희석

404.9, M – 해발 고도(미터)

45.7, M – WGS84 타원체 위의 지오이드(평균 해수면) 높이

비어 있음 - DGPS 업데이트 시간

비어 있음 - DGPS 스테이션 ID

*79 – 체크섬 데이터는 항상 *로 시작합니다.

 

NMEA 문장은 매우 다양합니다. 더 자세한 내용을 알고 싶으시다면 GIDS 웹사이트를 방문하세요 . 모든 기본 정보가 정리되어 있습니다.

 

ESP32와 NEO-6M GPS 인터페이싱을 위한 코드

 

모듈을 직렬 모니터에 연결하면 위에서 언급한 직렬 모니터 창에 출력이 표시됩니다. 원한다면 이러한 유형의 데이터를 다룰 수도 있지만, 가장 쉬운 방법은 라이브러리를 사용하여 모든 GPS 데이터를 파싱하고 나중에 사용할 수 있도록 변수에 저장하는 것입니다. 코드에서는 정확히 그렇게 할 것입니다. Mike Hart의 TinyGPSPlus-ESP32 라이브러리를 사용할 것입니다. 라이브러리는 GitHub에서 다운로드하거나 Arduino의 라이브러리 관리자를 사용하여 설치할 수 있습니다.

 

이제 모든 준비가 완료되었으므로 ESP32 코드 작성 단계로 넘어가겠습니다. 먼저 필요한 모든 라이브러리를 포함시키는 것부터 시작합니다. 예제가 매우 간단하므로 라이브러리를 하나만 사용합니다.

 

#include <TinyGPSPlus.h>

 

다음으로, 라이브러리 작업을 위해 TinyGPSPlus 객체를 생성합니다 .

 

TinyGPSPlus GPS;

 

다음으로, setup 함수 가 있습니다 . setup 함수에서는 ESP32 모듈의 Serial 과 Serial2를 초기화하여 PC와 GPS 모듈 모두와 통신할 수 있도록 합니다. 즉, Serial 은 ESP32 실행할 때 아두이노 IDE 시리얼 모니터로 전송하는 데이터에 사용하고, Serial2는 GPS ㅁ모듈 데이터를 받아오는 기능에 사용합니다. 기억하세요!

 

void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);
  delay(3000);
}

 

다음으로 updateSerial() 함수 가 있습니다 . 이 함수는 UART1 과 UART2 사이의 루프백 역할을 하며 , 이를 통해 시리얼 모니터 창에서 수신 데이터를 모니터링할 수 있습니다.

 

void updateSerial(){
  delay(500);
  while (Serial.available())  {
    Serial2.write(Serial.read()); //시리얼 모니터에서 입력한 데이터를 GPS 모듈로 전송합니다.
  }
  while (Serial2.available())  {
    Serial.write(Serial2.read());//소프트웨어 직렬에서 수신한 내용을 시리얼 모니터로 전달합니다.
  }
}

 

 

다음으로, displayInfo() 함수가 있습니다 . 이 함수에서 TinyGPSPlus 라이브러리 의 gps.location.lat() 및 gps.location.lng() 메서드를 사용하여 GPS 위도와 경도를 구문 분석하고 이를 직렬 모니터 창에 출력합니다.

 

void displayInfo()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid()){
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }
}

 

마지막으로 루프 함수가 있습니다 . 루프 함수에서 먼저 updateSerial() 함수를 호출하고 주석 처리했습니다. 기기를 처음 실행하거나 GPS 모듈을 디버깅하는 경우 주석 처리를 해제할 수 있습니다. 다음으로, serial2가 사용 가능한지 확인합니다. serial2를 사용할 수 있으면 displayInfo() 함수를 호출합니다. 이 함수는 위도와 경도 데이터를 반환합니다.

 

void loop() {
  //updateSerial();
  while (Serial2.available() > 0)
    if (gps.encode(Serial2.read()))
      displayInfo();
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while (true);
  }
}

 

이것으로 코딩 부분이 끝났고 이제 기사의 다음 부분으로 넘어갈 수 있습니다.

 

NEO-6M GPS 모듈의 작동

 

아래 gif는 NEO-6M GPS 모듈의 작동 방식을 보여줍니다. ESP32가 초기화된 후 모듈이 작동하는지 확인하고 직렬 모니터 창에 출력을 표시하도록 코드를 작성했습니다. 모든 확인 절차가 완료되면 모듈은 사용 가능한 데이터가 있는지 확인하고 직렬 모니터 창에 출력합니다.

 

NEO-6M GPS 모듈 디버깅

 

NEO-6M GPS 모듈을 사용하는 동안 여러 가지 문제에 직면했습니다. 이 글의 이 섹션에서는 그러한 문제 중 일부를 논의하겠습니다.

 

  • ESP32를 사용하여 GPS 모듈과 통신하므로 처음에는 ESP의 3.3V 레일로 전원을 공급하는 것이 생각났지만 모듈에 전선이 연결되어 있지 않아 모듈을 작동시키려면 외부 배터리를 연결해야 했습니다.

 

  • 두 번째 큰 문제는 안테나였습니다. 실내에서 모듈을 사용하려고 생각 중이시라면, 안테나 성능이 매우 나빠서 실내에서는 위성 신호를 수신할 수 없기 때문에 작동하지 않을 것이라고 말씀드립니다.

 

GPS 모듈을 처음 사용하시는 분이라면, Neo 6M GP 모듈이 작동하지 않는 문제 해결 가이드 문서를 참고하여 이 모듈과 관련된 일반적인 문제와 해결 방법을 확인하세요.

 

제대로 동작하는 코드는 아래 코드를 참고하고 그 아래에 원래 있던 동작하지 않는 코드를 실었다.

 

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete instructions at https://RandomNerdTutorials.com/esp32-neo-6m-gps-module-arduino/
  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("-------------------------------");
}

 

 

결과는 시리얼 모니터를 클릭해 데이터를 확인한다.

 

$GPVTG,,T,,M,0.185,N,0.343,K,A*2B
$GPGGA,041435.00,3722.34287,N,12657.10112,E,1,06,1.20,47.9,M,18.5,M,,*62
$GPGSA,A,3,32,31,26,29,16,03,,,,,,,2.45,1.20,2.14*0D
$GPGSV,2,1,06,03,22,296,2800,A,A*64
-------------------------------
$GPRMC,041436.00,A,3722.34280,N,12657.10130,E,0.163,,291125,,,A*71
$GPVTG,,T,,M,0.163,N,0.303,K,A*27
$GPGGA,041436.00,3722.34280,N,12657.10130,E,1,06,1.20,47.7,M,18.5,M,,*68
$GPGSA,A,3,32,31,26,29,16,03,,,,,,,2.45,1.20,2.14*0D
$GPGSV,2,1,06,03,22,296,2800,A,A*60
-------------------------------
$GPRMC,041437.00,A,3722.34257,N,12657.10132,E,0.207,,291125,,,A*79
$GPVTG,,T,,M,0.207,N,0.383,K,A*2E
$GPGGA,041437.00,3722.34257,N,12657.10132,E,1,06,1.20,47.5,M,18.5,M,,*63
$GPGSA,A,3,32,31,26,29,16,03,,,,,,,2.45,1.20,2.14*0D
$GPGSV,2,1,06,03,22,296,2800,A,A*69

 

 

 

전체 코드로 제공하는 이 코드는 무언가 잘못되었다.

 

#include <TinyGPSPlus.h>
// The TinyGPSPlus object
TinyGPSPlus gps;
void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);
  delay(3000);
}
void loop() {
  //updateSerial();
  while (Serial2.available() > 0)
    if (gps.encode(Serial2.read()))
      displayInfo();
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while (true);
  }
}
void displayInfo()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid()){
    Serial.print("Lat: ");
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print("Lng: ");
    Serial.print(gps.location.lng(), 6);
    Serial.println();
  } 
  else
  {
    Serial.print(F("INVALID"));
  }
}
void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    Serial2.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while (Serial2.available())
  {
    Serial.write(Serial2.read());//Forward what Software Serial received to Serial Port
  }
}

 

 

위 튜토리얼의 번역 문서는 언제나 그렇듯이 이 링크를 따라가세요.

 

 

반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

당신의 성공을 위해 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩