NEO-6M GPS Modülü Arduino Kullanımı: Konum, Hız ve Saat Okuma
NEO-6M GPS modülü Arduino'ya nasıl bağlanır? TX/RX bağlantısı, ilk konum süresi, $GPGGA ve $GPRMC, TinyGPSPlus ile konum ve hız, ESP32 OLED ve Pico kodu.
NEO-6M GPS modülü, Arduino, ESP32 ya da Raspberry Pi Pico projene enlem, boylam, hız, yükseklik ve uydulardan gelen son derece hassas UTC saatini ekleyen, ucuz ve çok yaygın bir GPS alıcısıdır. Arduino ile kullanmak için modülü dört kabloyla (VCC, GND, TX, RX) bağlaman yeterlidir: modül saniyede bir kez 9600 baud hızında NMEA adı verilen metin satırları gönderir, TinyGPSPlus kütüphanesi de bu satırları doğrudan kullanabileceğin sayılara çevirir.
Bu rehberde modülün nasıl çalıştığını, Arduino Uno, ESP32 ve Pico bağlantılarını, ilk konum kilidinin neden bazen dakikalar sürdüğünü, $GPGGA ve $GPRMC cümlelerinin her alanını, enlem ve boylamı bir Google Haritalar bağlantısına çevirmeyi ve konumu OLED ekranda göstermeyi adım adım göreceksin. Yazının sonunda en sık karşılaşılan "veri gelmiyor" ve "konum bulmuyor" sorunlarının nedenlerini ve çözümlerini bir tabloda bulacaksın.

