Serial Haberleşme Adabı

Başlatan veliusta, 13 Mayıs 2022, 22:53:58

veliusta


Yukarıdaki resimdeki gibi karışık uygulama yapmak istiyorum.

İnternetten Serial Port ile yapılmış haberleşme örneklerini inceleyiyorum. Herkes kafasına göre iletişim kurmuş.
Kimisi verileri birliştirip tek seferde göndermiş. Kimileri ayrı ayrı göndermiş. Bazıları Başlangıç verisini R + Veri + r şeklinde göndermiş.
Bazılar R + Veri şeklinde.
Bu haberleşmenin olması gerektiği bir standart, adap yok mudur?

z

File transferi tipi veri aktarimi icin protokoller var fakat iki cihazin muhabbetine kim neden sinir getirsin?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Tagli

Bilinen standart protokolleri uygulamak en doğrusu olur. En basit olanı Modbus'tır. Günümüzün endüstriyel gereksinimlerini pek karşılamasa da, temel hobi projeleri için yeterlidir. Uygulamanın kapsamına göre profesyonel hayatta da kullanılabilir tabi.

Ben şahsen text tabanlı protokolleri sevmiyorum ve uzak duruyorum. Özellikle de "kendi protokolünü kendin uydur" mantığına genel olarak karşıyım.
Gökçe Tağlıoğlu

ziyaretci

#3
Bu tamamen sisteminizin ihtiyacı ve kapasitesiyle alakalı bir durum. Öbür türlüsü ihtiyaca ve kapasiteye göre kullanılan teknikler standarttır diyebiliriz. Haberleşme hızınız yeterliyse, belli bir frame oluşturup, belli bir periyotta verileri şutlarsınız.

Örneğin;
100 byte'lık bir bandım var ve ben bu bandı ihtiyacıma göre böre 3'er 5'er vs. bölerek kendime göre formatladım. Ve sistemi de öyle ayarladım ki her 10ms'de(100 fps) bu 100 byte'lık bandımı şutluyorum. Artık karşısı ne isterse yapar. Karşı tarafında işleme hızı bu bandın kapasitesini 100 fps'e yetiştiriyorsa karşıyı darlamadan bu iş çözülür. Bu indikatör görevi için güzel bir yöntem mesela. Ama ihtiyacı bilmeden kesin konuşmak mümkün değil.

Veya broadcast(kesintisiz) olarak da veri yollayabilirsiniz. Karşı taraf sizden hız bekler, hemen istenilen data'yı ayrıştıracak birkaç byte daha ekleyip şutlarsınız. Bu şekilde fps bazında hızınız artar ama data çeşitliliğiniz(bandınız) kısalır.

Veya sizin için veri doğruluğu önemlidir, sırf hata oranını düşürmek için bandınızdan yemek zorunda kalırsınız. Hem zamandan hem kapasiteden taviz verirsiniz. Karşıdan hatalı paket ya da alındı onayı almak için.

Bu iş biraz belli dinamikler dahilinde standart olsa da ihtiyaca ya da tasarımcıya göre değişebilen bir durumdur. Bazı oyunların kendi oyun motorlarını yapması gibi. Çünkü oyuna kattıkları özellik varsayılan motoru yetersiz kılabilir(her yönden). Böylelikle özelliğin ihtiyacına göre bir tasarım yaparak ping süresini kısaltabilirler. Lag oluşmaz vs.  :)

Peki ihtiyacınızı nasıl belirleyeceksiniz?
Öncelikle kapasite analizi yapmalısınız. Örneğin haberleşme hızı, istediğiniz fps hızı, veri boyutunun fps ile uyumuna bakmak gibi.

Aşağıdaki resimde ne demek istediğimi daha iyi anlayacaksınız. Fiziksel katmanla ilgili bir resim ama mantık aynı. Benim size yukarıda anlatmaya çalıştığım OFDM.



