A_Mia Posted August 9, 2012 Report Share Posted August 9, 2012 Good morning, I'm reviewing the .net verision of the Com Drive, I've got an applicaiton that requires serial communication between the PC and the PLC occur on a seperate thread from the UI due to performance concerns. Has anyone done this successfuly and would you be willing to share the .net class code? Thanks a million, any help would get me out of a pickel. Aaron Link to comment Share on other sites More sharing options...
Saragani Posted August 11, 2012 Report Share Posted August 11, 2012 The .Net driver has the ReadWrite functions with an overload that works with IAsyncResult. In my opinion, it is not easy to work with microsoft IAsyncResult because it requires splitting your code into 2. The .Net driver does do the communication on another thread, but it is blocking the calling thread up until it got a reply or the timeout and retires passed. I will help you with your request when I'm back to work. For that, I need to know if you are working with WinForms or WPF. Link to comment Share on other sites More sharing options...
Saragani Posted August 12, 2012 Report Share Posted August 12, 2012 Ok, I understand that it is a WinForms program. I saw on your email that you are using VB.Net I don't know which version of .Net you are using There are some differrences between VB.Net and C#, mostly in syntax, but C# 3.5 supports something called Anonymous Method which VB.Net doesn't (I think that in .Net 4.0 VB.Net also capable of this feature). If you can switch to C#, it would be better for both of us. I've attached a small example that shows how to read and write files from SD Card using the communication driver and doing in on a differernt thread (If it was on the UI thread, then after 5 seconds, the program would become "Not Responding"). As for the questions you've asked in your email: Question 1 – Can I setup a multithreaded application with the PLC via the serial port , i.e a separate read and a second write thread Will I generate any collisions as a result of that? Answer: You can setup a seperate thread for read and a seperate thread for write, but it would be useless. The Communication driver works Syncronously with the PLC, meaning: it can't do read and write at the same time... In fact, it is not just read and write... it can't handle 2 communications at the same time. This is why the Communication driver has a queue that collects your requests and does it one by one. So.. there won't be any collisions, and several threads will only reduce the performance. Question 2- Would you be able to provide me with a Class of sample code illustrating a multithread situation? Yes.. I've provided one... I will also explain a little more. Ok, lets start talking about UI and multithreaded applications. Here are some pseudo code: Button Click: Disable some of the UI depending on what you want to do (For example, when you click on "Read File From SD" you don't want to be able to Delete, or write some other files, so you disable those buttons. You create a thread (Or a Task, if you are using .Net 4.0) that invokes the following code: 1) Reads data from PLC (lets assume it take 5 seconds to accomplish this action).. Since we are not doing it in the UI thread, so it is not "not responding" 2) Now we want to update the UI... we create a delegate and call the UI.Invoke with that delegate (for example, this.Invoke if the code is now running in the Form) 3) We perform Data writing to the PLC 4) Update the UI again (for example percentage), again using this.Invoke 5) Now update the UI again in order to enable buttons/UI that we have disabled at the begining, using the this.Invoke If I know in what .Net framework you are working, then I can be more specific in my code. SD Card Explorer Lite - Example.zip Link to comment Share on other sites More sharing options...
Saragani Posted August 12, 2012 Report Share Posted August 12, 2012 Here is a code example that shows how to work with 2 threads (using .Net 4.0 Task in VB.Net): Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Button1.Enabled = False Label1.Text = "Starting Long work" ProgressBar1.Value = 0 Dim action As Action action = Sub() Dim uiAction As Action Dim index As Integer For index = 0 To 100 ' Do some work that takes time Threading.Thread.Sleep(1000) ' Update the UI with the results uiAction = Sub() Label1.Text = "Working... " & index & "%" ProgressBar1.Value = index End Sub updateUI(uiAction) Next uiAction = Sub() Button1.Enabled = True Label1.Text = "Done" ProgressBar1.Value = 100 End Sub updateUI(uiAction) End Sub System.Threading.Tasks.Task.Factory.StartNew(action) End Sub Private Sub updateUI(action As Action) If (Me.InvokeRequired) Then Me.Invoke(action) Else Call action() End If End Sub End Class Link to comment Share on other sites More sharing options...
A_Mia Posted August 15, 2012 Author Report Share Posted August 15, 2012 Thank you for the reply. The application is a winforms proejct written in VB on the .net 4 Framework, using the .net version of the untronics Driver The reason this is an issue is I need to monitor PLC inputs such as an E-Stop for example, by the PC interface every .5 sec. This continual monitor loop is causing a massive impact on the UI performance as you can well imagine. First thought is to create a read only dataset or datatable for each PLC datatype, for example (ReadInputs, ReadOutputs, ReadMI, ReadMB, etc.) on a background worker thread that's dedicated to monitoring the PLC and exectue a update every .5 sec. Using the rowchanged event on the main IU thread against these tables to get the state of the PLC I/O MI/MB, etc. This would prevent the main UI thread from needless looping through the PLC inputs to see what's changed. If this is feasible could there be a second set of tables, for example WriteInput, WriteMI, WriteMB, etc, that would receive the changes from the UI thread and again using the row changed event to write these values back to the PLC as a "Batch", possibly bundling the read with the write events every .5 seconds to send back to the PLC. I realize there may be slight latency issues with the serial port. Am I making this more complicated that it needs to be? Thank you again for you guidence and patience! Link to comment Share on other sites More sharing options...
Saragani Posted August 19, 2012 Report Share Posted August 19, 2012 No, it looks OK. I don't know how many Operands are you reading, but note that if you read too much, then the time it takes to read them all could exceed 0.5 seconds. Also, you don't need to send several requests to the PLC (1 for reading inputs, one of reading outputs, one for MIs, one of MBs etc)... You can create use 1 ReadWrite call and give it an array of ReadWriteRequest that contains all the reads (you can also give it write requests). The communication driver would joins and split them to several requests of needed (if the sent or the received data exeeds the rt/tx buffer of the plc). Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now