NEO-6M GPS modülü nedir, nasıl çalışır?
GPS (Küresel Konumlama Sistemi), yaklaşık 20.200 km yükseklikte dönen 30'dan fazla uydudan oluşur. Her uydu, içindeki atom saatinin zamanını ve kendi yörünge bilgisini sürekli yayınlar. NEO-6M bu sinyallerin yola çıktığı an ile kendisine ulaştığı an arasındaki farkı ölçerek her uyduya olan uzaklığını hesaplar; en az 4 uydu gördüğünde enlemi, boylamı, yüksekliği ve kendi saatindeki hatayı bulur. Yalnızca 3 uydu görürse yükseklik olmadan iki boyutlu (2D) bir konum hesaplayabilir. Uydu sinyalleri yeryüzüne çok zayıf ulaşır (yaklaşık -130 dBm); beton, metal çatı ve hatta sık ağaç örtüsü bu sinyali büyük ölçüde keser. Bu yüzden GPS'in altın kuralı şudur: anten gökyüzünü görmeli.
| Özellik | Değer |
|---|---|
| Alıcı yonga | u-blox NEO-6M (u-blox 6 konum motoru) |
| Kanal ve sinyal | 50 kanal, GPS L1 C/A (1575,42 MHz), SBAS: EGNOS, WAAS, MSAS |
| Yatay doğruluk | 2,5 m CEP (SBAS ile 2,0 m) |
| Hız ve yön doğruluğu | 0,1 m/s ve 0,5 derece |
| İlk konum süresi (TTFF) | Soğuk 27 s, ılık 27 s, sıcak 1 s |
| Hassasiyet | Takip -161 dBm, soğuk başlatma -147 dBm |
| Güncelleme hızı | Varsayılan 1 Hz, en fazla 5 Hz |
| Haberleşme | UART, varsayılan 9600 baud 8N1, NMEA 0183 |
| Besleme | Kart: 3,3–5 V (regülatörlü); yonga: 2,7–3,6 V |
| Akım | Uydu ararken ~47 mA, takipte ~39 mA |
| Çalışma sıcaklığı | -40 ile +85 °C arası |
Satın aldığın kart yalnızca 16×12 mm'lik NEO-6M yongasından ibaret değildir. Yaygın GY-NEO6MV2 kartlarında yongayla birlikte 25×25 mm'lik seramik bir yama (patch) anten, modülü 3,3–5 V ile besleyebilmeni sağlayan bir regülatör, ayarları saklayan küçük bir EEPROM, saat ve uydu bilgisini koruyan şarjlı bir yedek pil ve konum bulununca yanıp sönen bir LED bulunur. Bazı kartlarda, yukarıdaki fotoğraftaki gibi, harici anten için SMA ya da küçük u.FL konnektörü ve bilgisayara doğrudan bağlanmak için mikro USB girişi de vardır.
NEO-6M bağlantısı: Arduino Uno, ESP32 ve Raspberry Pi Pico
NEO-6M, bilgisayarın seri portu gibi çalışan UART ile haberleşir ve iki veri hattı kullanır. Kural basittir: veri hatları çapraz bağlanır. Modülün TX (gönderen) pini kartın RX (alan) pinine, modülün RX pini de kartın TX pinine gider. Arduino Uno'nun tek donanım seri portu (pin 0 ve 1) USB ile kod yüklemek ve Seri Monitör için kullanıldığından GPS'i SoftwareSerial ile D4 ve D3 pinlerine bağlıyoruz. Seri haberleşmenin ayrıntılarını UART seri haberleşme yazısında bulabilirsin.
| NEO-6M pini | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | VIN (5V) ya da 3V3 | VBUS (5V) ya da 3V3(OUT) |
| GND | GND | GND | GND |
| TX | D4 (SoftwareSerial RX) | GPIO 16 (RX2) | GP1 (UART0 RX) |
| RX | D3, 1 kΩ / 2 kΩ bölücü üzerinden | GPIO 17 (TX2) | GP0 (UART0 TX) |
| PPS (varsa) | Boş bırakılabilir | Boş bırakılabilir | Boş bırakılabilir |
İlk konum kilidi (fix): soğuk, ılık ve sıcak başlatma
GPS modülünü ilk kez çalıştırdığında hemen konum vermemesi tamamen normaldir. Konum hesaplamak için modülün, görünür uyduların hassas yörünge bilgisine (efemeris) ihtiyacı vardır ve her uydu bu bilgiyi yaklaşık 30 saniyede bir yayınlar; tüm uyduların kaba yörünge listesi olan almanak verisinin tamamını indirmek ise 12,5 dakika sürer. Modül, kapanmadan önceki bilgileri ne kadar saklayabildiğine göre üç farklı şekilde başlar. Veri sayfasındaki süreler tüm uyduların güçlü sinyal verdiği test koşullarında ölçülmüştür; kartla gelen küçük seramik antenle birkaç dakika beklemek olağandır.
| Başlatma türü | Modülde kayıtlı bilgi | Veri sayfası | Pratikte (açık hava) |
|---|---|---|---|
| Soğuk başlatma | Saat, konum ve uydu bilgisi yok (ilk kullanım ya da yedek pil boş) | 27 s | 1–5 dakika; zayıf sinyalde 10 dakikayı geçebilir |
| Ilık başlatma | Almanak, yaklaşık saat ve konum var; efemeris eskimiş (yaklaşık 4 saatten uzun kapalı kaldı) | 27 s | 30 saniye – 1 dakika |
| Sıcak başlatma | Güncel efemeris ve saat var (kısa süre önce kapatıldı, yedek pil dolu) | 1 s | Birkaç saniye |
- Açık havaya çık: Ev içinde, özellikle betonarme binalarda modül çoğu zaman hiç konum bulamaz. Test için balkon, bahçe ya da en azından açık bir pencerenin önünü kullan.
- Anteni doğru çevir: Seramik antenin düz ve açık renkli yüzü gökyüzüne bakmalı; anteni ters çevirmek ya da elinle kapatmak sinyali çok zayıflatır.
- Anteni elektronikten uzak tut: ESP32'nin Wi-Fi anteni, anahtarlamalı regülatörler ve uzun USB kabloları gürültü yayar; anteni kartlardan birkaç santimetre uzağa yerleştir.
- Sabırlı ol ve modülü oynatma: İlk kilitlenme sırasında modülün gücünü kesme; her yeniden başlatma aramayı baştan başlatır.
- LED'i izle: Kart üzerindeki LED konum bulunana kadar sönük kalır, kilitlenince saniyede bir yanıp sönmeye başlar.
- Yedek pili doldur: Pil boşsa her açılış soğuk başlatma olur. Modülü birkaç saat enerjili bırakmak pili şarj eder ve sonraki açılışlar saniyelere iner.
NMEA cümleleri: $GPGGA ve $GPRMC nasıl okunur?
NEO-6M bulduğu her şeyi NMEA 0183 standardında, virgülle ayrılmış düz metin satırları olarak gönderir. Varsayılan ayarda her saniye GGA, GLL, GSA, GSV, RMC ve VTG olmak üzere altı çeşit cümle gelir; TXT cümleleri ise genellikle yalnızca açılışta yazılım sürümü gibi bilgi mesajları taşır. Her cümle $ ile başlar; GP öneki verinin GPS'ten geldiğini, sonraki üç harf cümlenin türünü gösterir. Satır sonundaki * işaretinden sonra gelen iki karakter, $ ile * arasındaki tüm karakterlerin XOR'lanmasıyla bulunan sağlama toplamıdır (checksum) ve bozuk satırlar bununla ayıklanır. Konum için en önemli iki cümle şunlardır: $GPGGA,092750.00,4100.82500,N,02858.74000,E,1,08,1.01,39.2,M,36.9,M,,*67 ve $GPRMC,092750.00,A,4100.82500,N,02858.74000,E,0.512,,281026,,,A*7E
| $GPGGA alanı | Örnek | Anlamı |
|---|---|---|
| Saat (UTC) | 092750.00 | 09:27:50 UTC (Türkiye saatiyle 12:27:50) |
| Enlem | 4100.82500,N | 41 derece 00,825 dakika Kuzey |
| Boylam | 02858.74000,E | 28 derece 58,74 dakika Doğu |
| Fix kalitesi | 1 | 0 = konum yok, 1 = GPS, 2 = diferansiyel (SBAS) düzeltmeli |
| Uydu sayısı | 08 | Konum hesabında kullanılan uydu |
| HDOP | 1.01 | Yatay hassasiyet kaybı; 2'nin altı çok iyidir |
| Yükseklik | 39.2,M | Ortalama deniz seviyesinden 39,2 m |
| Geoid farkı | 36.9,M | Deniz seviyesi ile WGS84 elipsoidi arasındaki fark |
| $GPRMC alanı | Örnek | Anlamı |
|---|---|---|
| Saat (UTC) | 092750.00 | Saat, dakika, saniye |
| Durum | A | A = geçerli konum, V = konum yok |
| Enlem / boylam | 4100.82500,N / 02858.74000,E | GGA ile aynı biçim |
| Hız | 0.512 | Knot cinsinden (0,512 × 1,852 ≈ 0,95 km/sa) |
| Yön | (boş) | Hareket yönü, derece; dururken boş kalabilir |
| Tarih | 281026 | ggaayy biçiminde: 28.10.2026 |
| Mod | A | A = otonom, D = diferansiyel, N = veri yok |
NMEA'daki enlem ve boylam ondalık derece değil, derece ve dakika (ddmm.mmmm) biçimindedir; Google Haritalar ve çoğu yazılım ise ondalık derece ister. Çevirmek için enlemde ilk iki, boylamda ilk üç haneyi derece olarak al, kalan dakikayı 60'a bölüp ekle: 4100.82500 → 41 + 0,825 / 60 = 41,013750; 02858.74000 → 28 + 58,74 / 60 = 28,979000. Güney (S) ve batı (W) değerleri eksi işaretli yazılır. Ondalık kısmın altıncı hanesi yaklaşık 11 cm'ye, beşinci hanesi 1,1 m'ye karşılık gelir; NEO-6M'nin doğruluğu 2,5 m olduğu için altı hane fazlasıyla yeterlidir.
Adım adım: Arduino Uno ile ham GPS verisini görmek
- NEO-6M'yi tablodaki gibi bağla: VCC → 5V, GND → GND, GPS TX → D4, GPS RX → bölücü üzerinden D3.
- Aşağıdaki kodu yükle; ek kütüphane gerekmez, SoftwareSerial Arduino IDE ile birlikte gelir.
- Seri Monitör'ü aç ve hızı 115200 baud olarak seç.
- Modülü açık havaya ya da pencere önüne götür ve $GP ile başlayan satırların akmasını izle.
- $GPRMC satırındaki ikinci alan V'den A'ya döndüğünde ve LED yanıp sönmeye başladığında modül konumu bulmuş demektir.
1#include <SoftwareSerial.h>
2
3SoftwareSerial gpsSerial(4, 3); // RX, TX → GPS TX D4'e, GPS RX D3'e / GPS TX to D4, GPS RX to D3
4
5void setup() {
6 Serial.begin(115200); // Seri Monitör hızı / Serial Monitor speed
7 gpsSerial.begin(9600); // NEO-6M varsayılan hızı / NEO-6M default baud rate
8 Serial.println(F("NEO-6M ham NMEA / raw NMEA"));
9}
10
11void loop() {
12 while (gpsSerial.available()) {
13 Serial.write(gpsSerial.read()); // gelen her baytı aynen aktar / pass every byte through
14 }
15}Seri Monitör'de saniyede bir, altı ile dokuz satırlık bir blok görürsün (görünen uydu sayısı arttıkça GSV cümlesi birkaç satıra bölünür). Modül henüz uydu bulamadıysa satırlar $GPRMC,,V,,,,,,,,,,N*53 ve $GPGGA,,,,,,0,00,99.99,,,,,,*48 gibi boş virgüllerle doludur; bu bir hata değildir, modülün çalıştığını ama henüz konum hesaplayamadığını gösterir. $GPGSV satırlarında görünen uyduların sayısını ve her birinin sinyal gücünü (dB-Hz) izleyebilirsin; 30 dB-Hz'in üzerindeki değerler iyi sinyal demektir. Hiç satır gelmiyorsa kablolamayı, anlamsız karakterler geliyorsa hız ayarını kontrol et.
TinyGPSPlus ile enlem, boylam, hız ve saat okumak
NMEA satırlarını elle ayrıştırmak yerine Mikal Hart'ın TinyGPSPlus kütüphanesini kullanmak çok daha pratiktir. Kütüphane Yöneticisi'nde "TinyGPSPlus" arayıp kurabilirsin; kurulum adımlarını Arduino kütüphane ekleme yazısında anlattık. Dikkat: kütüphanenin örnek kodları 4800 baud ile gelir, NEO-6M ise 9600 baud kullanır. Örneği hızı değiştirmeden çalıştırırsan konum hep INVALID görünür, çünkü kütüphane bozuk karakterlerden tek bir cümle bile çıkaramaz. Aşağıdaki kod konumu, hızı, yüksekliği, uydu sayısını, tarihi ve saati saniyede bir yazar ve konumu tarayıcıda açabileceğin bir Google Haritalar bağlantısına çevirir:
1#include <TinyGPSPlus.h>
2#include <SoftwareSerial.h>
3
4const int RX_PIN = 4; // GPS TX → D4
5const int TX_PIN = 3; // GPS RX ← D3 (bölücü üzerinden / through a divider)
6const uint32_t GPS_BAUD = 9600; // NEO-6M varsayılanı / NEO-6M default
7
8TinyGPSPlus gps;
9SoftwareSerial gpsSerial(RX_PIN, TX_PIN);
10unsigned long lastPrint = 0;
11
12void setup() {
13 Serial.begin(115200);
14 gpsSerial.begin(GPS_BAUD);
15 Serial.println(F("NEO-6M + TinyGPSPlus"));
16}
17
18void loop() {
19 while (gpsSerial.available()) {
20 gps.encode(gpsSerial.read()); // her baytı ayrıştırıcıya ver / feed every byte to the parser
21 }
22 if (millis() - lastPrint >= 1000) { // delay() yok, saniyede bir yaz / no delay(), print once per second
23 lastPrint = millis();
24 printInfo();
25 }
26}
27
28void printInfo() {
29 if (gps.charsProcessed() < 10) {
30 Serial.println(F("GPS verisi yok: kablolari ve baud hizini kontrol et / No GPS data: check wiring and baud"));
31 return;
32 }
33 Serial.print(F("Uydu / Sats: "));
34 Serial.println(gps.satellites.value());
35
36 if (gps.location.isValid()) {
37 Serial.print(F("Enlem / Lat: "));
38 Serial.println(gps.location.lat(), 6);
39 Serial.print(F("Boylam / Lng: "));
40 Serial.println(gps.location.lng(), 6);
41 Serial.print(F("Hiz / Speed: "));
42 Serial.print(gps.speed.kmph(), 1);
43 Serial.println(F(" km/h"));
44 Serial.print(F("Yukseklik / Alt: "));
45 Serial.print(gps.altitude.meters(), 1);
46 Serial.println(F(" m"));
47 // Google Haritalar bağlantısı / Google Maps link
48 Serial.print(F("https://www.google.com/maps/search/?api=1&query="));
49 Serial.print(gps.location.lat(), 6);
50 Serial.print(',');
51 Serial.println(gps.location.lng(), 6);
52 } else {
53 Serial.println(F("Konum yok, uydu araniyor / No fix yet, searching"));
54 }
55
56 if (gps.date.isValid() && gps.time.isValid()) {
57 char buf[32];
58 snprintf(buf, sizeof(buf), "%02d.%02d.%04d %02d:%02d:%02d UTC",
59 gps.date.day(), gps.date.month(), (int)gps.date.year(),
60 gps.time.hour(), gps.time.minute(), gps.time.second());
61 Serial.println(buf); // saat UTC'dir / time is UTC
62 }
63 Serial.println();
64}| Fonksiyon | Ne döndürür? |
|---|---|
| gps.encode(c) | Gelen her baytla çağrılır; geçerli bir cümle tamamlanınca true döner |
| gps.location.lat() / lng() | Enlem ve boylam, ondalık derece |
| gps.location.isValid() / age() | Geçerli konum var mı / son güncellemeden bu yana geçen milisaniye |
| gps.speed.kmph() | Yer hızı, km/sa (mps() ve knots() da var) |
| gps.course.deg() | Hareket yönü, derece (0 = kuzey, 90 = doğu) |
| gps.altitude.meters() | Deniz seviyesinden yükseklik, metre |
| gps.satellites.value() | Konum hesabında kullanılan uydu sayısı |
| gps.hdop.hdop() | Yatay hassasiyet kaybı (küçük değer = iyi) |
| gps.date.day() / gps.time.hour() | UTC tarih ve saat alanları |
| TinyGPSPlus::distanceBetween(...) | İki koordinat arasındaki mesafe, metre |
| gps.failedChecksum() | Bozuk gelen cümle sayısı; sürekli artıyorsa veri kaybı var |
Kodun en önemli kuralı loop() içinde delay() kullanmamaktır. GPS saniyede yaklaşık 500 bayt gönderir, SoftwareSerial'ın alma tamponu ise yalnızca 64 bayttır; uzun bir delay() sırasında tampon taşar, cümleler yarım kalır ve TinyGPSPlus onları sağlama toplamı hatasıyla çöpe atar. Bu yüzden ekrana yazma işini millis() ile saniyede bir yapıyoruz; ayrıntılar için millis() ve delay() farkı yazısına bakabilirsin. GPS saati her zaman UTC'dir; Türkiye saati için 3 saat ekle. Arduino Uno'da double aslında 32 bitlik float olduğundan enlem ve boylamın son hanesi yaklaşık yarım metre yuvarlanır; modülün 2,5 metrelik doğruluğu yanında bu fark önemsizdir.
ESP32 ile Serial2: konumu OLED ekranda göstermek
ESP32'de SoftwareSerial'a gerek yoktur: kartta üç donanım UART'ı vardır ve Serial2 istediğin pinlere atanabilir. Aşağıdaki örnekte GPS, GPIO 16 (RX2) ve GPIO 17'ye (TX2) bağlıdır; ESP32 3,3 V ile çalıştığı için bölücüye de gerek kalmaz. Konum, hız ve yerel saat, I2C ile GPIO 21 (SDA) ve GPIO 22'ye (SCL) bağlı 0,96 inçlik bir SSD1306 OLED ekranda gösterilir. Kod için TinyGPSPlus'ın yanında Adafruit SSD1306 ve Adafruit GFX kütüphaneleri de gerekir.
1#include <TinyGPSPlus.h>
2#include <Wire.h>
3#include <Adafruit_GFX.h>
4#include <Adafruit_SSD1306.h>
5
6#define GPS_RX 16 // ESP32 RX2 ← GPS TX
7#define GPS_TX 17 // ESP32 TX2 → GPS RX
8const int UTC_OFFSET = 3; // Türkiye UTC+3, kendi saat dilimini yaz / set your own time zone
9
10TinyGPSPlus gps;
11Adafruit_SSD1306 display(128, 64, &Wire, -1); // OLED: SDA 21, SCL 22
12unsigned long lastDraw = 0;
13
14String mapsLink() {
15 // Google Haritalar bağlantısı üret / build a Google Maps link
16 return "https://www.google.com/maps/search/?api=1&query=" +
17 String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6);
18}
19
20void drawScreen() {
21 display.clearDisplay();
22 display.setTextSize(1);
23 display.setCursor(0, 0);
24 display.print(F("Uydu/Sat: "));
25 display.print(gps.satellites.value());
26
27 if (gps.time.isValid()) {
28 int h = (gps.time.hour() + UTC_OFFSET + 24) % 24; // yerel saat / local time
29 char t[12];
30 snprintf(t, sizeof(t), "%02d:%02d:%02d", h, gps.time.minute(), gps.time.second());
31 display.setCursor(80, 0);
32 display.print(t);
33 }
34
35 if (gps.location.isValid()) {
36 display.setCursor(0, 16);
37 display.print(F("Lat: "));
38 display.println(gps.location.lat(), 6);
39 display.print(F("Lng: "));
40 display.println(gps.location.lng(), 6);
41 display.setTextSize(2); // hız büyük yazılsın / speed in large digits
42 display.setCursor(0, 44);
43 display.print(gps.speed.kmph(), 1);
44 display.print(F(" km/h"));
45 } else {
46 display.setCursor(0, 24);
47 display.println(F("Uydu araniyor..."));
48 display.println(F("Searching for fix"));
49 }
50 display.display();
51}
52
53void setup() {
54 Serial.begin(115200);
55 Serial2.begin(9600, SERIAL_8N1, GPS_RX, GPS_TX); // donanım UART2 / hardware UART2
56 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
57 Serial.println(F("OLED bulunamadi / OLED not found"));
58 while (true) delay(10);
59 }
60 display.setTextColor(SSD1306_WHITE);
61}
62
63void loop() {
64 while (Serial2.available()) {
65 gps.encode(Serial2.read()); // NMEA baytlarını çöz / decode NMEA bytes
66 }
67 if (millis() - lastDraw >= 1000) { // saniyede bir güncelle / refresh once per second
68 lastDraw = millis();
69 drawScreen();
70 if (gps.location.isValid()) {
71 Serial.println(mapsLink()); // Telegram ya da SMS ile gönderilebilir / can be sent via Telegram or SMS
72 }
73 }
74}UTC_OFFSET değişkeni GPS saatini yerel saate çevirir; Türkiye için 3'tür. mapsLink() fonksiyonu konumu, query=enlem,boylam parametresi taşıyan bir Google Haritalar adresine dönüştürür. Bu bağlantıyı Seri Monitör'den kopyalayıp tarayıcıda açabilir, bir Telegram botu ile telefonuna gönderebilir ya da SIM800L GSM modülü ile SMS olarak yollayabilirsin. PSRAM'li ESP32-WROVER kartlarında GPIO 16 ve 17 bellek için kullanıldığından GPS'i örneğin GPIO 26 ve 27'ye bağla; yalnızca iki UART'ı olan ESP32-C3'te ise Serial2 yerine Serial1 kullan.
Raspberry Pi Pico ve MicroPython ile GPS okuma
Raspberry Pi Pico'da GPS'i UART0'a bağlarız: modülün TX'i GP1'e, RX'i GP0'a gider. MicroPython'da ek kütüphane kurmadan NMEA satırlarını kendimiz ayrıştırabiliriz; bu, cümlelerin yapısını öğrenmek için de harika bir alıştırmadır. Kod her satırın sağlama toplamını doğrular, GGA'dan uydu sayısını, RMC'den konumu, hızı ve saati alır ve derece-dakika biçimini ondalık dereceye çevirir. Koddaki timeout=200 ayarı, readline()'ın satır sonunu 200 ms'ye kadar beklemesini sağlar; açılışta yarım kalmış bir satır gelse bile sağlama toplamı denetimi onu eler. Cümle türü f[0][3:] ile alındığı için kod, birden çok uydu sistemi kullanan modüllerin $GNRMC ve $GNGGA satırlarını da tanır. Kodu Thonny ile çalıştırmayı bilmiyorsan önce MicroPython temelleri yazısına göz at.
1from machine import UART, Pin
2
3# GP0 (TX) → GPS RX, GP1 (RX) ← GPS TX
4gps = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1), timeout=200, rxbuf=1024)
5
6def checksum_ok(line):
7 # $ ile * arasındaki karakterlerin XOR'u / XOR of the characters between $ and *
8 try:
9 body, cs = line[1:].split('*')
10 x = 0
11 for ch in body:
12 x ^= ord(ch)
13 return x == int(cs[:2], 16)
14 except ValueError:
15 return False
16
17def to_deg(value, hemi):
18 # ddmm.mmmm → ondalık derece / decimal degrees
19 dot = value.index('.')
20 deg = int(value[:dot - 2]) + float(value[dot - 2:]) / 60
21 return -deg if hemi in ('S', 'W') else deg
22
23sats = '0'
24while True:
25 raw = gps.readline() # bir NMEA satırı / one NMEA line
26 if not raw:
27 continue
28 try:
29 line = raw.decode().strip()
30 except UnicodeError:
31 continue # bozuk bayt / corrupted byte
32 if not line.startswith('$') or not checksum_ok(line):
33 continue
34 f = line.split('*')[0].split(',')
35 kind = f[0][3:] # GPRMC ya da GNRMC → RMC / GPRMC or GNRMC → RMC
36 if kind == 'GGA':
37 sats = f[7] # kullanılan uydu sayısı / satellites in use
38 elif kind == 'RMC':
39 if f[2] != 'A':
40 print('Uydu araniyor / searching, uydu/sats:', sats)
41 continue
42 lat = to_deg(f[3], f[4])
43 lon = to_deg(f[5], f[6])
44 kmh = float(f[7] or 0) * 1.852 # knot → km/sa / knots → km/h
45 t = f[1]
46 print('UTC {}:{}:{} uydu/sats: {}'.format(t[0:2], t[2:4], t[4:6], sats))
47 print('Konum / position: {:.6f}, {:.6f} {:.1f} km/h'.format(lat, lon, kmh))
48 print('https://www.google.com/maps/search/?api=1&query={:.6f},{:.6f}'.format(lat, lon))NEO-6M ile proje fikirleri
- SMS ile konum gönderen takip cihazı: NEO-6M ve SIM800L ile, "KONUM" yazan bir SMS'e Google Haritalar bağlantısıyla cevap veren bir araç ya da bisiklet takip cihazı.
- GPS veri kaydedici: Gittiğin rotayı her saniye bir SD kart modülüne CSV olarak kaydet, sonra bilgisayarda haritaya dök.
- Bisiklet hız göstergesi: Anlık ve en yüksek hızı, toplam mesafeyi OLED ekranda göster; mesafeyi ardışık noktalar arasında TinyGPSPlus::distanceBetween() ile topla.
- Uydu saatli dijital saat: Saati GPS'ten al ve bir RTC saat modülünü internet olmadan saniyesi saniyesine ayarla.
- Coğrafi çit (geofence) alarmı: Belirlediğin noktadan 100 metreden fazla uzaklaşıldığında buzzer çalan ya da bildirim gönderen bir sistem.
- Uzun menzilli takip: Konumu bir LoRa modülü ile kilometrelerce uzaktaki bir alıcıya gönder; pille çalışırken ESP32 deep sleep ile enerji tasarrufu yap.
Veri gelmiyor ya da konum bulmuyor: sık hatalar ve çözümleri
| Belirti | Olası neden | Çözüm |
|---|---|---|
| Seri Monitör tamamen boş | TX ve RX ters bağlı, GND ortak değil ya da modüle güç gitmiyor | GPS TX'i kartın RX pinine (Uno'da D4) bağla, GND'leri birleştir, VCC'yi ölç |
| "No GPS detected: check wiring." | Kütüphaneye 5 saniyede 10 karakter bile ulaşmamış | Kablolamayı ve koddaki pin numaralarını kontrol et; TX ile RX'i yer değiştirerek dene |
| Anlamsız karakterler | Baud hızı uyuşmuyor | GPS için 9600, Seri Monitör için koddaki hızı seç; olmazsa 4800 ve 38400'ü dene |
| Satırlar geliyor ama alanlar boş (,V,) | Modül çalışıyor ama uydu bulamadı | Açık havaya çık, anteni gökyüzüne çevir, 5–15 dakika bekle |
| Uydu sayısı 0–3 arasında kalıyor | Zayıf sinyal, ters anten, gevşek u.FL konnektörü ya da yakında gürültü kaynağı | Anteni kontrol et, konnektörü sıkıca tak, anteni ESP32'den ve regülatörlerden uzaklaştır |
| Ham veride konum var, TinyGPSPlus INVALID diyor | loop() içindeki delay() yüzünden tampon taşıyor; failedChecksum() artıyor | delay()'i kaldır, millis() kullan, encode()'u sürekli çağır |
| Saat birkaç saat geride | GPS saati UTC'dir | Saat dilimi farkını ekle (Türkiye için +3) |
| Dururken konum birkaç metre kayıyor, hız 0 değil | Normal GPS gürültüsü ve binalardan yansıyan sinyaller | 2 km/sa altındaki hızları 0 say, HDOP yüksekse veriyi atla, ortalama al |
| Her açılışta yine dakikalarca bekliyor | Yedek pil boş ya da kartta pil yok | Modülü birkaç saat açık bırakıp pili şarj et |
NEO-6M, projelerine "neredeyim, ne kadar hızlı gidiyorum, saat kaç" sorularının cevabını çok düşük bir maliyetle ekler; işin sırrı, anteni gökyüzüne göstermek ve ilk kilitlenmeye sabırla izin vermektir. Seri haberleşmeyi daha iyi kavramak için UART yazısına göz atabilirsin. BlueGrays uygulamasında iki Arduino arasında seri haberleşme, OLED ekran, microSD ile veri kaydı, ESP32 deep sleep ve Telegram bildirimli alarm gibi, GPS projelerinde de işine yarayacak projeleri devre şemaları ve adım adım kodlarıyla bulabilirsin.
Sıkça sorulan sorular
NEO-6M GPS modülü kapalı alanda çalışır mı?
Genellikle hayır. Uydu sinyalleri yeryüzüne çok zayıf ulaşır ve beton ya da metal çatılar onları büyük ölçüde keser. Açık bir pencerenin önünde bazen birkaç uydu yakalanabilir, ama güvenilir konum için anten gökyüzünü doğrudan görmelidir; kapalı alanda konum gerekiyorsa çatıya ya da pencereye taşınan harici aktif anten kullan.
NEO-6M'nin ilk konumu bulması ne kadar sürer?
Veri sayfasına göre soğuk başlatma 27 saniye, sıcak başlatma 1 saniyedir. Pratikte küçük seramik antenle açık havada ilk konum genellikle 1–5 dakika sürer; ilk kullanımda ya da yedek pil boşken 10–15 dakikayı bulabilir. Modül kısa süre önce kapatıldıysa birkaç saniyede yeniden kilitlenir.
NEO-6M GPS modülünün doğruluğu ne kadar?
Üretici, açık gökyüzünde yatay doğruluğu 2,5 m CEP, SBAS düzeltmesiyle 2,0 m olarak verir; bu, ölçümlerin yarısının gerçek noktaya 2,5 m'den daha yakın olduğu anlamına gelir. Şehirde binalardan yansıyan sinyaller hatayı 5–10 metreye çıkarabilir. Yükseklik ölçümü ise yatay konumdan daha az hassastır.
NEO-6M 5V ile çalışır mı, Arduino'ya doğrudan bağlanır mı?
Yaygın GY-NEO6MV2 kartlarında regülatör olduğu için VCC 5 V ile beslenebilir. Ancak yonganın RX pini en fazla 3,6 V'a dayanır; Arduino Uno'nun 5 V'luk TX sinyalini 1 kΩ ve 2 kΩ'luk bir gerilim bölücüyle düşür. Modülün TX çıkışı 3,3 V'tur ve Uno bunu sorunsuz okur.
GPS modülü için internet ya da SIM kart gerekir mi?
Hayır. NEO-6M konumu doğrudan uydulardan gelen sinyallerle, ücretsiz ve internetsiz hesaplar. İnternet ya da SIM kart yalnızca bulunan konumu başka bir yere göndermek istediğinde gerekir; bunun için ESP32'nin Wi-Fi'ı ya da SIM800L gibi bir GSM modülü kullanılır.
NEO-6M ile NEO-M8N arasındaki fark nedir?
NEO-6M yalnızca GPS uydularını kullanır. Daha yeni NEO-M8N ise GPS ile birlikte GLONASS, Galileo ya da BeiDou uydularını da aynı anda kullanabilir; daha çok uydu gördüğü için şehirde daha hızlı ve kararlı konum bulur. M8N'in cümleleri genellikle $GN ile başlar, ama TinyGPSPlus ikisini de aynı kodla okur.
Bu yazıdan sonra yapabileceğin projeler
Tüm projeleri gör
2 Arduino Tek Yönlü Haberleşme
İki Arduino arasında seri haberleşme ile tek yönlü veri aktarımı yapan proje. Verici tarafta buton basışını algılayıp alıcı tarafta LED'i kontrol etmeyi öğretir.

