26 Mayıs 2014 Pazartesi

C# Gerçek Zamanlı Grafik Çizme Programı

Herkese Merhabalar!
    Programın kaynak koduna buradan ulaşabilirsiniz.
    İkinci yazımda C# ile gerçek zamanlı grafik çizdirme uygulamasından bahsedeceğim. Bu uygulamada C# programlama dili ve Microsoft Visual Studio 2010 kullanılmıştır. C# ile grafik çizmemize olanak sağlayan zed graph eklentisinden yararlanılmıştır.Bu eklentiyi buradan indirebilirsiniz. Sistemin genel algoritmasına bakarsak şöyle çalışır; seri porttan veri okunur, veri aralardaki virgüllere göre parse edilip labellera aktarılır, Eklenen "Timer" öğesi ile timerın her periyodunda zaman belirten labela geçen zaman kadar eklenir böylece kaçıncı saniye olduğu tutulur, aynı zamanda timerın her bir periyodunda x değerleri zaman, y değerleri data noktaları olmak üzere grafiğe bir nokta eklenir. Şimdi çalışma şeklini daha ayrıntılı bir şekilde inceleyelim.
    Mikrodenetleyici-bilgisayar iletişimi projelerinde olmazsa olmazlardan biri Seri porttan veri okumaktır. Bu sayede mikrodenetleyici ile iletişim
kurabiliriz ve veri alışverişinde bulunabiliriz. Aynı zamanda bilgisayar kontrollü robotikte de komut vermek için  kullanılır. C# üzerinden serial port programı yazma işlemi oldukça kolaylaştırılmıştır. Seri port öğesi eklenir ve ayarları yapılır. Buradaki ayarlar veri transfer hızı hangi Com Portun okunacağının ayarı v.b. "Save to text" özelliği de gelen veriyi saklayıp sonra tekrar inceleme imkanı sunar.Asıl konumuz bu olmadığı için çok ayrıntıya girmiyorum zaten kolayca örnekleri bulunabilir.


    İkinci kısım seri porttan alınan verinin uygun şekilde parçalandığı ve labellara aktarıldığı bölümdür. Bunun için "Display Text" isimli bir fonksiyon yazılmıştır. Bu fonksiyon ile gelen verinin her satırının şekli "$,data1,data2,data3" olarak belirlenmiştir. Fonksiyonun algoritması şu şekildedir; gelen verinin ilk harfi "$" değilse veriyi işlemez, eğer ilk harfi oysa virgül sayısına bakar(Stringin içinden belli bir karakteri arama fonksiyonu kullanılmıştır.), eğer o da 3'e eşit ise gelen veriyi virgüllere göre parçalar ve ilk kısım hariç("$") kalan veriyi, tek tek 3 ayrı labela aktarır böylece gelen data1, data2, data3 ayrı labellara aktarılmış olur.


   Grafik çizdirme kısmına geçmeden önce grafiği çizen timerı açan ve kapatan 2 butondan bahsedeyim. Bunlar sayesinde grafik çizdirme başlatılır ve durdurulur. Yani butonların tıklama "event"lerinde sadece "timer1.enable=true;" ve "timer1.enable=false" kodu vardır.(Tabi ayrı ayrı birinde true olan diğerinde false olan )

