Vai al contenuto
PLC Forum


Snap7 E Readmultivars


Paolo GUerrieri

Messaggi consigliati

Paolo GUerrieri

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
Link al commento
Condividi su altri siti


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

Link al commento
Condividi su altri siti

Paolo GUerrieri

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
Link al commento
Condividi su altri siti

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.

Link al commento
Condividi su altri siti

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...