2 Arduino Çift Yönlü Haberleşme
İki Arduino arasında seri haberleşme ile çift yönlü veri aktarımı yapan proje. Her iki kart da hem buton okuyup veri gönderir hem de veri alıp LED kontrol eder.

ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)
ESP32 ile zamanlı sıcaklık ve nem kayıt sistemi kur! Bu projede DHT22 sensörü ile her 10 saniyede sıcaklık/nem okuyup DS1307 RTC modülünden aldığın gerçek zaman etiketiyle microSD karta CSV formatında kaydediyoruz. OLED ekranda büyük font ile son sıcaklık değeri, nem yüzdesi, timestamp ve toplam kayıt sayısı canlı gösterilir. SD kart üzerindeki `/temp_log.csv` dosyası Excel/Google Sheets/Python pandas ile açılıp analiz edilebilir — sera monitörü, ev/oda sıcaklık takibi, laboratuvar veri toplama,

ESP32 HTTPClient + Hava Durumu API (SSD1306 OLED Ekranlı)
Bu projede ESP32 ile internet üzerinden hava durumu API'sine (wttr.in) `HTTPClient.h` kullanarak REST API çağrısı yapıyoruz. Bir önceki I2C LCD versiyonundan farklı olarak burada SSD1306 OLED (128×64) ekran kullanıyoruz — büyük font, vector ikonlar ve tek ekranda zengin görsel sunum mümkün oluyor. Hava durumu için 7 farklı vector ikon (güneşli, parçalı bulutlu, bulutlu, yağmurlu, karlı, fırtınalı, sisli) runtime'da çiziliyor (bitmap dosyası gerektirmez). Sıcaklık 3x büyük fontla ortada, hava dur

