Vai al contenuto
PLC Forum


Socket C# - 1756 Enbt


mr. white

Messaggi consigliati

Buongiorno

è possibile comunicare con il controllogix tramite 1756enbt

con socket da un sw C#?

Nel caso esiste un esempio semplice che apre la connessione

legge dei dati e ne scrive altri?

Grazie

:unsure:

Link al commento
Condividi su altri siti


Anche il nostro Team di ricerca ha tentato di usare un Socket TCP per comunicare con un Modulo 1756-ENBT

ma cio' non e' attualmente possibile,

forse in futuro con qualche aggiornamento firmware sara' possibile. per ora il modulo ENBT, puo' benissimo funzionare con dispositivi che implementano il protocollo CIP "Common Industrial Protocol (CIP)"

devi contattare il consorsio ODVA per Ethernet-IP

Percio' devi usare il Modulo 1756-EWEB che permette di gestrire i Socket, E-mail, web-server

ed altro.

Link al commento
Condividi su altri siti

Non conosco CIP e quindi ti chiedo se risulterebbe

molto complesso implementarlo autonomamente.

L'ODVA che mi suggerisci mi aiuterebbe in questo?

Grazie

Ciao

Link al commento
Condividi su altri siti

Dovresti chiedere al Consorsio ODVA, per avere le librerie per implementare a Livello "applicazione"

questo Protocollo CIP.

Non tutto il Protocollo, ma solo quella parte di protocollo che ti permetta di scambiare dei Dati con il Modulo 1756-ENBT.

Poi dipente dalla tua bravura nel implementare questo CIP in Linguaggio C#.

Il Consorsio ODVA ti puo' seguire, e darti anche la certificazione sulla tua Applicazione.

Chiaramente questo potrebbe essere un valido investimento per un azienda, ma per un singolo, e' tutto da valutare.

Perche' certamente servira' molto tempo e anche del denaro.

Alcure librerie "dll" di Comunicazione le puoi avere con RsLinx versione SDK.

Noi abbiamo studiato questa possibilita' per far dialogare con un dispositivo Hardware con interfaccia Ethernet.

Poi abbiamo interroto momentaneamente lo studio perche' abbiamo intravisto dei dispositivi IC che implemetavano a livello di Chip questo protocollo, che ci risolveva quasi tutte le nostre esigenze.

oppure perche' non usi quel modulo che gia' ti ho consigliato 1756-EWEB ?

Link al commento
Condividi su altri siti

Eweb me lo sto procurando e tento sicuramente questa strada.

Ti chiedo inoltre se conosci qualcosa a riguardo delle pestazioni che

si possono ottenere, soprattutto a livello di velocità (magari con pochi dati da

scambiare).

Il mio sistema dovrebbe chiudere il loop (includendo quindi anche lo scambio

dati via rete in 20 msec).

Grazie

Ciao

Link al commento
Condividi su altri siti

Con il Modulo 1756-EWEB puoi instaurare sia un Socket TCP che UDP, percio' sicuramente nella modalita'

UDP sara' velocissimo certamente <20ms (Chiaramente dipente dal numero di dati da inviare)

Chiaramente se usi il Modulo 1756-EWEB non potrai indirizzare Moduli I/O (Ethernet-IP), per questo motivo

se hai la necessita' di interfacciarti con degli I/O in Rete Ethernt-IP devi inserire anche il Modulo

1756-ENBT oppure 1756-EN2T.

Link al commento
Condividi su altri siti

Intendi un esempio per creare un Socket Client o Server per il Modulo 1756-EWEB ?

Con questo modulo puoi creare un’ istruzione Message MSG, ed aprire un Socket.

In questo modo specificando indirizzo del Host, e la Porta,

potrai inviare e Ricevere Dati, creando appunto un Buffer di Scambio Dati.

Potresti usare per testare la connessione HyperTerminal settando

Un collegamento WinSocket, specificando indirizzo e porta.

