Kết nối ESP32 với GPS module NEO-6M
Trong bài viết này, chúng ta sẽ tìm hiểu cách giao tiếp với module GPS NEO-6M bằng ESP32 để lấy dữ liệu GPS. Bạn sẽ biết cách lấy dữ liệu GPS thô và giải mã dữ liệu NMEA. Cuối cùng, chúng ta sẽ biết cách lấy được vĩ độ, kinh độ, độ cao, tốc độ, và thời gian UTC bằng cách sử dụng thư viện TinyGPSPlus.
Tóm tắt, trong hướng dẫn này, bạn sẽ học cách:
- Kết nối module GPS NEO-6M với ESP32 qua giao tiếp serial
- Lấy dữ liệu GPS thô
- Phân tích dữ liệu thô để lấy thông tin GPS đã chọn và dễ đọc
- Lấy vị trí hiện tại của bạn
Giới thiệu về module GPS NEO-6M
Module GPS NEO-6M là một thiết bị thu GPS tương thích với hầu hết các vi điều khiển. Nó có thể thu thập dữ liệu về vị trí, tốc độ, độ cao và thời gian.

Nó đi kèm với một pin dự phòng nhỏ, bộ nhớ EEPROM ngoài, và một đèn LED chỉ báo tín hiệu. Đèn LED này sẽ bắt đầu nhấp nháy khi nó nhận được tín hiệu định vị.
Thông thường, các module này đi kèm với một ăng-ten gốm GPS.

Tuy nhiên, bạn có thể thay đổi nó thành bất kỳ ăng-ten tương thích nào khác phù hợp hơn với dự án của bạn. Ví dụ, tôi thích sử dụng ăng-ten ở phía bên phải trong hình dưới đây vì nó chống nước và đi kèm với một dây cáp dài, cho phép linh hoạt hơn.

Module GPS NEO-6M giao tiếp với vi điều khiển bằng giao thức truyền thông serial.
Module này hoạt động với các câu NMEA chuẩn. NMEA là viết tắt của National Marine Electronics Association (Hiệp hội Điện tử Hàng hải Quốc gia), và trong lĩnh vực GPS, đây là một định dạng dữ liệu tiêu chuẩn được các nhà sản xuất GPS hỗ trợ.
Tính năng module GPS NEO-6M
Tóm tắt:
- Module này có ăng-ten ngoài và bộ nhớ EEPROM tích hợp.
- Kết nối: Serial TTL
- Nguồn cung cấp: 3V đến 5V
- Tốc độ truyền mặc định: 9600 bps
- Hoạt động với các câu NMEA chuẩn

Kết nối Module GPS NEO-6M với ESP32
Chúng ta sẽ kết nối module GPS NEO-6M bằng các chân UART2 mặc định của ESP32. Sơ đồ kết nối như hình ảnh bên dưới

| NEO-6M GPS Module | ESP32 |
| VCC | 3V3 |
| RX | TX2 (GPIO 17) |
| TX | RX2 (GPIO 16) |
| GND | GND |
Lấy dữ liệu GPS thô – Kiểm tra module GPS NEO-6M với ESP32
Để lấy dữ liệu GPS thô, bạn chỉ cần bắt đầu giao tiếp serial với module GPS và đọc dữ liệu.