ESP32 Deep Sleep — Pil Tasarrufu (OLED + RTC RAM Sayaç)
ESP32'nin Deep Sleep modu, CPU ve çoğu çevre birimini kapatarak akım tüketimini ~10µA seviyesine düşürür ve pille çalışan IoT cihazları için kritik öneme sahiptir. Bu projede üç farklı uyandırma kaynağını kullanıyoruz: zamanlayıcı (timer, 15sn), harici pin (EXT0 — buton GPIO 33) ve touch (T0/GPIO 4). `RTC_DATA_ATTR` ile işaretlenen değişkenler deep sleep boyunca korunur — boot sayacı, timer wake sayacı ve buton wake sayacı kalıcı olarak izlenir. SSD1306 OLED ekranda her uyanışta wake reason, say

ESP32 NTP ile İnternetten Gerçek Zaman
ESP32, Wi-Fi'a bağlanıp NTP (Network Time Protocol) sunucularından milisaniye hassasiyetiyle gerçek zamanı çeker. `configTzTime()` fonksiyonu sayesinde Türkiye saat dilimi (TRT, UTC+3) otomatik uygulanır ve yaz/kış saati uygulayan ülkelerde DST geçişi POSIX TZ string'i ile otomatik yönetilir. Saat hem Serial Monitor'e hem de opsiyonel I2C LCD'ye yazdırılır. `configTzTime()` SNTP hizmetini başlatır; ağ erişimi varken periyodik yeniden senkronizasyon yapılır ve iki senkronizasyon arasında sistem s