In C# ci sono delle Class-Object che gestiscono i Socket TCP/IP o UDT, un esempio in C# non lo posseggo. Potresti guardare su Internet di sicuro potrai trovare un esempio

Guarda in http://msdn.microsoft.com/library/ oppure http://msdn.microsoft.com/library/ita/

Per il Manuale 1756-EWB pagine 126-160

http://literature.rockwellautomation.com/i...um527_-en-p.pdf

Questi esempi li ho trovati

Link al commento
Condividi su altri siti

Ho scaricato all' incirca gli stessi esempi che hai visto anche tu.

Sono riuscito a inviare messaggi ma non riesco a riceverne.

Ti descrivo la struttura del sistema :

Lato PLC ho implementato l'esempio scaricabile dalla KnowledgeBase

di Rockwell (tn 32962 A131152816 ) EWEB_SOCK_UDP_VER2_1.ACD

che crea una socket e poi fa read e write modo UDP. Ci sono poi anche EWEB_SOCK_TCP_CLIENT_VER2.ACD e EWEB_SOCK_TCP_SERV_VER2.ACD

per TCP server e client. Poi insieme ai .ACD c'è un exe

che tramite una maschera si collega con l'opzione che si desidera (UDP, TCP cl. , TCP serv.)

Ovviamente uso UDP e la maschera tramite pulsanti manda un testo e riceve dal PLC

un altro testo.

Con una mia elaborazione dell'esempio scaricato da msdn.microsoft.com/library (come anche tu

mi indichi) riesco ad inviare un dgram al PLC ma non riesco a leggere ciò che arriva da PLC.

In tale codice è implementato sia il sistema di receive con attesa di risposta (che non arriva)

sia della callback (detta asincrona) ma anche in questo caso non succede nulla.

in http://msdn2.microsoft.com/en-us/library/t...wb1(VS.71).aspx c'è un esempio che ho usato

per creare una funzione che in modo UDP resti in ascolto di messaggi inviati dal PLC.

in http://msdn2.microsoft.com/en-us/library/w...yex(VS.71).aspx invece ho trovato le implementazioni che probabilmente mi suggerisci tu.

Ho un po rielaborato il tutto ed il risultato è quanto allego qui

Grazie

Ciao

using System;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.Text;

// State object for receiving data from remote device.

public class StateObject

{

// Client socket.

public Socket workSocket = null;

// Size of receive buffer.

public const int BufferSize = 256;

// Receive buffer.

public byte[] buffer = new byte[bufferSize];

// Received data string.

public StringBuilder sb = new StringBuilder();

}

public class AsynchronousClient

