Aller au contenu principal

BASIC IDE Delay Logic

Commentaires

25 commentaires

  • Tim Beaulieu

    You should just be able to put all of the TSETs in the top of your section. I'd avoid putting them in a goto function unless you want to change the value of a TSET.

    0
  • PJ_IOT

    @Tim_hms

    Yes, I actually changed that yesterday after I created the post and I took the TSET out of the routine and put it above after finding another post you mention using the same TSET for multiple and separate ONTIMER; however, the result was when the ONTIMER was used in the conditional routine per the ONCHANGE of the tag, it made the tag start logging ever 5 seconds indefinitely rather than giving me the 5 second delay and having it only run once for LOGIO.

    I found the Advanced data transfer schedule from last year where Jordan helped me and gave me a function type solution to emulate a delay which I marked as the solution but I was only after the DMSync command in that case and never used the function.

    I guess I need a solution where if conditional logic goes to a routine or a function, etc. then I need a way to tell it to delay for X seconds and then run the logic beneath.

    I read over the programming guide and all and read how the code is executed\queued but it's not 100% clear to me if I use a function as per that post from Jordan and then call it and pass in the parameter for the number of seconds to delay, if that will delay all execution of everything else or just whatever is in the conditional logic or whatever I need it to delay on.

    Essentially when there is a specific tag that ON, then I need to set the deadband logging to a negative value so it does not log when the value changes if it were set to 1 but I need it to wait 5 seconds before that change occurs without affecting the other logic from other stuff programmed in the BASIC IDE interface of the Flexy 205 device.

    Is there not a sleep() or timeout() function or something like that I could use or so I need to use a custom function as per that one Jordan mentioned from that post, and if I am to use that one, will it affect the execution of other code while it counts or whatever?

     

     

    0
  • Tim Beaulieu

    Hi PJ,

    Was this the code that you were looking at earlier?

    https://hms-networks-s3.s3.dualstack.us-east-1.amazonaws.com/original/2X/d/d77c8af2b891fbc0f8ba9384b69aa1c00ecbdc94.txt

    I think I should be able to make some kind of delay for your project using this. Can you try and implement it and if you run into issues, I can help you take a look at it on teamviewer?

    Please select the below download button to download HMS Teamviewer QuickSupport. https://s3.amazonaws.com/hms-networks-s3/original/1X/HMS_QS.exe

    Thanks,
    Tim

     

     

     

     

    0
  • PJ_IOT

    @Tim_hms

    This might work for the need but I cannot test right now as they are running production from the eWON I need to use it.

    I will test as soon as I can when they are not running and see if it works. I'll circle back around to the post but this seems like it should do what I need but i'll test and analyze with more thorough detail as soon as I can.

    Thanks!!

     

    0
  • Tim Beaulieu

    Sounds good to me, let me know if you run into issues

    0
  • PJ_IOT

    @Tim_hms

    I came up with some logic that I think will suffice but I'll need to see if it actually works to turn off the deadband logging on the 3 second delay as expected though.

    I believe the Init Section logic needs to be in this specific order to work as I need it but it's still not clear to me how the eWON execution will work if ONCHANGE for the HOPPER1_SETPOINT_MET tag senses a change and during its 3 second delay (like second #1) the HOPPER2_SETPOINT_MET2 tag has a change how exactly does that work.

    If I have a need for 3 second delay logic for more than 4 tags and if using separate TSET will be a requirement for such a solution as described above, then the TSET limitation of 1-4 quickly becomes an issue.

    I turned this logic on last night and even though the plant didn't run today, there were some 1 bits set on the HOPPER2_LIVEWEIGHT tag (nor 0 values) and the deadband for the tag was set to 1 rather than -9 so I changed that back and see what happens when they actually run tomorrow.

    Perhaps there's a more dynamic way to write a BASIC function to complete this sort of task.

    Init Section

    TSET 3, 0      // -- Initialize Timer
    ONCHANGE "HOPPER1_SETPOINT_MET", "GOTO Hopper1_SetPointMet"
    ONTIMER 3, "@timeroff()" // -- Disable Timer
    ONCHANGE "HOPPER2_SETPOINT_MET", "GOTO Hopper2_SetPointMet"
    ONTIMER 3, "@timeroff()"
    END
    
    Hopper2_SetPointMet:
    IF(HOPPER2_SETPOINT_MET@ < 1) THEN
      LOGIO "HOPPER2_LIVEWEIGHT"
      SETSYS TAG, "load","HOPPER2_LIVEWEIGHT"  // -- Load Tag
      SETSYS TAG, "LogEnabled", 1              // -- Enable historical logging
      SETSYS TAG, "LogDB", 1                   // -- Enable deadband logging
      SETSYS TAG, "save" 
      LOGIO "HOPPER2_LIVEWEIGHT"
    ELSE
      LOGIO "HOPPER2_LIVEWEIGHT"
      @delay()
      ONTIMER 3, "@Hopper2DBandOff()"
      LOGIO "HOPPER2_LIVEWEIGHT"
    ENDIF
    END
    
    FUNCTION Hopper2DBandOff()
      //Run logic here that starts after the x second delay
      LOGIO "HOPPER2_LIVEWEIGHT"
      SETSYS TAG, "load","HOPPER2_LIVEWEIGHT"  // -- Load Tag
      SETSYS TAG, "LogEnabled", 1              // -- Enable historical logging
      SETSYS TAG, "LogDB", -9                  // -- Disable deadband logging
      SETSYS TAG, "save"
      LOGIO "HOPPER2_LIVEWEIGHT"
      @timeroff()
    ENDFN
    END
    
    FUNCTION delay()
      TSET 3, 3 // -- Initialize timer with a 3 second delay
    ENDFN
    END
    
    FUNCTION timeroff()
      TSET 3, 0  // -- Disable Timer
    ENDFN
    END

     

     

    0
  • Tim Beaulieu

    I think that this might help you if you need multiple delays for a tag. It's only using one Tset and is just using an additional tag as a counter to create the delays.

    multidelay example.txt (552 Bytes)

    0
  • Tim Beaulieu

    Hi PJ,

    Just wanted to see if that code helped?

    0
  • PJ_IOT
     
    Tim_hms:

    delay example.txt

    @Tim_hms -

    I apologize for the delay as this plant just started back up a couple hours ago from planned downtime for a few days which I wasn't aware of when I originally asked the question but I have data now and can provide some feedback.

    I can confirm that the first script example you provided named "Delay example.txt " did indeed give us what we needed to control the logic to basically make it turn deadband to 1 when a specific tag goes OFF and then once that same specific tag goes ON to then log that tag for 3 or so more seconds before changing deadband back to a negative value to turn off logging but not disable it because once an hour we also LOGIO tag values so when we visualize the data, I get an hourly point always regardless.

    We need to record specific tag data when a weight setpoint is met and record that for a few more seconds afterwards too. We get sporadic weights recorded/noise such as 299, 300,301, 300, 299, 301, etc. fluctuation incrementally increasing by one after the weight setpoint is met.

    NOTE: Stopping that noise at the sensor/tag level does not seem to be an option in this particular case as I've already asked about the root level solution.

    Keeping the [required] deadband to 1 for that tag's value logs way too much data and we are bringing it into MySQL tables so this gives us another way to not have to work with or store unnecessary data at the eWON level between the PLC and the MySQL in addition to the other eWON services playing the middle man we use.

    I'm not sure what the problem was when I checked the other day after I initially implemented it but everything seems to work as expected with the script as I posted in my above response labeled BASIC IDE Logic.

    I still think the multidelay example.txt is good logic that I could use later potentially if needed as I scale it for business needs, but for now I'll leave as-is since it's giving me the expected result so far.

    I appreciate the good help as usual; support here has always been great for us!!

     

     

    0
  • Tim Beaulieu

    Hi PJ,

    Is there a number I can call you at to go over that specific tag weight setpoint and see if we can find a solution? I just want to try and get a little more info on what you're trying to do with it first.

    Thanks,
    -Tim

    0
  • PJ_IOT

    Hey Tim -

    The solution you provided which I tested worked as expected. I honestly won't know if I'll need to extend it or scale it further until they get the other hopper up and running and we start getting data from it.

    This is for a new plant and Hopper2 is the only one running right now. I'm happy to open a new post and link/reference back to this one on it if I find there are issues if Hopper2 and Hopper1 setpoints are met at the same time.

    My flexibility is less available at the moment for Mon. - Fri. 8-5 EDT so unless we can talked after (or before) those hours, I'll only be able to use this forum, email, etc.

    If I use the logic I provided right above your response with the attachment related to the multidelay example if Hopper1 and Hopper2 setpoints are met at the same time, will there be a conflict?

    With that same logic I used in that post right above the response you provided with the multidelay example using only Hopper1 and Hopper2 only and no other hoppers, could you write me a snippet from the multidelay example and incorporate some of that other logic I used into it to give me a rough idea how I should structure the flow, etc.?

    Even if it's not perfect and you get me in the right direction, that'll be good for me if you think the way I have it now (from that post) I will have trouble when 2 setpoints are met at the same time.

    0
  • Tim Beaulieu

    I think this might be a good starting point

    0
  • Tim Beaulieu

    example for pj.txt (1.6 KB)

    0
  • PJ_IOT

    Wow, I didn't think about or know it was possible for ONCHANGE to be used with a variable like that. Everything makes sense with the counter variable and the conditional and nested if statements too checking that value.

    I am a little confused how it knows 1 is for hopper1 and 2 is for hopper2 with the way it's written but I'll need to test it more to know for sure but they need to start running the additional hopper I suppose first before I can do that.

    If I have two triggers then I need to use something for each of those to be triggered, right?

    ONCHANGE "Intialize1", "@delay()"
    ONCHANGE "Intialize2", "@delay()"
    

    It will be possible for Initialize1 to have 2 or 3 changes in a row and Initialize2 to not have any during that time. It seems like this logic expects the delay_count@ variable value of 1 to always be one ONCHANGE intialize and 2 to be another ONCHANGE initialize.

    In any case, I don't do much BASIC script so you will know better than me on this but I will get it tested and confirmed. In the meantime, I'm fine with this being the solution since it makes sense to me other than my lack of understanding the precise flow of logic with init and when functions are called, etc. with this language.

    Feel free to update or include anything further if what additional detail I added here justifies any modifications of the logic you provided to accommodate for the tags' inconsistent changing pattern and needs.

    I appreciate your time and effort helping me with this Tim!!

    0
  • Tim Beaulieu

    Hi PJ,

    the Initialize that I created was to just turn the counter on. The way I wrote it was basically so that it's calling a tag on the Flexy called Initialize and when it sees that value change it would cause the counter to start. We could also do an if statement inside of the delay with something like this:

    FUNCTION delay()
    If Initialize@ = 1 Then
    TSET 3, 3 // " Initialize timer with a 3 second delay
    Print "Timer Started"
    Endif
    Else
    ENDFN

    If you want it to be time dependent you could do something like this:

    Function Check()
    current_time$ = TIME$ // grabs the current time
    time_str$ = current_time$(12 To 13) //grabs the current hour
    time_check% = Val time_str$ // converts from a string to an int
    Print time_check%

    if time_check% > 8 AND time_check% < 17 Then
    print "Can Initialize"
    else
    print "Can't Initialize"
    endif
    Endfn

    We can then merge these to something like this:

    Function Check()
    current_time$ = TIME$ // grabs the current time
    time_str$ = current_time$(12 To 13) //grabs the current hour
    time_check% = Val time_str$ // converts from a string to an int
    Print time_check%

    If time_check% > 8 AND time_check% < 17 AND Initialize@ > 0 AND Initialize@ < 5 Then
    Print "Can Initialize, Timer Started"
    TSET 3, 3 // " Initialize timer with a 3 second delay
    Else
    Print "Can't Initialize"
    TSET 3, // " Doesn't allow initialization
    Endif
    Endfn

    0
  • PJ_IOT

    To maybe clarify more just to be sure I'm explaining it so you understand with more clarity just in case since I'm new to BASIC logic, I wanted to mention two main points below itemized in case it helps or justifies modifications to your snippet example:

    1. There is no "standard" as for the order which Hopper# may come on first or if they'll be using both at the same time, or just one or the other only, or one only one for 5 minutes then both for x minutes, and then only the other, and so forth for any combination or variation as such with respect to order or timing.

    2. It needs to be dynamic enough to handle each Hopper# having its own "Trigger" for ONCHANGE too.

    0
  • Tim Beaulieu

    You could either have 4 different initializes that cause the code to run, or you could have it so the initialize triggers on 4 different values

    0
  • PJ_IOT

    Here's a visual to see what I'm trying to do to keep data collection points efficiently since data is retained and you can imagine having hundreds of tags of data points for every change 24x7x365.

    This is a zoomed in view without data all data points show for how it's typically viewed since it's drillable

    Here's a view I wanted to show where I unhid all the data points for an entire day where we are only catching the data when the hopper starts filling.

    I'll scale the eWON BASIC logic accordingly for all applications where this method of efficient data collection is applicable.

    0
  • Tim Beaulieu

    Can we set up a time for you to call me to go over more of this if you're still running into issues with the code above?

    Thanks,
    -Tim

    0
  • PJ_IOT

    Can I have each ONCHANGE pass a function a variable of either 1, 2, 3, or 4 so I can use conditional logic to check that value for whichever hopper triggers the function call to start the timer, etc.

    So if Hopper1 ONCHANGE call Func(1), :, Hopper4 ONCHANGE call Func(4) and then in the conditional logic of that function it will take action accordingly?

    To me this would be perfect in the "example for pj.txt" you provided to use for the delay_count@ variable where in that example it is incrementally going up by 1 per the ~= delay_count@+1 portion. In that example it seems whenever that multidelay() is called by any trigger it will just add one to the current variable. I think something like this but each ONCHANGE or specific tags passing the function an argument int and then check that.

    I also like the logic idea about basing it off time but I think I need to have be able to set time1, :, time4 as separate variables per each hopper and then be able to have conditional logic take action for each if time greater than +3 seconds of that time or whatever otherwise loop and keep checking until that's true (no more than 3 secs tho for example).

    I'm not sure I'll be available to work on this during normal hours anytime soon at the moment and tied up from 8 AM - 5 PM.

    Is phone support ever available on the weekends or after 5 PM on the weekdays? In the meantime, I'm fine with this forum as nothing is urgent or broken.

    I look forward to testing out some of this logic you provide and get something working for the need.

    0
  • Tim Beaulieu

    Hi PJ,

    Can you send me something like a block diagram showing what you're trying to do?

    0
  • PJ_IOT

    I don't have a diagram but I'll see if I get time if I can make something but essentially we have two hoppers, two receivers, and two transporters. Each hopper has a fill valve that once it [opens] starts filling we start the data collection with a deadband of 1 until that same fill valve closes (plus 3 seconds after).

    The fill valve is a BOOL data type but that's is what ONCHANGE needs to monitor for each hopper to "trigger" the conditional logic to set the deadband accordingly based on the fill valves opening and closing.

    I only need to get the weight values from the "other" things (receiver, hopper, transporter) when the hopper file valve is opened and then 3 seconds after it closes. Each hopper (for example hopper1) has it's own set of "other" things that are not shared with the other hopper (e.g. hopper2).

    If hopper1 fill valve opens, I need to then collect the weight value by setting deadband to one for receiver1, transporter1, and hopper1 [weight] until hopper1 fill valve closes after 3 additional seconds. So hopper1 has it's own set of "other" things that's not shared with hopper2 and hopper2 will have it's own set of "other" things.

    Essentially I want to control the eWON to say, when this Hopper boolean tag goes X then turn deadband on for these three "other" tags until this same tag changes again but to X then wait an additional 3 seconds, and then turn deadband for these "other" tags to a negative value so data is not logged to the historical file for those tags.

    So if I have two hoppers and two fill valves and think of it as if each hopper is not even related to the other at the plant level but each hopper has its own set of separate "other" tags that are correlate to the respective hopper only.

    I need to only have Hopper1 and Hopper2 fill valves share the same logic or function to make each wait 3 seconds when the respective hopper fill valve closes to turn off logging for the respective "other" things without hogging up a bunch of TSET's since I use those for other logic too.

    Maybe what you provided already will work for this scenario but if I can figure out a way to make a diagram or something I will"I won't be able to share any diagrams from the actual plant though but I suppose I could draw up a generic sketch or something if i get some time.

    0
  • Tim Beaulieu

    Ok thanks, I was just thinking something along the lines of like a block diagram where it would say something like Trigger 1 -> if time is X -> hopper 1, -> wait 3 seconds - Do X. I'd check if the code above works first but if it's running into issues, it will be easier to debug with a block diagram I think

    0
  • PJ_IOT
    Tim_hms:

    wait 3 seconds

    Can you tell me "in general" during the "wait 3 seconds" per the above you wrote latest about, will during that wait time before it does the "Do X" will other running logic in the init still take action from taking action or is it executing the 3 second wait and not executing other logic during that time such as another ONCHANGE trigger?

    With other programming code I'm able to emulate these sort of scenarios but I've never really been able to do that with the eWONs unless the PLC programmer is right there sending the tags data, etc. while I'm testing the BASIC code.

    I could answer this question myself if I had a way to safely emulate changing tag data which the eWON collects. I think understanding this will help me understand what the best approach is I need to take on the 3 second delay logic.

     

     

    0
  • Tim Beaulieu

    So in the code that I provided, it is based off of an ontimer. This means that it will execute the code each time that ontimer is reached. In this case it will be triggering on a counter that will count up every 3 seconds. So that means that once the timer hits 3 seconds and the counter increments, it will do the code that is specified in the onchange section. Or in this case since it's based on some if statements, it will begin as soon as the counter changes to the specified number. To test it you could just try and have the ewon write to another internal tag if you want to make sure that the delay is working

    0

Vous devez vous connecter pour laisser un commentaire.