Modbus RTU Frame Yapısı

Başlatan serhat1990, 04 Ocak 2013, 11:42:44

serhat1990

Merhabalar değerli PicProje üyeleri ,

Bir sorum olacaktı. Modbus RTU için bir kütüphane yazacam Hi-Tech C dilinde . Modbus RTU frame yapısında okuduğum kaynaklarda , 3.5 karakter süresi kadar boşluk gönderilerek haberleşme başlıyor .

Sonrasında -->  Adres --> Fonksiyon --> Veri --> CRC Kodları ve 3.5 karakter boşluk süresi ile bitirildiğini gördüm . Sorularım şunlar .

1- Buradaki 3.5 karakter süresi sabitmidir ?
2- Veri kontrolü yapmayacaksam datanın başlayıp bittiğini nasıl anlayabilirim . Veri içerisinde 4 byte ve üstü boş veri gönderilirse bunu sistem sonlandırma datası olarak algılayabilir diye düşünüyorum .

Bu konuda yardımlarınızı , önerebileceğiniz kaynakları bekliyorum . Herkese iyi çalışmalar ... 



94220039

Yazacaklarım için "bu böyledir" diye bir iddiam yok. Ancak MODBUS RTU'yu otomasyon sistemlerinde kullanan birisi olarak şunları söyleyebilirim.

*** 3,5 karakter : Haberleşme hızı 9k6, Data yapsı  1-start biti 8-Data biti 1-stop biti olacak şekilde bir seçim yapılmışsa 1 karakter için harcanacak süre 1,0416666 ms'dir. Bu durumda 3,5 karakterlik sürede 3,6458 ms'dir. Bu süre doğal olarak Haberleşme Hızı ( Baud Rate) ve Data Yapısına göre değişir.


**** Zaten dataları alırken veri kontrolü yapmak pek doğru olmaz. Alım işlemini sonlandırmak için her data alındıktan sonra bir timer başlatırsın, 3,5 karakter süresince herhangi bir data alımı olmadığı zaman işlemi sonlandırırsın. Daha sonra da aldığın datalarda veri kontrolü yaparak alımın doğru olup olmadığını kontrol edebilirsin.


***** Boş veri diye bişey yoktur. "idle time" diye bişey vardır. o da MODBUS RTU'da 3,5 karakterlik süredir.


serhat1990

#2
Anladım Hocam hatalı bir tabir yazmışım oraya ( Boş veri gönderme kısmında ) . Start ve stop bitlerini tamamen atlamışım , kafamda artık ne varsa :)

3.5 karakter süresinin 9.6Kbps hıza göre olduğunu yazmayı unutmuşum . Bit hızına göre değişiyor . Birşey daha var data başlarken geçen bu idle time dediğimiz sürede veri hattının lojik seviyesi 0'mı oluyor ( 3.5 karakter süresi boyunca ) . Normalde RX kısmı lojik-1 seviyesinde bekliyor. Start biti olan 0'ı bekliyor ... Modbus RTU'da hat boşta iken ve idle time dediğimiz zamandayken aynı RS232 gibimi davranıyor .

Teşekkür ederim yanıt için . İyi çalışmalar dilerim ... 

Salih

Alıntı yapılan: serhat1990 - 04 Ocak 2013, 11:42:44

2- Veri kontrolü yapmayacaksam datanın başlayıp bittiğini nasıl anlayabilirim . Veri içerisinde 4 byte ve üstü boş veri gönderilirse bunu sistem sonlandırma datası olarak algılayabilir diye düşünüyorum .

Bu konuda yardımlarınızı , önerebileceğiniz kaynakları bekliyorum . Herkese iyi çalışmalar ...

Şöyle bir yöntem kullanılabilir.
Gelen verinin ilk baytı kullanılan fonksiyon nosudur.
Örneğin register okuma 03 gibi.
ikinci bayt cihazın adresidir. Gelen verinin iki baytını kontrol ederek veri almayı başlatırız.
Kullandığınız fonksiyonun göndereceği bayt sayısı bellidir. Bu şekilde veri alınabilir.

serhat1990

Hocam , adapte edeceğim sistemler arasında repeate görevi göreceksem bu verinin uzunluğunu bilme şansım yok ... RTU çalışan sistemleride ben yapsam zaten böyle birşey sormaya gerek yok giden gelen herşeyi bilecem . Ama farklı sistemlerde uzunluk belli olmayacak . 3.5 Karakter uzunluğundaki idle time denilen zamandan anlayacak sistemler başka yol yok gibi . Ondada aklıma takılan soruların yanıtını bulamadım , yada buldum anlayamadım :)






