“to detect if a Knob has been changed”
In Max, a param will hold an input value perfectly. E.g., 0.5 will always be 0.5 until you send a message to change it. In hardware, there is always some very small voltage fluctuations, so even if thte knob is positioned at 0.5, you will see a signal flow of something like 0.5001, 0.4995, 0.5012, 0.4989, etc. (really those numbers will have a lot more decimal places, but just to get the idea across). Since CV/knob inputs are sampled once per block, these little fluctuations will happen at whatever block rate you have – e.g. every 48 samples in your screenshot. Feeding this signal through [oopsy.ctrl.smooth3] will lowpass filter it, so you get very small, slow, but now continuously moving variation on the order of +/- 0.001. Your [change] object will pick up these fluctuations as real changes, even if they are very small, and continously output +1 and -1 accordingly.
If you want to know whether a knob was moved, you need to measure if the variation has exceeded a certain threshold; e.g. if the param value has changed by at least +/- 0.01 for example. For that, you need to know where it was since the last significant move. You can then use an [absdiff] to get the absolute difference, and if that is [> 0.01], then “knob is moving” is true. If “knob is moving” we need to update our reference value, which we can do using a [latch] (feed the smoothed signal into the left input, and the [> 0.01] to the right input). That [latch] can go back into the [absdiff] via a [history]:
And as @TheSlowGrowth says, if you want to usefully quantize the knob without having tiny fluctuations when the knob is right on the boundary between settings, you want to use hysteresis. A schmitt trigger is a common circuit for this:
Hope this helps!