Mesela, nextion hmi 0xFF, 0xFF, 0xFF ile api kodlarını sonlandırmanızı ister. Bu kodu işlemek için gelen datanın son 3 byte'ının 0xFF olduğunu kontrol eder ve 3xFFh'a kadarki datayı bufferdan işleyeceği alana çeker.

Ek:
Örneğin;
{01 03 00 AA 00 FF FF FF} yolladığınızda, haberleşme ucundan hangi data gelirse gelsin direkt olarak önbelleğe yazarsınız ve her data için önbellek indeksini arttırırsınız. Ana döngüde ise önbelleği dinamik bir indeks ile okuyup son 3 byte'ı kontrol edersiniz.

Void uart()
{
   onbellek[i]=RXREG;
   if(i<onbellek_boyutu-1)
   {
       i++;
   }
   else
       i=0
}

void main()
{
   for(;;)
   { 
      ii=i;
      while(ii!=j)
      {
         paket[jj] = onbellek[j];
          if(j<onbellek_boyutu-1)
         {
            j++;
         }
         else
         {
            j=0;
         }
        if(jj>1)
         {
            if(paket[jj]==0xff && paket[jj-1]==0xff && paket[jj-2]==0xff)
            {
                paket_isle(); // gibi
                jj=0;
               paket_islendi=1;
            }
         }
         if(j<paket_boyutu-1)
         {
            jj++;
         }
         else
         {
            jj=0;
         }
         if(paket_islendi)
         {
               jj=0;
              paket_islendi=0;
         }
      }
   }
}

veliusta

@z Benim şuan veri alma yöntemim "Bir Harf + Veri"  Bilgisayar Kısmından da İlk Harfi Sil Kalan veri sayı ise Kutucuğa yazdır Şeklinde.
Aslında Sizin YouTube kalınızda yaptığınız projeyi yapmak istiyorum. Breakboard'da yaptığım çalışmalarda MCU'ya Buton veya Led bağlamak yerine simülasyon tarzı bir programdan kontrol etmek amacım. Elimde öyle bir çalışma olması iyi olur. Projeyi benimle paylaşırsanız çok işime yarar.
Hocam Dikkatimi çekti, Siz neden Delphi 7 ile yazıyorsunuz? Lazarus aynısı değil mi? Hem ücretsiz hem özgür.

z

#5
Bir harf bir veri yetersiz.

Baslatma verisi, N byte veri, check sum, bitis verisi seklinde yapmani oneririm.

Delphi 6 ve 7'ye alisigim yeni bir dil ya da ortama gecmeye zamanim yok.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

veliusta

Haberleşme konusuna hakim değilim.

@z # LED1 ON \n    Bu şekilde mi?

Hocam siz o uygulama Butonlarını sürekli okumamı yaptırıyorsunuz? Yoksa Sadece Butona basılırsa bir kez "# BUTTON1 ON \n" verisini mi gönderiyorsunuz? Buton'dan elinizi çekince "# BUTTON1 OFF \n" verisi şeklinde.
Ya da Progresbardaki Analog değerleri sürekli gönderiyor musuz yoksa sadece değer değiştiğinde birkez mi gönderiyor sunuz?

CH340C entegresi için haberleşmesi baund hızı 115200 fazla mı? Aynı anda Hem veri gönderip, hem veri alabiliyor muyuz? Çakışma oluyor mu yoksa sıraya girip beklememi yapıyor.

Visual Studio ile MCU Serial Haberleşmede String değerinden mi haberleşme üzerinden mi yapılıyor genelde?

z

#7
Tercih meselesi ama ben soyle bir yapi kuruyorum.

Atiyoum start char 0xAA
End char 0x55

0xAA, Cmd, data1, data2, data3, ...., CheckSum, 0x55

Karsi taraf 0xAA aldimi biliyor ki bir sonraki Komut

Komutu aldimi biliyorki N tane data gelecek

N datayi aldimi biliyor ki CheckSum

CheckSum geldimi  biliyorki 0x55 gelecek.

Bu kurguda bir hata bile olsa bu blok oldugu gibi cop

