Facebook RSS Feed
 

C# İle GPS Seyir Kaydedici

GPS IconGPS Uygulamaları pozisyon göstermenin ve yol bulmanın yanı sıra bizlere birçok değişik uygulama çeşitleri sunuyor. Yapabileceğimiz en basit uygulamalardan biri de izimizi kaydeden “GPS Seyir Kaydedici”. Bu uygulama ile Bluetooth yada COM portu ile bağlı GPS alıcımızın gönderdiği komutları çözümleyip kaydedeceğiz. İleride yapacağımız başka bir uygulama ile de katettiğimiz yolu harita üzerinde görebiliriz.

Gerekenler

  • COM Portu üzerinden bağlantı kurabileceğimiz Bluetooth yada Seri Port GPS Alıcısı
  • .NET Framework 4.0
  • Microsoft Visual Studio 2010

Proje Temelleri

Öncelikle Visual Studio’da yeni bir Windows Form Application oluşturalım. Daha sonra aşağıdakine benzer bir tasarım oluşturalım.

GPS

Kullanacağımız Kontroller:

  • Panel: panelPozisyon
    • TextBox: txtEnlem
    • TextBox: txtBoylam
    • TextBox: txtYukseklik
  • Panel: panelGPS
    • TextBox: txtSaat
    • TextBox: txtSapma
    • TextBox: txtKilitlenme
    • TextBox: txtUydu
    • TextBox: txtVeriTipi
  • Panel: panelBaglanti
    • ComboBox: cmbPort
    • ComboBox: cmbPortHizi
    • Button: btnBaglanti
  • Panel: panelSeyirKaydi
    • RichTextBox: rtxtSeyirKaydi
    • CheckBox: cbKayitTut
    • Button: btnSil
    • Button: btnKaydet
    • SerialPort: spGPS

Kodları Yazalım

Uygulamada kullanacağımız değişkenleri tanımlamakla kodlarımıza başlayalım.

string[] gParca;
string gKG, gDB, gUydular, gYukseklik, gEnlem, gBoylam, gVeriTipi, gYataySapma, gKilitlenme, gSaat;
bool GPSBagli;

Şimdi cmbPort’un Item’larına COM1’den COM9’a kadar portları ekleyelim

GPS

Aynı şekilde cmbPortHizi’nin Item’larına GPS bağlantı standartları 4800 ve 9600’ü ekleyelim.

Formumuzun Load eventine de başlangıçta kullanılmasını istediğiniz portu ve hızını yazalım.

private void frmMain_Load(object sender, EventArgs e)
{
    CheckForIllegalCrossThreadCalls = false;
    cmbPort.SelectedIndex = 0;
    cmbPortHizi.SelectedIndex = 1;
}

Şimdi GPS portuna bağlanmamızı ve bağlantıyı kesmemizi sağlayacak butonun eventine gelelim. Başlangıçta buton text’i “Bağlan” olacak. Tıklandığında “Bağlanıyor…” yazacak ve enabled özelliği false olacak. Bağlantı kurulduğunda üzerinde “Durdur” yazacak. Olası bağlantı hatalarından uygulamamızın etkilenmemesi için bağlantı fonksiyonunu try – catch bloğu içerisinde yazacağız. Hata oluştuğunda yada bağlantı kurulduğunda butonun enabled özelliği true olacak.

private void btnBaglanti_Click(object sender, EventArgs e)
{
    if (GPSBagli)
    {
        btnBaglanti.Text = "Bağlan";
        if (spGPS.IsOpen) spGPS.Close();
        Temizle();
        GPSBagli = false;
    }
    else
    {
        btnBaglanti.Text = "Bağlanıyor…";
        btnBaglanti.Enabled = false;
        try
        {
            spGPS.PortName = cmbPort.SelectedItem.ToString();
            spGPS.BaudRate = Convert.ToInt32(cmbPortHizi.SelectedItem);
            if (!spGPS.IsOpen) spGPS.Open();
            btnBaglanti.Text = "Durdur";
            GPSBagli = true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Bağlantı Hatası", MessageBoxButtons.OK,
                MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            btnBaglanti.Text = "Bağlan";
        }
        btnBaglanti.Enabled = true;
    }
}

