Jump to content

How do I do it in Unilogic?


Vesp123

Recommended Posts

Hey all,

 

I am looking for your suggestions/ideas in regard to writing a below described program.
Lets say I need to control lighting(many lamps) in 20 rooms. Each room has the same, very advanced funcionalities.  How do I write a program avoiding creating 20 exact multi-lines subroutines with different variables in each subroutine? Copying and pasting would take me perhaps 2 days, but maintaining it would be horrible, because when I make small change I need to make it in every subroutine every time! Is there a better approach?

I thought that I could use UDFBs while passing as "Function In" a proper variables related to each room, but it seems like UDFB does not allow using Positive contacts. This way UDFBs are useless to me.

What am I missing guys? How should I do it in Unilogic?

Link to comment
Share on other sites

This is what I meant by not being able to put a Positive Transition Contact:
ACtC-3dDTuws_2gll-uetDPOcVh0aUN1dDB1VrNw
ACtC-3eO0VY_Co_KaiKQu_heZAn5mcXTrtoFOyFG
U can only put a direct contact. If 'var1' tag would be placed on HMI as monostable button it would be impossible to perform operation that needs single trigger e.g : incrementation, toggling. 

Meanwhile, I came up with a different approach that omit using UDFB:
I will create 20 subroutines, however each of them will be separated to 3 regions.

subroutine1:
Region 1 - copy struct1 to structX
Region2 -  program based on variablesX
Region3 - copy structX to struct1

subroutine2:
Region 1 - copy struct2 to structX
Region2 -  program based on variablesX
Region3 - copy structX to struct2

...

This way I do not have to put variables of each room to every basic element(every contacts and so on). Whenever I need to change something in program, I copy Region2  to every subroutine and change structs if needed.

There is one flaw in this idea, I cant copy e.g Timer1 to TimerX,  Timer2 to TimerX ... because it will not work, so in Region2 of each subroutine I need to put correct timer variable(Timer2). I cannot leave TimerX. Anyway, its better than changing all the basic elements.

Do you have any other ideas?

Link to comment
Share on other sites

hi Vesp123,

if I well remember the "local tag" can't be |P| or |N|...because these are create and destroyed every cycle..then they can't remember the previously state...then...I have many projects that has to manage many devices in the same way but with different timming...then, usually, I create a struct that contain all the information about the specific device and I pass this struct at the UDFB...then I know if the specific device was "busy" or "free" or "running" or other else every new cycle.

 

Link to comment
Share on other sites

i forgot to write that if you need a multiple timer you can use the "millis" control...instead of a TON or TOFF or other timers.

then in your struct you will have an "startMillis" variable that will be updated when wil be needed...and with this you can check the timing of your actions.

Link to comment
Share on other sites

Thanks for your answear @ORSO2001. 
Not having a possibility to use positive contacts is a shame :/ I can omit it by creating a global tag and putting into a UDFB however this idea does not work when I do more than 1 call to UDFB with different input variables.

I am not sure if I understand correctly what you mean by "milis" control. Does it mean creating a variable e.g. "timer12" in a struct and control a timer that would be in another subrutine?
Thats a way to go! Also another variable eg. "timer12_out" would be needed. This way I can have only one version of subroutine that could be copied freely without hasitation to other soubroutines(I am talking about my idea from previous post). If needed, I would create/delete a timer in struct and in separate subroutine with timers. At least in theory, I need to check it out yet.
 

Link to comment
Share on other sites

You build your UDFB to contain all your room arguments

Then you pass it which room/device  you want it to handle and  trigger the UDFB with rising P in your global or main program. Using a conditional statement like equal, only the desired sections of the UDFB runs. 

In the picture "LoadActuator" is my UDFB and the top 2 rungs are inside the UDFB.

The bottom is a call showing how I pass it A) SelectedPostion (pointName)and B)Actuator Number.

-Swervo

example.png

  • Like 1
Link to comment
Share on other sites

hi Vesp123

what I meant is that the unistream share a system variable called  "General.Milliseconds Counter" that is an UINT32 variable that start to count the milliseconds from the PLC power ON.

so you can save, when you want, its value to check how much time is gone...like a timer...obviously, or better I think that is obviously, this procedure need a "finite state machine" logic...so some other variable/s in your struct  will define which steps are you performing for each single struct...attached an example about what i meant.

MILLIS.ulpr

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...