AngryRobot

Anyone have much experience creating IAGs?

9 posts in this topic

I am trying to create an IAG to store and display some alarm messages for a servo drive.  I wanted to do it in an IAG in order to make it easily reusable; but so far I'm not having much luck getting it to work.

I created an input variable that will have the error number stored as an INT or Short; then I added a VB sub to run through a CASE statement in order to write the messages.  I've tried writting them to a String variable that I would display with a data display, but that didn't work.  So then I tried just writing the string directly to the object parameter (ie: Label0.Text), and that doesn't seem to be working either.

Could it be that the sub isn't getting triggered?

Share this post


Link to post
Share on other sites

Yeah, it seems I wasn't calling my sub like I thought I was.  I am now able to get it to run the sub; the sub just isn't doing what I want.  So now I've got some sort of issue interfacing the input variable to the VB code.

Share this post


Link to post
Share on other sites

So part of the problem is my familiarity with ST versus VB.

 

I didn't think about the subs only running once when called.  So that is where most of my problem is.  I'm only running the sub once when I load the page, and never again to change the value of the label when the variable changes.

 

I have six servos on this machine, so six different IAGs or pages to display the faults and other info.  What is a good way to continuously call a sub, without sticking it in the global events table and calling all six all the time, even if the page the sub is on isn't being called?

Share this post


Link to post
Share on other sites

You can do it. But this require some bit of .NET coding experience. Anyway, I'll just put up an example for you.
This code below will continuously increment a variable value by one every 1000 milliseconds. You can change that function to any statement you want.
This code utilizes the fact that NA uses Windows Operating System which supports Multi-Threading. But how powerful the CPU is able to do that is up to the test. But I believe that doing Select Case statement is not consuming memory that much.

'Code behind Page - Add local subroutines for the page.    
Dim TestThread As System.Threading.Thread

'You call this Sub to start the looping. For example, call it on a "PageDisplayed" event or any other event you need
Sub InfiniteStart()
    'Instantiate the Thread Object if it is not defined. This will reference the Thread to it's Callback Sub defined below
    If TestThread Is Nothing Then
        TestThread = New System.Threading.Thread(AddressOf LoopThread)
    End If

    Try
        TestThread.Start()
    Catch
    End Try
End Sub    

'You call this Sub to stop the looping. For example, call it on a "PageHidden" event or any other event you need
Sub InfiniteStop
    Try
        TestThread.Abort()
    Catch
    End Try
End Sub

'Callback for the separate Thread
Sub LoopThread    
    'Loop forever
    While True
        'Increment variable, or do anything you want to
        MyVal += 1    
        'Sleep the Thread for 1000 ms. No matter how small the value, you still need a Sleep in a looping Thread
        'If not, the GUI will got hanged (user cannot interact with the buttons, screens, etc.)

        System.Threading.Thread.Sleep(1000)    
    End While
End Sub

Share this post


Link to post
Share on other sites

Someone here at work suggest multi-threading as well, and they were also worried about the performance affect it might have on the HMI.

 

This will be going into an IAG object, so it isn't very easy to call subs from page displayed/hidden events.  Right now I set a BOOL variable when the page is displayed, and that is passed into the IAG and used as a conditional expression to call the sub, and then I reset the variable when the page is hidden.  So I think, using  your example, I could  create another variable that would be set when the page is hidden, and reset when the page is displayed, and then use that to call the end loop.

Share this post


Link to post
Share on other sites

Well... NA runs under an Intel CPU, so I guess having this much of multi-threading shouldn't be much of a problem. But it is still an issue to be thought.

Share this post


Link to post
Share on other sites

I think I came up with more crude solution, that I'm not as worried about zapping the HMI performance with.

I created a variable in the HMI called CLOCK that maps to the 100ms clock pulse in the PLC.  Then inside of the IAG I set the expression that calls the sub to (Run AND Clock).  So now it only calls the Sub when the page is displayed, and the clock pulses.

Edited by AngryRobot

Share this post


Link to post
Share on other sites

That's a good idea and, arguably, easier to reproduce.
The only downside is that PLC needs to be connected to the HMI in order for this background refresh to work... But then again what use is the HMI without a PLC intact :D

Share this post


Link to post
Share on other sites

For the purpose of object animation, I created a Subroutine in "Global Subroutines" that simply toggles a NA internal bit variable.

In "Gobal Events" I've created an event that cycles (Interval) every 200 milliseconds to run the bit toggle subroutine.

I then use this NA internal bit to change a number of image visibility states to give the impression of fans turning, or pump pistons moving.

Share this post


Link to post
Share on other sites

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