GPS ile bağlantıyı kestiğimizde TextBox’larımızın temizlenmesi için aşağıdaki kodu da ekleyelim:

private void Temizle()
{
    foreach (Control item in Controls)
    {
        if (item is Panel)
        {
            foreach (Control subItem in item.Controls)
            {
                if (subItem is TextBox) subItem.ResetText();
            }
        }
    }
}

Bu şekilde bağlantıyı kestiğimizde formdaki tüm panellerin içerisindeki TextBox’ların text’leri başlangıçtaki haline dönecek.

Form kapanırken COM portunun kapanması için formun onclosing eventine spGPS.Close(); komutunu ekleyelim:

private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
    if (spGPS.IsOpen) spGPS.Close();
}

Yukarıda eklediğimiz kodlarla uygulamamızın temelini tamamlamış olduk. Şimdi sıra uygulamamızın kalbi olan GPS komutlarını ayıklamaya geldi. GPS çipi tarafından hesaplanan pozisyon bilgisi, uygulamaya standard cümle kalıpları halinde gönderilir. Bu kalıpların birkaç çeşidi vardır ve her biri farklı hesaplamaları içerir. NMEA (National Marine Electronics Association) tarafından belirlenen 30’un üzerinde cümle türü mevcuttur. Biz bu cümle tipleri arasından temel 3 boyutlu (Enlem, Boylam, Yükseklik) pozisyon bilgisi olan GPGGA’yı kullanacağız.

Örnek bir GPGGA cümlesine bakacak olursak:

“$GPGGA,201308.255,4737.9922,N,12211.1734,W,1,05,2.9,30.1,M,-17.2,M,0.0,0000*78”

gibi bir ifade ile karşılaşırız. Bu bilgiler bize o anki saati, bulunduğumuz enlem, boylam ve yüksekliği verir. GPGGA’ya daha detaylı bakalım:

Hane Veri Açıklama
1 $GPGGA Cümlenin GPGGA türünde olduğunu belirtir.
2 201308.255 UTC’ye göre o o anki saat
3, 4 4737.9922,N Enlem
5, 6 12211.1734,W Boylam
7 1

Kilitlenme kalitesi:
0: Geçersiz
1. GPS fix (SPS)
2. DGPS fix
3. PPS fix
4. Real Time Kinematic
5. Float RTK
6. Estimated
7. Manual Input Mode
8. Simulation Mode

8 05 Ölçümde kullanılan uydu sayısı
9 2.9 Yatay pozisyon kayması
10, 11 30.1,M Ortalama deniz seviyesine göre yükseklik
12, 13 -17.2,M Ortalama deniz seviyesine göre geoid yüksekliği
14 0.0 Son DGPS güncellemesinden sonra geçen saniye
15 0000 DGPS istasyonunun ID numarası
16 *78 Checksum bilgisi, her zaman * ile başlar

Biz de yukarıdaki tabloya göre gelen komutu parçalara bölüp uygulamamızın başında tanımladığımız değişkenlere, sonra da ilgili TextBox’lara atayacağız.

private void GPSBilgisiGoster(string NMEA)
{
    gParca = NMEA.Split(new char[] { ‘,’ });
    switch (gParca[0])
    {
        //Global Positioning System Fix Data
        case "$GPGGA":
            gParca[2] = gParca[2].Replace(‘.’, ‘,’);
            gParca[4] = gParca[4].Replace(‘.’, ‘,’);

            if (gParca[3] == "N") gKG = "Kuzey";
            else if (gParca[3] == "S") gKG = "Güney";
            if (gParca[5] == "E") gDB = "Doğu";
            else if (gParca[5] == "W") gDB = "Batı";

            switch (gParca[6])
                {
                    case "0": gKilitlenme = "Invalid";              break;
                    case "1": gKilitlenme = "GPS fix (SPS) ";       break;
                    case "2": gKilitlenme = "DGPS fix";             break;
                    case "3": gKilitlenme = "PPS fix";              break;
                    case "4": gKilitlenme = "Real Time Kinematic";  break;
                    case "5": gKilitlenme = "Float RTK";            break;
                    case "6": gKilitlenme = "Estimated";            break;
                    case "7": gKilitlenme = "Manual Input Mode";    break;
                    case "8": gKilitlenme = "Simulation Mode";      break;
                    default:  gKilitlenme = "Unknown";              break;
                }

            gEnlem = gParca[2];
            gBoylam = gParca[4];
            gUydular = gParca[7];
            gYukseklik = gParca[9] + " " + gParca[10];

            gVeriTipi = "GPS Fix Data";
            gYataySapma = gParca[8];
            gSaat = gParca[1].Substring(0, 2) + ":" + gParca[1].Substring(2, 2) + " " + gParca[1].Substring(4, 2) + " (UTF)";
            SeyirKaydi(NMEA);
            break;
        default:
            break;
    }
    txtEnlem.Text = gEnlem + " " + gKG;
    txtBoylam.Text = gBoylam + " " + gDB;
    txtYukseklik.Text = gYukseklik;

    txtSaat.Text = gSaat;
    txtSapma.Text = gYataySapma;
    txtKilitlenme.Text = gKilitlenme;
    txtUydu.Text = gUydular;
    txtVeriTipi.Text = gVeriTipi;
}

