Ok, what is *hysteresis*?

I feel I have to ask.

I was sort of helping someone with using it, but am not getting what it does.

Say I have the lower/upper values at 16 / 24.

If it gets an input of 2, that is way below the 16.

Say the second input is 8, which is still below 16.

Should that be sent through or blocked?

Now, if the second input was 17, what should happen? Should it be on-sent?

Just I have made a simple flow and it isn't making sense what is getting blocked and what is passing.

Take look at https://en.wikipedia.org/wiki/Hysteresis
I think the quote from that site - " Hysteresis can be a dynamic lag between an input and an output that disappears if the input is varied more slowly" pretty much sums it up.

Yeah, I went off and read all that, but it is in congruent to what I am seeing with the hysteresis node.

If you are talking about some sort of on/off control with hysteresis for noise suppression then that is not a valid description.
@Trying_to_learn in your example with limits of 16/24 then if you are talking about the type of hysteresis I think you are then if the input is rising from 2 then the output would stay the same until it gets to 24, then it would switch, if the input later falls then the output will stay the same till it gets to 16. If that doesn't explain it the give us more information on the context of the question.

It could be wrong, I am asking because someone else is using it and maybe they are wrong with their use also.

The OP's question was 'Ok, what is hysteresis ?', no mention of noise suppression in his post.
I've posted the link to & quoted part of the definition as per the wikipedia entry, is that wiki incorrect?

No probably not.

But it doesn't help the original person (not me) who is using that node to do that function.

I got caught up in it and so got curious about what I was getting out of the node when I did certain things, which to me didn't make sense.

As there is also a threshold node, maybe the two are getting confused.

But I have other things which require my attention. I just was trying to help someone and got confused.

But you did not provide a link to the the original person's thread or provide the name of the node that you are referring to (since your last post, I'm now assuming node-red-contrib-hysteresis, but hysteresis could have been introduced into a flow without a contrib node at all).

My last post here as it's not helping your question getting answered, but can you see how context is important.

I didn't want to drag them into this. But the thread is:
This is the one

It is a bit of a give away with its title.

The "you" in "if you are talking about ..." was intended to be @Trying_to_learn. Apologies for my loose use of words. My comment was not intended to say the definition there is incorrect for some use of the term hysteresis, but just to say that it probably isn't the right definition for this use case.

Assuming the node is question is node-red-contrib-hysteresis then the readme for that node gives a definition of what the node does. It isn't exactly what I would expect a hysteresis node to do but it probably does the job. Personally I would only expect it to output on change of output state.

@Trying_to_learn you said the the node's output isn't making sense, what it is doing and what would you expect? Make a mini-flow with just the hysteresis node, and tell us what you would expect.

1 Like

Alas there is the first problem.

@Dom_Nate was asking about what was going on. I stuck my nose in and started to reply.
Then @Steve-Mcl posted.

That's where the bigger picture of confusion set in.

Yes, there is a node-red-contrib-hystesis node, but there is also one in another set.
node-red-contrib-edge-trigger which also includes a hysteresis node.

The first one is poorly maintained, the second one a lot better.

So, cutting to my curiosity I wanted to play with the node and see what happens.
Understanding that there is a hysteresis node and with the understanding that there is also a threshold node that can be used.

The flow:

[{"id":"b4212ac4.d972f8","type":"random","z":"2a10ff07.234f98","name":"","low":"15","high":"25","inte":"true","property":"payload","x":210,"y":1170,"wires":[["cf807902.29ddf8","94aebf13.2f94d"]]},{"id":"f96a0bfc.f37e8","type":"inject","z":"2a10ff07.234f98","name":"foo","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":80,"y":1170,"wires":[["b4212ac4.d972f8"]]},{"id":"cf807902.29ddf8","type":"hysteresis","z":"2a10ff07.234f98","name":"","rising_threshold":"18","falling_threshold":"22","initial_edge":"any","x":400,"y":1170,"wires":[["686091ce.31cbf8"]]},{"id":"94aebf13.2f94d","type":"debug","z":"2a10ff07.234f98","name":"Random","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":200,"y":1130,"wires":[]},{"id":"686091ce.31cbf8","type":"debug","z":"2a10ff07.234f98","name":"Output  ************","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":580,"y":1170,"wires":[]},{"id":"d6c2287d.71b5d8","type":"inject","z":"2a10ff07.234f98","name":"","topic":"Upper Threshold","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":1030,"wires":[["cf807902.29ddf8"]]},{"id":"6895b86a.6ca8d","type":"inject","z":"2a10ff07.234f98","name":"","topic":"Lower Threshold","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":1070,"wires":[["cf807902.29ddf8"]]},{"id":"1d954b62.b5da45","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"17","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1250,"wires":[["cf807902.29ddf8"]]},{"id":"9a66d04a.d5f598","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"18","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1290,"wires":[["cf807902.29ddf8"]]},{"id":"f533bb99.e755a","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"19","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1330,"wires":[["cf807902.29ddf8"]]},{"id":"486b5dda.5637f4","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"20","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1370,"wires":[["cf807902.29ddf8"]]},{"id":"38173ab.97e34c6","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"21","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1410,"wires":[["cf807902.29ddf8"]]},{"id":"c519a2f1.5d8808","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"22","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1450,"wires":[["cf807902.29ddf8"]]},{"id":"1e3f63b5.b7746c","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"23","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1490,"wires":[["cf807902.29ddf8"]]},{"id":"da65dfa6.beffb","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"30","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1530,"wires":[["cf807902.29ddf8"]]},{"id":"94b989eb.2a7ca8","type":"inject","z":"2a10ff07.234f98","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1210,"wires":[["cf807902.29ddf8"]]}]

This is using the node which comes in: node-red-contrib-edge-trigger.

The random part wasn't really working but I put it in at the start hoping for something I shouldn't.

given 18 and 24 are the two values:

If I inject: 17, 17, 1 I get only one 17 coming out.

Ok, That is below the 18 value. Why are they all filtered? (Rhetorical at this point)

Then I inject 19, 19, 19 and only get one 19.

That value is between the 18 and 24, so maybe they should be blocked.

But! Considering how I read the definition, the results are in congruent.

Ok, so my take is that you have two values - an upper and lower - and if you get values which are below the lower, you get the inputs reflected on the output.

When the input is between the lower and upper, no output is seen.

OR it could be read as:

If the values are below the lower limit, only the first one is passed to the output.

If the values are between the lower and upper, all inputs are reflected on the output.

The node does neither.

I don't know which of the two above assertions is correct - if either.

Continuing on from what I did with the inject node/s on the flow I posted, I then injected:
23, 23, 30. nothing came out.

Then I injected 21 and got 21 at the output.

Nah, something is wrong, and I accept I don't understand.

I can read until the cows come home. It is not matching what I am seeing.

I slightly modified the flow

Only for appearance.

Here is an example of what I see, so there is no arguing:

The description of the node (https://www.npmjs.com/package/node-red-contrib-edge-trigger) includes pictures showing how it should behave. Do you believe that it does not behave as shown in the pictures?

Well, I have to admit I am too stupid to understand it.

I have looked at what they call the definition and how it works.

What I make of it and what I am seeing confuse me.

Going back to the old definition I learned in digital electronics many years ago, you can think of it as a way to stop small variations in an input from causing lots of changes in an output.

When a signal/value/parameter is increasing, the output doesn't change until the value passes a threshold. At this point, the input can vary up or down a bit without changing the output, but if it goes down below a lower threshold, then the output changes to the opposite state.

This way a noisy input is changed to a nice set of steady outputs.

Without hysteresis, and a single threshold, an input which varies around the threshold value will cause lots of changes in output.

Ok, building on what @molesworth said:

So I have the values set at 18 and 22.

If the changes are between 18 and 22 they are not passed through. Or: the are blocked/filtered.



1 gets through. It is outside the 18 - 22 range.

  1. BLOCKED. No. It is outside the range. It should get through.
  2. I get. It is inside the range.

But why is 17 blocked / not sent to the output?

So which way round have you set the limits. 22 should be the rising limit and 18 the falling one.

1 Like


I had them the wrong way around!

I had

Screenshot from 2020-07-23 08-29-47

But, indulge me:

Given that, why was the 17 blocked?

I put the numbers in the node the other way around.

Tried again:

Screenshot from 2020-07-23 08-32-20

So why is only the first 1 being passed?

After a few more hundred head collisions with the wall.....

So the rising limit is (now) set to 22 and the falling to 18.

Given there has been no input as yet.

1 is received.

It is below the rising limit - 22

It is passed.

Next is 17. It is still below 22 so is blocked.
Likewise with the next bunch as I showed.

So they are blocked.

Once it gets above 22 it will be sent.

Then, if the next is also above 18 it will be blocked.

So what happens between 18 and 22 that is different?

I think I am starting to get it though.

Almost. The difference is from which direction the limits are hit. Going up it has to be above 22 to "fire"/send the message, then next it has to go below 18 before it will fire again. That 4 degrees is the hysteresis gap.
If you had a simple if >= 20 then if your sensor wobbled around 19.9, 20, 19.9 it would keep sending values. Hysteresis can remove that over sensitivity.

1 Like

I guess the most common use for Hysteresis in modern home automation systems is in climate control.
Say you have a temperature sensor that you’re polling every 5 or 10 seconds, and you’ve set your target temperature at 22°
If it’s below 22° then you turn the heating on, if it’s above then you turn it off.
The problem is that when the temperature is 21.9° the heating will kick on, but at 22.1° it will go off again. This means that the heating will constantly be turning on and off, trying to maintain exactly 22.0°. That’s general not good for your heating equipment, or the relays that are being used to turn it on and off.
So, what you want is a bit of hysteresis to reduce the sensitivity a little. There are a number of ways to do it, but you might choose to turn the heating on at 21.5° and off at 22.5° ( assuming still that your target temperature is 22.0°). That gives you +/- half a degree of latitude and depending on your heating setup and how quickly it boosts the temperature after turning on, it may give the correct balance between comfort and operational considerations.

I use a similar system to control an inverter aircon unit which provides heating to our holiday home in winter. I tend to find that it’s more comfortable if you don’t let the temperature drop too far below the target, but not an issue if it goes quite a bit above. As a result I have a hysteresis formula which puts the heating on at 0.2° below target and off at 0.4° above target - which works well.