C# ModBus RTU Haberleşmesi

Katılım
11 Nis 2014
Mesajlar
3
Puanları
1
Yaş
52
arkadaşlar iyi çalışmalar internetden bulduğum örneği inceleyerek modbus RTU haberleşmesini çözmeye
çalışıyorum..
örnekde 11 adet byte türünde data seri porta yazılıyor bu dataların neler olduğunu tam olarak çözemedim
yardımcı olursanız sevinirim

saygılarımla

message[0] = //Slave ID-plc adresi
message[1] = //Fonksiyon (okuma-yazma)
message[2] =
message[3] =
message[4] =
message[5] =
message[6] =
message[7] =
message[8] =
message[9] = //CRC0 hata kodu
message[10] = //CRC1 hata kodu



-----örnek çalışmanın son hali-------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}


private void button1_Click(object sender, EventArgs e)
{
serialPort1.Open();
button1.Enabled = false;
}

//Holding Register:0 //Deger:5
//Data-> 01 10 00 00 00 01 02 00 05 66 53

//Holding Register:1 //Deger:5
//Data-> 01 10 00 01 00 01 02 00 05 67 82

//Holding Register:3 //Deger:9
//Data-> 01 10 00 03 00 01 02 00 09 66 65

//Holding Register:4 //Deger:10
//Data-> 01 10 00 04 00 01 02 00 0A 27 D3

//Holding Register:5 //Deger:15
//Data-> 01 10 00 05 00 01 02 00 0F E6

//Holding Register:6 //Deger:16
//Data-> 01 10 00 06 00 01 02 00 10 A7 FA

private void button2_Click(object sender, EventArgs e)
{
//Message is 1 addr + 1 fcn + 2 start + 2 reg + 1 count + 2 * reg vals + 2 CRC
ushort registers=1;
byte[] message = new byte[9 + 2 * registers];

message[0] = 1; //Slave ID-plc adresi
message[1] = 16; //Fonksiyon (okuma-yazma)

message[2] = 0; //Okunacak registerlerin başlangıç adresi (MSB)
message[3] = 0; //Okunacak registerlerin başlangıç adresi (LSB)
message[4] = 0; //Okunacak register sayısı başlangıç (MSB)
message[5] = 1; //Okunacak register sayısı başlangıç (LSB)

message[6] = 2; //Add bytecount to message: (KAÇ byte var say)

message[7] = 0; //Put write values into message prior to sending: (yeni deger)
message[8] = 5; //Put write values into message prior to sending: (yeni deger)

message[9] = 102; //CRC0 hata kodu
message[10] = 83; //CRC1 hata kodu


serialPort1.Write(message, 0, message.Length);
MessageBox.Show("Ok");

}




#region CRC Computation
public void GetCRC(byte[] message, ref byte[] CRC)
{
//Function expects a modbus message of any length as well as a 2 byte CRC array in which to
//return the CRC values:

ushort CRCFull = 0xFFFF;
byte CRCHigh = 0xFF, CRCLow = 0xFF;
char CRCLSB;

for (int i = 0; i < (message.Length) - 2; i++)
{
CRCFull = (ushort)(CRCFull ^ message);

for (int j = 0; j < 8; j++)
{
CRCLSB = (char)(CRCFull & 0x0001);
CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);

if (CRCLSB == 1)
CRCFull = (ushort)(CRCFull ^ 0xA001);
}
}
CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
}
#endregion