{

// The port number for the remote device.

private const int port = 10002;

private const int loc_port = 10001;

// ManualResetEvent instances signal completion.

private static ManualResetEvent connectDone =

new ManualResetEvent(false);

private static ManualResetEvent sendDone =

new ManualResetEvent(false);

private static ManualResetEvent receiveDone =

new ManualResetEvent(false);

// The response from the remote device.

private static String response = String.Empty;

private static void StartClient()

{

int i;

// Connect to a remote device.

try

{

// Establish the remote endpoint for the socket.

// The name of the

// remote device is "host.contoso.com".

//IPHostEntry ipHostInfo = Dns.Resolve("10.0.0.68");

//IPAddress ipAddress = ipHostInfo.AddressList[0];

IPAddress ipAddress = IPAddress.Parse("10.0.0.68");

IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

//EndPoint rem_EP = (EndPoint)remoteEP;

// Create a TCP/IP socket.

Socket client = new Socket(AddressFamily.InterNetwork,

SocketType.Dgram, ProtocolType.Udp);

// Connect to the remote endpoint.

client.BeginConnect(remoteEP,

new AsyncCallback(ConnectCallback), client);

connectDone.WaitOne();

i = 0;

while (i < 1000)

{

// Send test data to the remote device.

Send(client, "This is not a test !!!! <EOF>");

sendDone.WaitOne();

// Receive the response from the remote device.

// qui utilizzo la versione UDPlistener

-> ReceiveDgram(remoteEP,client);

// qui utilizzo la versione fornita con questo esempio

-> Receive(client);

//receiveDone.WaitOne();

// Write the response to the console.

Console.WriteLine("Response received : {0}", response);

i++;

}

// Release the socket.

client.Shutdown(SocketShutdown.Both);

client.Close();

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static void ConnectCallback(IAsyncResult ar)

{

try

{

// Retrieve the socket from the state object.

Socket client = (Socket)ar.AsyncState;

// Complete the connection.

client.EndConnect(ar);

Console.WriteLine("Socket connected to {0}",

client.RemoteEndPoint.ToString());

// Signal that the connection has been made.

connectDone.Set();

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static void Receive(Socket client)

{

try

{

// Create the state object.

StateObject state = new StateObject();

state.workSocket = client;

// Begin receiving the data from the remote device.

client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

new AsyncCallback(ReceiveCallback), state);

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static readonly IPAddress myAddress = IPAddress.Parse("10.0.0.68");

private const int porto = 10002;

private static void ReceiveDgram(IPEndPoint EP, Socket client)

{

StateObject state = new StateObject();

state.workSocket = client;

UdpClient ascolta = new UdpClient();

//IPEndPoint localEP = new IPEndPoint(myAddress, porto);

try

{

ascolta.JoinMulticastGroup(myAddress);

ascolta.Connect(EP);

// Begin receiving the data from the remote device.

byte[] bytes = ascolta.Receive(ref EP);

Console.WriteLine("Received {0} - \n",

Encoding.ASCII.GetString(bytes, 0, bytes.Length));

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static void ReceiveCallback(IAsyncResult ar)

{

try

{

// Retrieve the state object and the client socket

// from the asynchronous state object.

StateObject state = (StateObject)ar.AsyncState;

Socket client = state.workSocket;

// Read data from the remote device.

int bytesRead = client.EndReceive(ar);

if (bytesRead > 0)

{

// There might be more data, so store the data received so far.

state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

// Get the rest of the data.

client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

new AsyncCallback(ReceiveCallback), state);

}

else

{

// All the data has arrived; put it in response.

if (state.sb.Length > 1)

{

response = state.sb.ToString();

}

// Signal that all bytes have been received.

receiveDone.Set();

}

Console.WriteLine("Received {0} - \n",

Encoding.ASCII.GetString(state.buffer, 0, state.buffer.Length));

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static void Send(Socket client, String data)

{

// Convert the string data to byte data using ASCII encoding.

byte[] byteData = Encoding.ASCII.GetBytes(data);

// Begin sending the data to the remote device.

client.BeginSend(byteData, 0, byteData.Length, 0,

new AsyncCallback(SendCallback), client);

}

private static void SendCallback(IAsyncResult ar)

{

try

{

// Retrieve the socket from the state object.

Socket client = (Socket)ar.AsyncState;

// Complete sending the data to the remote device.

int bytesSent = client.EndSend(ar);

Console.WriteLine("Sent {0} bytes to server.", bytesSent);

// Signal that all bytes have been sent.

sendDone.Set();

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

public static int Main(String[] args)

{

StartClient();

return 0;

}

}

Link al commento
Condividi su altri siti

Hai provato anche con il Socket TCP Server o Client abbinato relativamente

Ai programmi “EWEB_SOCK_TCP_CLIENT_VER2.ACD” e “EWEB_SOCK_TCP_CLIENT_VER2.ACD” ?

Invece di usare UDT ?

Magari poi quando vedi che tutto funziona, ti riconcentrerai nel tuo software per

Cercare di Ricevere i Dati da Socket UDT.

Il Programma “EWEB Socket Test Application.exe” che si trova allegato al Caso A131152816

ho visto che funziona perfettamente.

Non solo con il Modulo EWEB, ma anche tra altri Programmi che implementano un Socket,

Come HyperTerminal (WinSocket).

Perciò molto probabilmente devi cercare di costruire la tua applicazione in C# , aiutandoti con

questo programma di esempio “EWEB Socket Test Application.exe”.

Quando riuscirai a inviare o ricevere i dati da questo programma, la tua applicazione certamente

Funzionerà altrettanto bene con il Modulo 1756-EWEB.

Io per esempio ho realizzato dei piccoli programmi per testare i Socket Server o Client,

e funzionano perfettamente sia con il Modulo 1756-EWEB che con il programma

“EWEB Socket Test Application.exe”

Pultroppo non li ho realizzati in C#.

Link al commento
Condividi su altri siti

Bene sono contento, sono curioso di conoscere come hai realizzato il tutto.

Inoltre nella modalita' UDT non ho mai realizzato niente.

Grazie Mr. White

Link al commento
Condividi su altri siti

  • 2 weeks later...

Ciao ti allego la versione UDP dove la receive

è sincrona (cioè attende) mentre la send è asincrona.

Ti viene in mente qualcosa (magari un parametro da passare alle send e receive

che possa in qualche modo velocizzare il tutto. Magari anche settaggi del PC o della

scheda di rete o dei protocolli, e analogamente su PLC 1756-l62 con eweb)

Grazie

Ciao

qui il sw

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

class Program

{

static string sep = ";";

static string[] DATA_IN = new string[11];

static string[] DATA_OUT = new string[11];

static string data_in_appoggio = "";

static string data_out_appoggio = "";

static double[] DATA_IN_DOU = new double[11];

static double[] DATA_OUT_DOU = new double[11];

static double parziale1 = 0;

static double parziale2 = 0;

static double parziale3 = 0;

static double KY1 = -3.4537;

static double KY2 = 5.91;

static double KY3 = 30.25;

static double KY4 = -8.3267;

static double KFX1 = 5.0111;

static double KFX2 = 11.9144;

static double KFX3 = -28.87;

static double KFX4 = -0.03;

static double KT1 = -3.98;

static double KT2 = 10.66;

private static String response = String.Empty;

private static ManualResetEvent connectDone =

new ManualResetEvent(false);

private static ManualResetEvent sendDone =

new ManualResetEvent(false);

private static ManualResetEvent receiveDone =

new ManualResetEvent(false);

public static IPEndPoint EP_l;

public class StateObject

{

// Client socket.

public Socket workSocket = null;

// Size of receive buffer.

public const int BufferSize = 256;

// Receive buffer.

public byte[] buffer = new byte[bufferSize];

// Received data string.

public StringBuilder sb = new StringBuilder();

}

public class StateObject2

{

public UdpClient workUdpclient = null;

// Size of receive buffer.

public const int BufferSize = 8192;

// Receive buffer.

public byte[] buffer = new byte[bufferSize];

}

public static void Listener(IPEndPoint EP, UdpClient ascolta)

{

int i, indice, lungh;

StateObject2 state = new StateObject2();

state.workUdpclient = ascolta;

try

{

byte[] bytes = ascolta.Receive(ref EP);

DATA_IN[0] = Encoding.ASCII.GetString(bytes, 0, bytes.Length);

//Console.WriteLine("List. : Rec. from {0} :\n {1}\n",

// EP.ToString(), Encoding.ASCII.GetString(bytes, 0, bytes.Length));

//Console.WriteLine("Rec. from {0}", Encoding.ASCII.GetString(bytes, 0, bytes.Length));

// nel caso in cui si voglia usare il receive asincrono disattivare le due righe

// subito dopo il "try {" ed attivare la riga qui sotto

// ascolta.BeginReceive(new AsyncCallback(ReceiveCallback),state);

data_in_appoggio = DATA_IN[0];

for (i = 0; i < 10; i++)

{

lungh = data_in_appoggio.Length;

indice = data_in_appoggio.IndexOf(sep);

DATA_IN[i + 1] = data_in_appoggio.Substring(0, indice);

data_in_appoggio = data_in_appoggio.Substring(indice + 1, lungh - 1 - indice);

//Console.WriteLine("dde_in {0} {1}", i, DDE_IN[i + 1]);

if (i < 9)

DATA_IN_DOU = (double.Parse(DATA_IN[i + 1])) / 10000;

else DATA_IN_DOU = (double.Parse(DATA_IN[i + 1]));

}

parziale1 = 100 - DATA_IN_DOU[6];

parziale2 = DATA_IN_DOU[3] - 15.71;

parziale3 = DATA_IN_DOU[4] - DATA_IN_DOU[7];

DATA_OUT_DOU[0] = KFX1 * 0.88 +

KFX2 * DATA_IN_DOU[0] +

KFX3 * parziale2 * 1.95 +

KFX4 * DATA_IN_DOU[1];

DATA_OUT_DOU[1] = KY1 * parziale1 +

KY2 * DATA_IN_DOU[0] * 99.5123 +

KY3 * parziale2 +

KY4 * DATA_IN_DOU[1];

DATA_OUT_DOU[4] = KT2 * parziale3 +

KT1 * DATA_IN_DOU[5];

DATA_OUT_DOU[2] = 1 - DATA_OUT_DOU[4];

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static void ReceiveCallback(IAsyncResult ar)

{

try

{

StateObject2 state = (StateObject2)ar.AsyncState;

UdpClient client = state.workUdpclient;

byte[] bytes = client.EndReceive(ar,ref EP_l);

//Console.WriteLine("Rec. {0}", Encoding.ASCII.GetString(bytes, 0, bytes.Length));

if (bytes.Length > 0)

{

receiveDone.Set();

//Console.WriteLine("Rec. {0}", bytes.Length);

DATA_IN[0] = Encoding.ASCII.GetString(bytes, 0, bytes.Length);

}

else

{

client.BeginReceive(new AsyncCallback(ReceiveCallback), state);

}

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

private static void SendCallback(IAsyncResult ar)

{

try

{

Socket client = (Socket)ar.AsyncState;

int bytesSent = client.EndSend(ar);

sendDone.Set();

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

static void Main()

{

const int listenPort = 10001;

const int sendPort = 10002;

UdpClient ascolta1 = new UdpClient(listenPort);

IPAddress ipA_listen = IPAddress.Parse("100.100.100.101");

IPEndPoint EP_listen = new IPEndPoint(ipA_listen, listenPort);

EP_l = EP_listen;

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

IPAddress ipA_send = IPAddress.Parse("100.100.100.102");

IPEndPoint ep = new IPEndPoint(ipA_send, sendPort);

bool done = false;

byte[] sendbuf = Encoding.ASCII.GetBytes("");

StateObject state = new StateObject();

int i = 0;

while (!done)

{

//Console.Write("\ns {0} ms {1} ", DateTime.Now.Second,DateTime.Now.Millisecond);

Listener(EP_listen, ascolta1);

data_out_appoggio = "I;";

for (i = 0; i < 4; i++)

{

if (DATA_OUT_DOU < 0)

DATA_OUT = DATA_OUT_DOU.ToString("000.000");

else DATA_OUT = DATA_OUT_DOU.ToString("0000.000");

data_out_appoggio = data_out_appoggio + DATA_OUT + sep;

}

DATA_OUT[4] = DATA_IN_DOU[9].ToString("0000");

data_out_appoggio = data_out_appoggio + DATA_OUT[4] + sep + "E";

//data_out_appoggio = data_out_appoggio + "E";

sendbuf = Encoding.ASCII.GetBytes(data_out_appoggio);

//s.SendTo(sendbuf, ep);

s.BeginSendTo(sendbuf, 0, 43, 0, ep, new AsyncCallback(SendCallback), s);

}

}

}

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