Salih

Alıntı yapılan: serhat1990 - 04 Ocak 2013, 15:04:38
Hocam , adapte edeceğim sistemler arasında repeate görevi göreceksem bu verinin uzunluğunu bilme şansım yok ... RTU çalışan sistemleride ben yapsam zaten böyle birşey sormaya gerek yok giden gelen herşeyi bilecem . Ama farklı sistemlerde uzunluk belli olmayacak . 3.5 Karakter uzunluğundaki idle time denilen zamandan anlayacak sistemler başka yol yok gibi . Ondada aklıma takılan soruların yanıtını bulamadım , yada buldum anlayamadım :)

Eğer haberleşme hızını bilmiyorsanız, dediğiniz yöntemi kullanmakta mümkün gözükmüyor.
Belki son iki karekter olan CRC16 kontrol ederek verinin sonunu bulabilirsiniz.
Gelen her veriyi CRC16 işleminden geçirerek sonradan gelen 2 bayt ile kontrol edersiniz.
CRC16 eşleşince verinin sonlandığını anlarsınız.
Ben denemedim.

serhat1990

Alıntı yapılan: salih - 04 Ocak 2013, 16:02:01
Eğer haberleşme hızını bilmiyorsanız, dediğiniz yöntemi kullanmakta mümkün gözükmüyor.
Belki son iki karekter olan CRC16 kontrol ederek verinin sonunu bulabilirsiniz.
Gelen her veriyi CRC16 işleminden geçirerek sonradan gelen 2 bayt ile kontrol edersiniz.
CRC16 eşleşince verinin sonlandığını anlarsınız.
Ben denemedim.

Hocam haberleşme hızını biliyorum onda sıkıntı yok . Bu bir seçenek ama bir işlem külfiyatı olacak . Sürekli CRC kod değişecek . Doğru değilse CRC koduna ekle falan . Ama düşünülebilir . Kafamda bir yapı oluşturdum şimdi programa dökmeye başladım . Olur diye umuyorum bakalım :)

Cevap için teşekkürler ...

camby

#7
Slave tarafında,

Her byte geldiğinde timer kurulması gerekiyor, bu timer baud hızına göre olacak , 3.5 char süre. Timer bize paketin bitip bitmediğini gösterecek.

Eğer timer taşmadan önce yeni bir byte gelirse ,  timer baştan kurulacak. Bu şekilde her gelen byte kayıt edilecek.

Eğer timer taşıp kesme üretilirse , veri paketin bittiğini ( 3.5 char sürenin dolduğunu ) ve o pakete ait başka byte gelmeyeceğini anlamış oluruz.


Tüm verileri aldık diyelim diyelim 30 byte geldi ve hepsini ram'de bir alana kayıt ettik.

Yapılacak ilk iş ilk 28 byte'a göre CRC hesaplatıp , gelen CRC ile karşılaştırmak. Eğer uyuşmuyorsa gelen paket dikkate alınmaz. Paket ve diğer hatalar da doğrulanırsa gelen Modbus isteğini işleme koyabiliriz.

-------

Yukarıdakilere ek olarak performans geliştirmeleri de yapılabilir.

- Örneğin ben CRC'de şunu yapıyorum. Öncelikle veri paketinin hangi slave cihazına yollandığına bakıyorum , eğer slave adresi farklıysa CRC yada başka bir işlem yapmadan direk paketi çöpe atıp işlemi sonlandırıyorum. Çünkü CRC hesaplama işlemi vakit alıyor , eğer mesaj başka bir cihaza gitmiş ise gereksiz yere CRC vakti harcamıyorum.

- Benzer olarak byte'lar alındığı sırada , parity , overrun , frame error gibi hatalar gerçekleşirse , o paket boyunca herhangi bir kayıt yada kontrol işlemi yapmıyorum , gelmekte olan paketi direk çöpe atıp işime geri dönüyorum.

--------

Master tarafında da ,

Master Bir istek yollayacak diyelim , veri paketinin başında ve sonunda yine 3.5 char süre beklemesi gerekir. Bu çok kritik bir işlem değil çünkü öncesinde hat zaten idle konumunda , sonrasında da 3.5 char süreden önce bir cevap gelmeyeceği de kesin çünkü tüm slave ler bu şekilde çalışıyor
ama yine de uygulamak lazım olası hataları önlemek için. Belki de Multimaster çalışmalarda kritik olabilir.

serhat1990

Detaylı açıklama için çok teşekkürler Hocam ...