ESP32 Hareket Alarm Sistemi (PIR + Buzzer + LED + Telegram)
PIR sensörü hareket algıladığında buzzer ve LED'i aktif eden, aynı anda Telegram üzerinden sahibine anlık bildirim gönderen akıllı bir güvenlik alarm sistemidir. Tekrarlayan alarmların sıklığını sınırlamak için 30 saniyelik cooldown (bekleme süresi) mekanizması vardır; bu mekanizma PIR sensörünün yanlış algılamalarını doğrulamaz veya ortadan kaldırmaz. Ev güvenliği, garaj izleme, depo veya çalışma odası gibi alanlarda kullanılabilir. Telegram entegrasyonu sayesinde nerede olursanız olun anında h

ESP32 RTC DS1307 ile Dijital Saat (I2C + LCD)
Bu projede DS1307 gerçek zaman saati (RTC) modülü ile 16x2 I2C LCD ekrana saat ve tarih bilgisi yansıtıyoruz. DS1307 pil destekli bir RTC'dir; ESP32 kapansa bile zamanı korur. Her iki modül de aynı I2C hattını (SDA/SCL) paylaşır, böylece sadece iki sinyal kablosu ile çoklu cihaz kontrolü öğrenmiş oluruz. Bu proje sayesinde I2C haberleşme protokolünü, RTC modüllerinin çalışma prensibini ve LCD ekranda dinamik veri gösterimini pratik bir şekilde öğreneceksiniz.

