Vesp123 Posted February 20, 2021 Report Posted February 20, 2021 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?
MVP 2023 Joe Tauser Posted February 21, 2021 MVP 2023 Report Posted February 21, 2021 I tried putting a Positive in a function used in a UDFB and it worked. Can you give a more specific example? Joe T.
Vesp123 Posted February 21, 2021 Author Report Posted February 21, 2021 This is what I meant by not being able to put a Positive Transition Contact: 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?
ORSO2001 Posted February 21, 2021 Report Posted February 21, 2021 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.
ORSO2001 Posted February 21, 2021 Report Posted February 21, 2021 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.
Vesp123 Posted February 22, 2021 Author Report Posted February 22, 2021 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.
Swervomotor Posted February 22, 2021 Report Posted February 22, 2021 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 1
ORSO2001 Posted February 22, 2021 Report Posted February 22, 2021 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 1
Vesp123 Posted February 23, 2021 Author Report Posted February 23, 2021 Thank you guys for your ideas - you have both been very helpful!
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