Resimde altta eklediğimiz SeriPort ve timer1 öğesini görebilirsiniz. "FileDiaglog" öğeleri ise text dosyasına kaydetmek için ve bir text dostasını seri porttan yollamak için kullanılır
    ilk önce grafiğin ayarlarından başlayalım. Grafiğe bir çizim alanı yanı "pane" ekleyelim. Çizdiğimiz her şeyi hangi "pane"e çizdiğimizi belirtmek zorundayız. Eksenlere isim koymamız ve daha bir sürü ayar yapmamız mümkün ama ben karışıklık yaratmamak adına sade bir grafik tercih ettim. ZedGraph kütüphanesi yapabileceğiniz diğer ayarlar ile çok farklı grafikler çizdirme imkanı sunar. Grafiğin altını doldurma, nokta grafiği, sütun ve daire grafiği gibi çeşit ve renk opsiyonları mevcuttur. Bu çeşitlerin bazılarına buradan ulaşabilirsiniz.

    Grafik ayarlarında önemli bir yerlerden biri de "Point pair list"in ve "Line item"ın belirlenmesidir.Çizilecek her eğri için birer tane bunlardan belirlenmelidir. "RolingPointPairList" seçilmesinin sebebi ise "rolling" olduğunda en fazla seçilen kadar(burada en fazla 40 nokta çifti) noktanın hafızada saklaması böylece bir süre sonra biriken noktaların bilgisayarda yavaşlama meydana getirmesinin engellenmesidir. Belli aralıklarla zaten grafik üstüne sağ tıklanarak resim olarak kaydetme opsiyonu da mevcuttur.



       Gelelim grafiği çizdirme kısmına. İlk önce grafiğe bir "Timer" öğesi eklenir ve periyodu 1000 ms(1 saniye) olarak belirlenir. Bu tamamen opsiyoneldir ne kadarlık zaman aralıklarında grafiğimize nokta eklenmesi istendiğine bağlıdır.İlk 3 satırdaki kodlar ile bir labelda şu anki saniyenin tutulması sağlanır(Zaman bizim x koordinatımız olduğu için anlık olarak kulanılması gereklidir). Sonraki kısımlar ise grafiğe nokta eklenmesi algoritmasıdır. Gelen verileri yukarıda parçalayıp labellara aktarmıştık burda ise o labellar ve zaman labelı kullanılarak nokta çifleri elde edilir. Nokta çiftleri, nokta listelerine aktarılır sonra bunlar birleştirilerek eğri çizilir."myCurveOne = myPane.AddCurve(null, listPointsOne, Color.Blue, SymbolType.Circle) " bu satır ile eğrinin hangi "pane"e çizileceği, rengi, noktaların gösteren sembol (yuvarlak,yıldız,kare), eğrinin altının dolu-boş olacağı belirlenir.  En alt kısımda grafik yenilerek yeni eğrinin çizilmesi graifğin gördüğümüz yerinin eğrimize paralel olarak uygun şekilde yer değiştirmesi sağlanır. Böylece Bilgisayara hiç değmeden grafiğin takibi otomatik olarak yapılmış olur.

    Aşağıda programımızın son hali bulunmaktadır. En kısa zamanda videosunu eklemeye çalışacağım. Görselleme, telemetri projelerinde ve bilgisayarla kontrol projelerinde en önemli noktalardan biridir(ya da pid, sensor test ederken). Programımız da bu ihtiyaca yönelik yazılmıştır. Arduino ve ya pic ile (ya da seri porttan haberleşebilen tüm işlemciler) rahatlıkla çalışabilecek bir uygulamadır. C# ile yapılan gerçek zamanlı (real time) uygulama eksikliğinden bu konuyu yapma ihtiyacı hissettim. Ben bu konuyu araştırırken bu uygulamayı gerçek zamanlı yapan ve sonra nasıl yapıldığını anlatan bir kaynak bulamamıştım.Umarım bu bilgiler işinize yarar. Paylaşımlarınızda kaynak belirtirseniz çok iyi olur :). Tekrar görüşmek üzere...


Not: Sonradan programın derlenmiş halini de paylaştım indirmek isterseniz buradaki yazıma gitmeniz yeterli olacaktır.








8 yorum:

  1. Harika emeğinize sağlık.Farkat bir sorum olacak.Ben acemiyim ve bitirme projesinde çok sıkıştım.Projem ardunıo ile titreşim sensörü okuma ve c sharp ta grakfiksel olarak gösterme.acaba bu arayüz işime yarar mı ?

    YanıtlaSil
    Yanıtlar
    1. Tabi kullanabilirsiniz isinizi görecektir ;)

      Sil
    2. Peki ben x eksenınde gösterilen değerin neyi gösterdıgını anlamadım.Örneğin sensörden okunan gerilim değerimi ? Mesela ben o eksende titreşim sensörünün G (yercekım ivmesi) değişimini göstermek istiyorum bu değişikliği yapabılırmıyım ve nasıl olur sizce ?

      Sil
  2. X ekseni zamanı y ekseni gelen veriyi gösterecek şekilde ayarlamıştım

    YanıtlaSil
  3. Peki form üzerinde isim vb. değişiklikler yapmam için ne yapman gerekiyor lütfen yardım edin ,

    YanıtlaSil
  4. Setup olarak yüklediğiniden içeriğe ulaşamıyorum .Çok acil gerekli.

    YanıtlaSil
  5. Programın kaynak kodu için https://github.com/mozanunal/serialPortGrapher

    YanıtlaSil
  6. Bu yorum yazar tarafından silindi.

    YanıtlaSil