Rising and falling edge detection

I would like to detect rising and falling edges on I/O and variables. I believe this can be achieved on digital points with GetClearOnLatch and GetClearOffLatch, but I can’t seem to find a way to do this easily with variables.
I’m from a PLC background and you can do it very easily with a PLC. The only way I can think of how to do this in a PAC is to save the value of a variable and then compare it to the current value, but that would mean I need an extra variable for every variable I wanted to detect edges and a lot of redundant code.

Hi Koganei,

Welcome to the forums! You’re correct, we have lots of “built-in” intelligence at the I/O level, including latches, counting, and totalizing, just to name a few. PACs are a bit different (like you mentioned the variables vs. I/O), and usually there are a number of options for solving a particular problem–which you choose will vary depending one where you’re coming from and headed.

Before I suggest some options for you, could you give us a 10,000 ft “bigger-picture” view of what you’re trying to do here? For example, what causes those variable(s) to change? What do you need to have happen as a result?

I’d also be interested in know if you have an HMI, and which one: [I]groov[/I]? PAC Display? (PAC Display has a number of built-in options for Alarming or logging based on various triggers, which could be helpful if that’s where you’re headed.)


I’m trying to start/stop a motor. It will have manual and auto modes and the operator can start and stop the motor as desired in manual mode. But I want the motor to stop when they first switch to manual mode. So usually, in a PLC, I would just stop the motor when I detect a rising edge of the manual mode bit.
Other examples of using rising edges are when I only want something to happen once, e.g., send a start command once when an operator presses a button regardless of how long they hold the button down for, another start command will only be sent after they release the button and press it again.

I’ll be using groov.

Hi Koganei,

Thanks for the additional info. While PLCs and our SNAP PACs have their differences, they also have a lot in common. Let’s break down the pieces of your situation here.

As you mentioned, we do have the Latch commands which work for I/O. These functions actually happen at the “brain” level, right there on the same rack as the I/O. The brain has a scanner (like a PLC), and includes a number of built-in I/O features (in addition to digital features like latching and counting, a SNAP PAC brain can also: run up to 96 PID loops, do totalizing, TPOs, etc.).

PAC Control strategies (which run on a controller) make super easy with to uses these features with the commands like GetClearOnLatch.

On the other hand, your variables exist in the PAC controller. (If you have a SNAP-PAC-R1 or -R2, then you have both a PAC controller and a brain in the same hardware.) As you mentioned in your first post, to detect an edge in that case, you would store the previous value and compare it to the current value.

This would look about as you described in your second post: “stop the motor when I detect a rising edge of the manual mode bit.” You could use just a single bit here, but PACs have loads of memory (click here for details), so better to use a whole, aptly named variable, perhaps: nManualModeFlag. OptoScript to do this might look like this:

Or the equivalent Action blocks (because anything you can do in OptoScript can be done in a flow chart with action blocks – your choice):

These would both be part of a looping chart (we always recommended adding the biggest delay reasonable in a looping chart so that particular chart doesn’t hog the CPU more than necessary). This logic could be in it’s own chart if you’d like. Some PLC users will just have one big chart that does everything in sequence before looping around.

Sometimes having just one big chart the loops around isn’t practical (depending on how big your application is now or will be in the future). Also, since you mentioned a concern about “redundant code,” you’ll likely want to take advantage of a PAC’s ability to run multiple charts at once and maybe even use a subroutine or two. More on that later…

Glad you’ll be using groov! Is that where you’ll have this “Manual Mode” button, and the “start command” button you mention? Have you built any screens yet? We’d love to see!


For the “more on that later” I promised above, here’s a quick look at how you could modify the logic shown above to work with MANY motors instead of just one, using tables.

I’ve written this logic in a way that if I wanted to change the number of motors in the future, all I’d have to do is change the size of the tables (this code or chart wouldn’t have to change):

In OptoScript, I could make use of a “for” loop:

Or if I’m not using script, I’d create an equivalent loop like this:

Using tables and loops like this is one of many ways to avoid “redundant code.”
Hope that helps!