Tum bu islemleri int rutini icinde state machine mantigi ile yapiyorum.

Ornegin CMD alindiginda 0x00... 0x17 araligindaki komutlarda data sayisi 1 byte
0x17..0x20 araligi 2 byte gibi komutlari da katagorise ediyorum.

Basarili veri blogu alindiginda atiyorum 100mS icinde data aldim cevabi gondermezse karsi taraf ayni blogu bir kez daha yolluyor.

Surekli veri gondermek yerine saece degisim oldugunda veri gonderiyorum.

Yapiyi bu sekilde yaparsan sistem haberlesirken seri iletisim kablosunu sokup taksan bile sistem hic bir mudahaleye gerek kalmadan sorun oldugunu anliyor ve iletisimi duzgun sekilde kendiliginden yapabiliyor.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

power20

Start komutu en az 2 bayt olsun.  Başında preamble amaçlı fuzuli karakter olsun.FFFF

kudretuzuner

Merhaba, bu yazışmalarla çok faydalı bilgiler öğrenmekteyim. Çalışmalarım da PC ve MCU haberleşmesi üzerinedir. Gerek PC'den data yollayarak MCU'yu çalıştırmak gerekse MCU'dan PC'ye yollanan dataları işleyip ara yüz olarak işlem yaptırmak oldukça kolaydır. Benim uyguladığım yöntem örneğin MCU'dan tamamen random yollanan dataları( ki tek tek BYTE olarak yollamaktayım 00-FF arası) daha önceden anlamlandırılmış şekillerle PC'den okumaktayım. Tabii bunun da zahmeti, olası 00-FF arası dataların tamamını tanımlayıp bir dosya (atıyorum C\:) altında toplayarak ara yüzü yazılımında çağırıyorum. PC'den MCU kontrolu için de yazılım gereği PC hazır beklemede oluyor klavyeden veya ara yüzden yolladığınız her BYTE' kontrol ediyor yazılımda atadığınız BYTE'a eşit olunca MCU işlem yapıyor. Bu tür son bir çalışmam 8 sensörden gelen analog değerleri dijitale çevirip 00-FF arası gelen tüm dataları kontrol edebilmekteyim. Tabii ara yüz yazılımında 8 sensörü karşılıklı dörder dörder mukayese edebilmek için sadece 4 adet daha önceden tasarlanmış herhangi bir BYTE yollanmaktadır. Özetle haberleşme olayı sizlerin de yazdığı gibi tamamen yapımcının elindedir. Ama bilinmeyen MCU'dan gelen datalar için maalesef 00-FF arası değerleri gösterecek bir ara yüz hazırlamak gerekir. Akarak gelen tüm BYTE ları görürseniz anlamlandırmak olası olur. Aşağıdaki videoda hem PC tarafından hem de MCU tarafından karşılıklı data alış verişi yapan bir çalışmalarımdır.                                                                             https://www.youtube.com/watch?v=FZ2LI5Cv5wM
 https://www.youtube.com/watch?v=HL5IDpnKPig
Amatör

z

Alıntı yapılan: Kılıç - 14 Mayıs 2022, 15:00:47Start komutu en az 2 bayt olsun.  Başında preamble amaçlı fuzuli karakter olsun.FFFF

Boyle bir seye niye ihtiyac duyuyorsun?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

power20

#11
Başlangıç  karakteri tek olursa yanlışlıkla denk gelebilir.  Hatalı algılama ihtimali yüksek.

Kod içerisinde belli karakterleri bekleme rutini var. Bu sayede paket başlangıcı kolayca yakalayabiliyordu.checksum yoktu

foseydon

bu konularda daha önce yazdım bolca. geçmiş mesajlarıma bakarsanız ordan da faydalı şeyler çıkartabilirsiniz. birde wiki tarzı birşey lazım foruma. şu seri port mevzusu hiç gelmediyse 10 sefer geldi. aynı şeyleri yazaya üşeniyorum valla.