Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Snap7 E Readmultivars


Messaggi consigliati

Paolo GUerrieri
Inserito:

Buongiorno a tutti, è da poco che sto usando la libreria Snap7, sto provando ad usare la funzione ReadMultivars in c# ma ho degli errori nel codice,

try
{
lock (objLock)
{
byte[] E = new byte[100];
byte[] E1 = new byte[100];
S7Client.S7DataItem[] items = new S7Client.S7DataItem[2];
items[0].Area=S7Client.Block_DB;
items[0].WordLen= S7Client.S7WLByte;
items[0].Start=0;
items[0].DBNumber=1;
items[0].Amount= 100;
items[0].pData= E;//Errore 8 Impossibile convertire implicitamente il tipo 'byte[]' in 'System.IntPtr'
items[1].Area = S7Client.Block_DB;
items[1].WordLen = S7Client.S7WLByte;
items[1].Start = 106;
items[1].DBNumber = 1;
items[1].Amount = 100;
items[1].pData = E1;
int i= s7.ReadMultiVars(items, 2);///Errore 9 La corrispondenza migliore del metodo di overload per 'Snap7.S7Client.ReadMultiVars(ref Snap7.S7Client.S7DataItem, int)' presenta alcuni argomenti non validi
}
return bytes;
}
Qualcuno potrebbe dirmi come si imposta correttamente questa funzione
Grazie
Paolo

Inserita:

Un utente di sourceforge ha appena migliorato il meccanismo per il MultiRead/Write per .net.

Apparirà nella prossima daily, nel frattempo :

1) Modifica ReadMultiVars e WriteMultiVars in snap7.net.cs come segue:

    [DllImport(S7Consts.Snap7LibName)]
    protected static extern int Cli_ReadMultiVars(IntPtr Client, S7DataItem[] Items, int ItemsCount);
    public int ReadMultiVars(S7DataItem[] Items, int ItemsCount)
    {
        return Cli_ReadMultiVars(Client, Items, ItemsCount);
    }

    [DllImport(S7Consts.Snap7LibName)]
    protected static extern int Cli_WriteMultiVars(IntPtr Client, S7DataItem[] Items, int ItemsCount);
    public int WriteMultiVars(S7DataItem[] Items, int ItemsCount)
    {
        return Cli_WriteMultiVars(Client, Items, ItemsCount);
    }

2) Modifica S7DataItem come segue:

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct S7DataItem
    {
        public Int32 Area;
        public Int32 WordLen;
        public Int32 Result;
        public Int32 DBNumber;
        public Int32 Start;
        public Int32 Amount;
        public IntPtr pData;

        public void Set<T>(Int32 Area, Int32 WordLen, Int32 DBNumber, Int32 Start, Int32 Amount, ref T[] Buffer)
        {
            Set(Area, WordLen, DBNumber, Start, Amount, ref Buffer, 0);
        }

        public void Set<T>(Int32 Area, Int32 WordLen, Int32 DBNumber, Int32 Start, Int32 Amount, ref T[] Buffer, Int32 Offset)
        {
            this.Area = Area;
            this.WordLen = WordLen;
            this.Result = 0;
            this.DBNumber = DBNumber;
            this.Start = Start;
            this.Amount = Amount;
            GCHandle handle = GCHandle.Alloc(Buffer, GCHandleType.Pinned);
            this.pData = handle.AddrOfPinnedObject() + Offset * Marshal.SizeOf(typeof(T));
            handle.Free();
        }
    }

Infine questo è un esempio :

        using Snap7;

        S7Client client = new S7Client();
        int error = client.ConnectTo("192.168.0.10", 0, 2);
        if (client.Connected())
        {
            byte[] E = new byte[200];
            S7Client.S7DataItem[] items = new S7Client.S7DataItem[2];
            items[0].Set(S7Client.S7AreaPE, S7Client.S7WLByte, 0, 0, 1, ref E);
            items[1].Set(S7Client.S7AreaPE, S7Client.S7WLByte, 0, 20, 1, ref E, 20);

            client.ReadMultiVars(items, 2);
            client.Disconnect();

            MessageBox.Show("EB0: " + E[0].ToString() + ", EB20: " + E[20].ToString());
        }

Ciao

Davide

Paolo GUerrieri
Inserita:

Ok perfetto grazie 1000,...

qualcosa però continua a non andare....

byte[] Allbyte = new byte[300];
S7Client.S7DataItem[] items = new S7Client.S7DataItem[3];
items[0].Set(S7Client.S7AreaDB, S7Client.S7WLByte, 1, 0, 100, ref Allbyte);//Sinottico
items[1].Set(S7Client.S7AreaDB, S7Client.S7WLByte, 1, 106, 100, ref Allbyte, 100);//Comandi manuali
items[2].Set(S7Client.S7AreaDB, S7Client.S7WLByte, 1, 606, 100, ref Allbyte, 200);// out plc
s7.ReadMultiVars(items, 3);
forse sto sbagliando qualche impostazione....mi torna tutto 0
in pratica il db 1 lo devo spezzettare in 3 array da 100 byte ciascuno, il primo parte dal byte da 0, il secondo dal byte 106 ed il terzo dal byte 606
Grazie 1000
Saluti
Paolo
Inserita:

La quantità totale dei dati trasferiti (più le informazioni di header) con le funzioni Read/WriteMultivars non può superare il PDU size negoziato (come spiegato sul manuale).

Per cui, a meno che tu non stia utilizzanto un S7400 o WinAC o una CPU VIPA hai negoziato, 240 byte.

Devi usare 3 chiamate sequenziali usando DBRead o ReadArea. Per 300 byte complessivi dovresti essere intorno a 15 ms in totale.

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...