Đoạn code dưới đây sẽ thiết lập kết nối với module GPS và đọc dữ liệu.
/*********
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("-------------------------------");
}Giải thích cách hoạt động của code
Đoạn mã này giả định rằng bạn đang sử dụng GPIO 16 và GPIO 17 làm chân RX và TX để thiết lập giao tiếp serial với module GPS. Nếu bạn sử dụng các chân khác, bạn nên chỉnh sửa các dòng sau:
// Định nghĩa các chân RX và TX cho Serial 2
#define RXD2 16
#define TXD2 17Ngoài ra, nếu module của bạn sử dụng tốc độ baud khác với 9600 bps, bạn nên sửa đổi mã ở dòng sau:
#define GPS_BAUD 9600Sau đó, chúng ta tạo một đối tượng của lớp HardwareSerial để sử dụng UART 2, gọi là gpsSerial:
// Tạo một đối tượng của lớp HardwareSerial cho Serial 2
HardwareSerial gpsSerial(2);Trong setup(), chúng ta khởi động Serial Monitor:
// Serial Monitor
Serial.begin(115200);Sau đó, chúng ta khởi động giao tiếp serial với module GPS:
// Khởi động Serial 2 với các chân RX và TX đã định nghĩa và tốc độ baud 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");Trong loop(), mã lắng nghe cổng serial GPS và khi dữ liệu được nhận từ module, nó sẽ được in ra Serial Monitor:
void loop() {
while (gpsSerial.available() > 0) {
// Lấy dữ liệu byte từ GPS
char gpsData = gpsSerial.read();
Serial.print(gpsData);
}
delay(1000);
Serial.println("-------------------------------");
}Kiểm tra kết nối GPS
Sau khi upload code xuống board esp32, bạn hãy chắc chắn rằng ăng-ten đã được kết nối và module hoặc ăng-ten được đặt ở ngoài trời hoặc gần cửa sổ để nó có thể nhận dữ liệu từ các vệ tinh.

Module GPS sẽ nhấp nháy đèn LED nếu như đã định vị được vị trí thông qua GPS.

Serial Monitor sẽ hiển thị các câu NMEA với dữ liệu GPS. Khi bạn chạy đoạn mã này lần đầu tiên, có thể mất vài phút để nó nhận được vị trí định vị. Bạn sẽ bắt đầu nhận được dữ liệu thực tế khi đèn LED xanh bắt đầu nhấp nháy.

Bạn sẽ nhận được một loạt thông tin theo ngôn ngữ chuẩn của GPS, NMEA. Mỗi dòng bạn thấy trên serial monitor là một câu NMEA.
NMEA là viết tắt của National Marine Electronics Association (Hiệp hội Điện tử Hàng hải Quốc gia), và trong thế giới GPS, đây là định dạng dữ liệu tiêu chuẩn được các nhà sản xuất GPS hỗ trợ.
Cấu trúc dữ liệu NMEA
Các câu NMEA bắt đầu bằng ký tự $, và mỗi trường dữ liệu được phân cách bằng dấu phẩy.
$GPRMC,110827.00,A,4107.32485,N,00831.79799,W,0.888,30.44,180724,,,A*4B
$GPVTG,30.44,T,,M,0.888,N,1.644,K,A*01
$GPGGA,110827.00,41XX.32485,N,00831.79799,W,1,07,0.99,123.1,M,50.1,M,,*48
$GPGSA,A,3,03,32,22,08,04,14,17,,,,,,2.25,0.99,2.02*0A
$GPGSV,3,1,11,3,11,22,26,296,29,27,01,142,,32,17,042,23*48
$GPGLL,4107.32485,N,00831.79799,W,110827.00,A,A*7F
Có nhiều loại câu NMEA khác nhau. Loại tin nhắn được chỉ định bởi các ký tự trước dấu phẩy đầu tiên.
Ký hiệu GP sau ký tự $ cho biết đây là vị trí GPS. Câu $GPGGA là tin nhắn GPS NMEA cơ bản, cung cấp dữ liệu về vị trí 3D và độ chính xác.
Trong câu sau:
$GPGGA,110827.00,41XX.32485,N,008XX.XXXXX,W,1,07,0.99,123.1,M,50.1,M,,*48110827– đại diện cho thời gian khi vị trí được định vị, 11:08:27 UTC41XX.32485,N– vĩ độ 41 độ XX.32485′ N008XX.XXXXX,W– Kinh độ 008 độ XX.XXXXX′ W1– chất lượng vị trí (0 = không hợp lệ; 1 = GPS fix; 2 = DGPS fix; 3 = PPS fix; 4 = Real Time Kinematic; 5 = Float RTK; 6 = ước lượng (dead reckoning); 7 = chế độ nhập thủ công; 8 = chế độ mô phỏng)07– số vệ tinh đang theo dõi0.99– độ pha loãng ngang của vị trí (dưới một là lý tưởng)123.1, M– độ cao, tính bằng mét trên mức nước biển50.1, M– chiều cao của mặt địa hình (mức nước biển) trên ellipsoid WGS84- Trường trống – thời gian tính bằng giây kể từ lần cập nhật DGPS cuối cùng
- Trường trống – số ID trạm DGPS
*48– dữ liệu checksum, luôn bắt đầu bằng*
Các câu NMEA khác cung cấp thông tin bổ sung:
$GPGSA– DOP GPS và các vệ tinh hoạt động$GPGSV– Thông tin chi tiết về vệ tinh GPS$GPGLL– Vĩ độ và Kinh độ địa lý$GPRMC– Dữ liệu GPS cơ bản (vị trí, tốc độ, thời gian)$GPVTG– Tốc độ đạt được
Bạn có thể sử dụng Công cụ Phân tích NMEA Trực tuyến, Online NME Analyser và dán các câu của bạn vào đó để giải thích dữ liệu GPS.
Tuy nhiên, cách dễ nhất để lấy và giải thích dữ liệu GPS bạn muốn là phân tích các câu NMEA trực tiếp trong mã của bạn. Để làm điều đó, bạn có thể sử dụng thư viện TinyGPSPlus, cung cấp các phương pháp để trích xuất dữ liệu từ các câu NMEA một cách dễ dàng.
Phân Tích Các Câu NMEA Với Thư Viện TinyGPSPlus
Thư viện TinyGPSPlus giúp đơn giản hóa việc lấy dữ liệu GPS và cung cấp chúng theo định dạng dễ hiểu. Bạn có thể nhấp vào đây để biết thêm thông tin về thư viện TinyGPSPlus.
Cài đặt thư viện TinyGPSPlus
Trong Arduino IDE, bạn hãy vào Sketch > Include Library > Manage Libraries hoặc nhấp vào biểu tượng Library Manager ở thanh bên trái.
Tìm kiếm “TinyGPSPlus” và cài đặt thư viện của Mikal Hart.

Lấy Dữ Liệu GPS Sử Dụng Module GPS NEO-6M Và Thư Viện TinyGPSPlus
Dưới đây là đoạn mã cho thấy cách lấy dữ liệu GPS bằng thư viện TinyGPSPlus. Chúng ta sẽ lấy được ngày, giờ, tốc độ, độ cao, số lượng vệ tinh nhìn thấy và HDOP (đo độ chính xác của tín hiệu).
/*********
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.
*********/
#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("");
}
}
}Giải thích code
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
// Sau đó, bạn định nghĩa các chân RX và TX cho UART 2 và tốc độ baud của GPS. Nếu bo mạch của bạn sử dụng các chân UART 2 khác, hoặc nếu module GPS sử dụng tốc độ baud khác, bạn có thể chỉnh sửa chúng ở các dòng sau.
// Định nghĩa các chân RX và TX cho Serial 2
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600
// Sau đó, bạn tạo một đối tượng TinyGPS++:
TinyGPSPlus gps;
// Tạo một đối tượng của lớp HardwareSerial cho Serial 2 gọi là gpsSerial.
HardwareSerial gpsSerial(2);
void setup() {
// Khởi tạo Serial Monitor
Serial.begin(115200);
// Khởi động Serial 2 với các chân RX và TX đã định nghĩa và tốc độ baud 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
void loop() {
// Đây là nơi bạn yêu cầu thông tin. Phân tích dữ liệu từ module GPS vào đối tượng TinyGPS++ bằng phương thức encode() như sau.
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
// Sau đó, bạn có thể truy vấn đối tượng gps để xem có bất kỳ trường dữ liệu nào đã được cập nhật không:
if (gps.location.isUpdated()) {
// Nếu có dữ liệu mới, chúng ta có thể lấy nó như sau:
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 (m)= ");
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("");
}
}Kiểm tra hoạt động code
Tải mã lên bo mạch ESP32 của bạn. Mở Serial Monitor với tốc độ baud là 115200. Đảm bảo rằng ăng ten GPS của bạn được đặt bên ngoài hoặc gần cửa sổ để nhận dữ liệu từ các vệ tinh.
Bạn sẽ nhận được dữ liệu GPS trên Serial Monitor về vị trí hiện tại của bạn, tốc độ, độ cao, số vệ tinh có thể nhìn thấy, HDOP và thời gian.

HDOP, hay Horizontal Dilution of Precision, là một chỉ số đo độ chính xác của việc xác định vị trí. Giá trị HDOP càng cao, độ chính xác của việc xác định vị trí càng kém. Lý tưởng nhất là bạn nên nhận được giá trị thấp hơn 2. Giá trị thấp hơn có nghĩa là độ chính xác tốt hơn.
Lời kết
Trong hướng dẫn này, bạn đã biết cách sử dụng module GPS NEO-6M với ESP32 để lấy dữ liệu GPS: vĩ độ, kinh độ, độ cao, tốc độ, ngày, giờ, số vệ tinh, và nhiều thông tin khác.
Việc kết nối module GPS NEO-6M với ESP32 là khá đơn giản—bạn chỉ cần thiết lập một kết nối serial với cảm biến và đọc dữ liệu có sẵn.
Độ chính xác của dữ liệu sẽ phụ thuộc vào vị trí đặt module và loại anten được sử dụng. Để có hiệu suất tốt hơn, cảm biến nên được đặt bên ngoài hoặc gần cửa sổ và tránh các con phố hẹp với các tòa nhà cao. Số lượng vệ tinh nhìn thấy càng nhiều, vị trí xác định sẽ càng chính xác.
Nguồn: https://randomnerdtutorials.com/








