Jump to content

Recommended Posts

Posted

Hi,

I am working on .net application that listens on Ethernet from three PLCs witch are connected via switch to PC. I am using .net driver from the Unitronics web site (I used Listener Example solution).

Application should write incoming data in SQL database. I listen on port = 20256, I am getting data from one PLC successfully when one PLC is connected on the switch, but when I connect another one then I can't read from the other and also OnDisconnect event fires.

So:

- How to solve problem when more PLCs try to connect my application, and how to read from all of them at the same time?

- How to solve concurrent access in Database ?

In attachment are two .vlp files from the two PLCs.

Here is a part of the code:

private void ButtonListenOnPort_Click(object sender, EventArgs e)

{

EthernetListener listener = PLCFactory.GetChannel(LocalPort) ?? new EthernetListener(LocalPort, 3, 3000);

listener.OnListenerConnectionAccepted += OnConnect;

listener.OnListenerConnectionClosed += OnDisconnect;

PLCFactory.GetPLC(listener);

}

private void OnConnect(PLC plcfromlistener)

{

_plc = plcfromlistener;

var rw = new ReadWriteRequest[1];

rw[0] = new ReadOperands

{

OperandType = OperandTypes.MI,

NumberOfOperands = 9,

StartAddress = 0

};

try

{

_plc.ReadWrite(ref rw, AsyncReply);

}

catch

{

MessageBox.Show("bla bla");

}

}

private void AsyncReply(IAsyncResult ar)

{

var async = (AsyncResult)ar;

var del = (ReadWriteOperandsDelegate)async.AsyncDelegate;

var rw = new ReadWriteRequest[0];

try

{

del.EndInvoke(ref rw, ar);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

return;

}

var values = (object[])(rw[0].ResponseValues);

MethodInvoker mi = delegate

{

var success= new ClassSuccess();

success.Successful = 1;

StoreInClassSuccess(success);

};

UpdateUI(mi);

}

// store in database

public bool StoreInClassSuccess(ClassSuccess entry)

{

try

{

using (var context = new DBEntities())

{

context.ClassSuccess .Add(entry);

context.SaveChanges();

}

}

catch (Exception ex)

{

throw ex;

}

return true;

}

netv570.vlp

netv570n.vlp

  • MVP 2014
Posted

I suspect you will need to set up 3 different listening ports, 1 for each PLC.

The use of Connect and Disconnect functions implies you are using TCP.

I understand the general principles, but don't have a deep understanding of the .net code.

Even if I am wrong, setting up the 3 ports may be a valuable debugging step. I hope this helps.

Posted

Hi, the EthernetListener is meant (and designed) for having a 1 client (meaning, only 1 PLC can be connected to the same port).

This was done in order to support 1 client programs like SD Card Explorer etc.

We do have a multi connection listener for the kind of applications you want, and it is called ListenerServer.

About concurrent access in Database... Well, it depends on which database you are using. Microsoft SQL Express support multiple connections and multiple threads, but don't expect concurrency when reading things.

(Please note that if 2 threads are trying to update the same Database row, you cannot know what the result would be).

In order to simplifies things, it might be a good idea to use lock on the function that sends data to the Database, (This will result a lower performance since several threads might be waiting for each other).

Other options are invoking the "Add to DB" action on the same thread for all PLCs (hence, you are avoiding code races).

I'm not sure in which rate you are reading data from the PLC and writing it to DB, but with SQL Express you can use Stored Procedures and TVPs. In this way, you can send a DataTable (.Net data table, not a Unitronics one) to the SQL that contains several rows that you need to update or insert.

This way, a some part of your code can collect all data from the 3 PLCs (again, you need to make sure you are thread safe) and send it every 1 second (For example). By that, you reduce the number of calls to the Database.

(You can create a stored procedure that accepts a TVP and uses Merge... If exists update, else insert. This is very fast).

Please see the attached example for using Listener Server. I hope it will help you.

Listener Server Example.zip

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

This site uses cookies. By clicking I accept, you agree to their use.