Artık gelen veriyi pozisyon bilgisine çeviren bir uygulamamız var. Yapmamız gereken seri port önbelleğine gelen cümleyi alıp GPSBilgisiGoster() metodunu çalıştırmak. Genellikle GPS denetleyicileri saniyede bir pozisyon bilgisi hesaplayıp bunu 4800 yada 9600 bps hızında gönderirler. Seri port’un DataReceived eventine aşağıdaki kodu ekleyerek GPS alıcısından gelen komutu işleyebiliriz.

private void spGPS_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    GPSBilgisiGoster(spGPS.ReadLine());
}

Artık uygulamamız seri portu dinleyerek veriyi pozisyon bilgisine çevirebiliyor. NMEA cümlesinin geçmişini formda görmek için SeyirKaydi metodunu oluşturup aşağıdaki kodu da ekleyelim:

private void SeyirKaydi(string NMEA)
{
    if (cbKayitTut.Checked) rtxtSeyirKaydi.AppendText(NMEA);
}

Son olarak da seyir geçmişini silmek ve txt dosyası olarak kaydetmek için btnSil ve btnKaydet Button’larının Click eventlerine aşağıdaki kod bloklarını ekleyelim:

private void btnSil_Click(object sender, EventArgs e)
{
    if (MessageBox.Show("Seyir geçmişi silinsin mi?", "Seyir Geçmişini Sil", MessageBoxButtons.YesNo,
        MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes) rtxtSeyirKaydi.Clear();
}

private void btnKaydet_Click(object sender, EventArgs e)
{
    SaveFileDialog KayitPenceresi = new SaveFileDialog();
    KayitPenceresi.Filter = "TXT Dosyası|*.txt|Tüm Dosyalar|*.*";
    KayitPenceresi.Title = "Seyir Geçmişini Kaydet";
    if (KayitPenceresi.ShowDialog() == DialogResult.OK)
    {
        rtxtSeyirKaydi.SaveFile(KayitPenceresi.FileName, RichTextBoxStreamType.PlainText);
    }
}

Yukarıdaki kodları eklediğimizde ve uygulamamızı çalıştırdığımızda, GPS alıcımızın hızına bağlı olarak ortalama 30 saniye içerisinde bulunduğumuz pozisyonu göreceğiz.

GPS

Uygulamayı ve kaynak kodlarını buradan indirebilirsiniz:




 
Hoşgeldiniz!
Son güncelleme: 25.12.2016
-
Yeni Teknik Yazılar
Latte Panda İncelemesi
Turta IoT HAT İncelemesi
USB Gamepad Kullanımı
GPIO Kullanımı
VEML6075 UV Sensör Kullan...
-
İlgili Gruplar
.NET MF ve Gadgeteer FB Grubu
İst. IoT & Wearables Meet-up
-
 

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.Copyright © 1999 - 2017, Umut Erkal. Bu materyal, "Creative Commons Public Licence" ile sunulmuştur.
Kaynak göstererek ve ücretsiz olarak, aynı şartlar altında paylaşabilir ve kullanabilirsiniz. | Kullanım Sözleşmesi