private void button3_Click(object sender, EventArgs e)
{
byte address = Convert.ToByte(txtSlaveID.Text);
byte fonction = Convert.ToByte(txtFonksiyon.Text);
byte StartOn1 = Convert.ToByte(txtStartOn1.Text);
byte StartOn2 = Convert.ToByte(txtStartOn2.Text);
byte StartOff1 = Convert.ToByte(txtStartOff1.Text);
byte StartOff2 = Convert.ToByte(txtStartOff2.Text);

short[] values = new short[2];
values[0] = Convert.ToInt16(txtValue.Text);


byte[] CRC = new byte[2];


//Message is 1 addr + 1 fcn + 2 start + 2 reg + 1 count + 2 * reg vals + 2 CRC

ushort registers = 2; //hangi register değişsin
byte[] message = new byte[9 + 2 * registers];

message[0] = address; //Slave ID-plc adresi
message[1] = fonction; //Fonksiyon (okuma-yazma)

message[2] = StartOn1; //Okunacak registerlerin başlangıç adresi (MSB)
message[3] = StartOn2; //Okunacak registerlerin başlangıç adresi (LSB)
message[4] = StartOff1; //Okunacak register sayısı başlangıç (MSB)
message[5] = StartOff2; //Okunacak register sayısı başlangıç (LSB)

message[6] = (byte)(registers * 2); //Add bytecount to message: (KAÇ byte var say)

//Put write values into message prior to sending:
for (int i = 0; i < registers; i++)
{
message[7 + 2 * i] = (byte)(values >> 8);
message[8 + 2 * i] = (byte)(values);
}


GetCRC(message, ref CRC);
message[message.Length - 2] = CRC[0]; //CRC0 hata kodu
message[message.Length - 1] = CRC[1]; //CRC1 hata kodu


serialPort1.Write(message, 0, message.Length);
MessageBox.Show("Ok");
}
}
}
 
KNX Standardı, küçük bir rezidansın içerisindeki aydınlatma, perde panjur, klima kontrolünden, Dünya’nın en büyük havalimanlarındaki aydınlatma otomasyonu gibi çözümler için tercih edilen bir Dünya standardıdır.
Yazımızda endüstrinin can damarı sayılabilecek PLC’yi inceleyeceğiz.
Merhaba

11 Ader byte Modbus mesajinda göndermeniz gereken mesajın alanlarıdır. Göndermek istediğiniz mesaja göre değişir. Öncelikle modbus mesaj yapılarını öğrenmelisiniz. Modbus.org sitesinde komut yapılarını anlatan döküman mevcut. Okumanızı öneririm.
 
Okuma örneği :
ID SADDRH SADDRL CNTH CNTL CRCH CRCL (+Separator \r\n)
ID: MB adres no
SADDRH: Kaynak Adresin Yüksek bit
SADDRL: Kaynak Adresin Düşük bit
CNTH: Adet Yüksek bit
CNTL: Adet Düşük Bit
CRCH: CRC Kodu yüksek bit
CRCL: CRC Kodu Düşük bit

Bu komut yazma ile aynıdır fakat tek fark preset multiple register fonksiyonunda ilave bir byte boyutu girmeniz gerekerir(CNTH ile SADDRL arasına ne kaç adet gireceğiniz belirtlilmelidir).

Her ne kadar doğru kod yazsanızda cihazın hangi adresleri okuma yada yazma izni verdiğini dökümandan iyice irdeleyin(set buffer for read).

Yapılan hataların diğeri ise haberleşme modudur:
RTU ile ASCII arasındaki farklar:

Aşağıda ilk verilen değer ascii ikincisi ise rtu dur.
Başlangıç: ":" , NONE*
Byte ayırıcı: None,"\x" (1.5 char boşluk)

*NONE = YOK DEMEK

** RTU ikiye ayrılır seri üstünde(seri port), ethernet. Ayrıca 8 bit ve 16 bit diye ayrılabilir(gönderdiğiniz paketler değişmez fakat alacağınız cevabın boyu değişir(Aynı anda daha çok veri okuma/yazma)). Örnek 16 bit bir portda 50 adet 16 bitlik data adresini 100ms de bir rahatlıkla okuyabilirsiniz(Hmi ile denemeyin !).

 

Forum istatistikleri

Konular
128,125
Mesajlar
915,221
Kullanıcılar
449,837
Son üye
betül hüsrevoğlu

Yeni konular

Geri
Üst