PLC - C# Haberleşmesi, Veri Okuma

Başlatan neo, 12 Kasım 2018, 13:30:02

neo

Merhabalar,

Siemens S7-1200/1500 PLC ile bir C# uygulamasını nasıl haberleştirebiliriz?

Bildiğim birkaç kütüphane var S7.net, Sharp7, Snap7 gibi. Amacım PLC'nin DataBlock'larındaki verileri okumak. Sharp7 (multiread methodu) ile en fazla 400 byte civarında veri okuyabiliyorum. Yani DataBlock'un 400byte'tan sonraki adreslerine ulaşamıyorum. Aşağıda kodları paylaşacağım. Daha fazla veriyi nasıl okuyabilirim?

S7 PLC - C# haberleşmesinde tavsiye edebileceğiniz daha farklı bir yöntem var mıdır?


using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sharp7;

namespace WindowsFormsApplication_MultiRW_Example
{
    public partial class Form1 : Form
    {
        static S7Client client = new S7Client();
        static S7MultiVar s7MultiVar = new S7MultiVar(client);
        public static byte[] bufferx = new byte[Constants.BUFFER_SIZE];
        public static int result;

        //------------------------------------------------------------------------------
        // Constants
        //------------------------------------------------------------------------------
        static class Constants
        {
            public const int START_NUMBER = 0;
            public const int OPTION_READ_NUMBER = 1;
            public const int OPTION_WRITE_NUMBER = 2;
            public const int BUFFER_SIZE = 400;
            public const int NO_ERROR_NUMBER = 0;
            public const int RACK_NUMBER = 0;
            public const int SLOT_NUMBER = 1;
            // BUFFER_SIZE'ın DB_Size'dan büyük olması sorun çıkartabiliyor. BUFFER_SIZE 458'den büyükse sorun çıkıyor
        }

        //------------------------------------------------------------------------------
        // Connect to PLC
        //------------------------------------------------------------------------------
        private void connect_to_plc(string plc_adress)
        {
            result = client.ConnectTo(plc_adress, Constants.RACK_NUMBER, Constants.SLOT_NUMBER);
            if (result == Constants.NO_ERROR_NUMBER)
            {
                lbl_result.Text = "Connected to " + plc_adress;
            }
            else
            {
                lbl_result.Text = client.ErrorText(result);
                return;
            }
        }

        //------------------------------------------------------------------------------
        // Multi Read
        //------------------------------------------------------------------------------
        private void multi_read_from_db(int db_number, int data_adress)
        {
            s7MultiVar.Add(S7Consts.S7AreaDB, S7Consts.S7WLByte, db_number, Constants.START_NUMBER, bufferx.Length, ref bufferx);
            result = s7MultiVar.Read();
            if (result == Constants.NO_ERROR_NUMBER)
            {
                lbl_result.Text = "DB" + db_number + ", " + data_adress + ".0 = " + S7.GetWordAt(bufferx, data_adress);
            }
            else
            {
                lbl_result.Text = ("Error on s7MultiVar.Read() " + result);
            }
            txb_dataValue.Text = "";
            // DB'den BUFFER_SIZE kadar data, bufferx'e aktarıldı.
        }

        
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txb_plcAdress.Text = "192.168.0.1";
            lbl_result.Text = "";
        }

        private void btn_connect_Click(object sender, EventArgs e)
        {
            string plc_adress = txb_plcAdress.Text;
            connect_to_plc(plc_adress);
            
        }

        private void btn_read_Click(object sender, EventArgs e)
        {
            int db_number = int.Parse(txb_dbNumber.Text);
            int data_adress = int.Parse(txb_dataAdress.Text);
            multi_read_from_db(db_number, data_adress);
        }
    }
}
Have you ever questioned the nature of your reality?

tunayk

Sharp7 ve libnodave  genel olarak kullanılan kütüphaneler.  libnodave'i yıllardır kullanırım pek sorun yaşamadım.  maksimum 240Byte okur, daha uzun okuma için kendiniz birkaç adımda okuyacaksınız.

Sharp7 nin .Net olan kodunu kullanıyorum şu aralar,birkaç fonksiyonda bug vardı.  Onları düzelttikten sonra pek sorun görünmüyor. 880 Byte'lık DB okuyorum.

PLC kodu da sizde ise, kodunuza Modbus TCP server gömebilirsiniz. Bu durumda herhangi bir modbus kütüphanesi işinizi görür. 

neo

#2
Anladım teşekkürler. Bahsettiğiniz fonksiyonlar hangileri
Have you ever questioned the nature of your reality?

anilkaygisiz

#3
Merhaba,
Bu şekilde 836 byte arrayi okuyorum ve hiç sıkıntı çıkmıyor. Cevap geç olmuş ancak dursun hiç kaynak yok zaten
                        int StartIndex = 0;
                        byte[] readBuffer = new byte[836];
                        int resultDBRead = client.DBRead(DBNumber, StartIndex, readBuffer.Length, readBuffer);
                        foreach (var tag in tags)//Elinizdeki tagler burada olacak ve okumayı buradan yapacaksınız
                        {
                            pLCTag.TagValue = S7.GetByteAt(readBuffer, tag.Offset);//byte
                            pLCTag.TagValue = S7.GetWordAt(readBuffer, tag.Offset);//word
                            pLCTag.TagValue = S7.GetRealAt(readBuffer, tag.Offset);//dword
                            //Stringte iş biraz karışık. 20 lik bir alanın 0 indexte alanın toplam boyutu yazar, 1. indexte de içerisindeki değerin toplam boyutu yazar o sebeple aslında 18lik alan vardır
                            pLCTag.stringset = S7.GetStringAt(readBuffer, tag.Offset);//String ise bu ama bazen alttaki
                            pLCTag.charset = S7.GetCharsAt(readBuffer, tag.Offset , tag.DataTypeSize);//String ancak boyut vermeniz gerekiyor
                        }