Author Topic: Hysteresis in float value for temperature display  (Read 1369 times)

0 Members and 1 Guest are viewing this topic.

Offline Vindhyachal.taknikiTopic starter

  • Frequent Contributor
  • **
  • Posts: 487
Hysteresis in float value for temperature display
« on: April 28, 2021, 03:18:02 pm »
1. I am measuring temperature of PT100 whose value is calculated in float inside the code, but on display only integer value is displayed. Now what happens is when 31.9 or 32.0,  display fluctuates between 31 & 32 very rapidly. 

2. I tried used round off from maths library, but again display fluctuates at 34.5 and 34.4. display keep fluctuates at 34 & 35.

3. how to add some hysteresis to this float value so that:
a) temperature keep on showing 31 if temperature goes from 31 to 31.9
b) at 32.0, it shows 32 only
c) but when now temperature falls to 31.9, it don't fall back to 31 on display, but keep it showing 32 until temperature falls below 31.5 ?
d) is there any math function for it in library?

 

Offline Martian Tech

  • Regular Contributor
  • *
  • Posts: 90
  • Country: us
Re: Hysteresis in float value for temperature display
« Reply #1 on: April 28, 2021, 03:22:22 pm »
You might consider using a moving average.
https://en.wikipedia.org/wiki/Moving_average
 
The following users thanked this post: mindcrime

Offline Syntax Error

  • Frequent Contributor
  • **
  • Posts: 584
  • Country: gb
Re: Hysteresis in float value for temperature display
« Reply #2 on: April 28, 2021, 03:48:38 pm »
I am not sure if this the solution to your problem, but as a firmware developer it is worth knowing about anyway.

For C and C++ there is the GSL, or GNU Scientific Library. This lib contains a whole zoo of functions for calculating everything from running statistics to fast fourier transforms, and a lots lots more.

https://www.gnu.org/software/gsl/

GSL is ported to Cygwin, so it should work with even the Arduino IDE.

Running statistics library: https://www.gnu.org/software/gsl/doc/html/rstat.html
« Last Edit: April 28, 2021, 03:52:36 pm by Syntax Error »
 
The following users thanked this post: mindcrime

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3719
  • Country: us
Re: Hysteresis in float value for temperature display
« Reply #3 on: April 28, 2021, 04:17:38 pm »
The easiest solution is to lower the display update rate.  If your application doesn't actually demand sub-second response times (very few temperature displays do!)  then don't update that quickly.  It's generally no big deal if something that flickers between 24.9 and 25.0 every few seconds.

It's definitely possible to add some hysteresis around the 0-9 rollover of the last digit if you want, but probably smoothing your data and reducing the update rate will solve your problem.
 

Offline atmfjstc

  • Regular Contributor
  • *
  • Posts: 121
  • Country: ro
Re: Hysteresis in float value for temperature display
« Reply #4 on: April 28, 2021, 04:52:31 pm »
A moving average will not necessarily be effective - you're just moving the problem from the original data potentially hovering around 31.99-32.00 to the average itself hovering around 31.99-32.00 etc. Same if you quantize/round the result.

I would try a simple hysteresis algorithm like this (pseudocode):


// Initialization

last_display_value = 0
last_compare = 0
streak = 0

// Somewhere in the main loop, for each sample:

value = get_incoming_data_sample()

current_compare = (value > last_display_value)    // 1 if true, 0 if not

if (current_compare == last_compare) {
    streak++
    if (streak >= 5) {    // or whatever other value, by trial and error
        update_display(value)
        last_displayed_value = value
    }
} else {
    streak = 1
    last_compare = current_compare    // streak broken :(
}
 

Offline BeBuLamar

  • Super Contributor
  • ***
  • Posts: 1200
  • Country: us
Re: Hysteresis in float value for temperature display
« Reply #5 on: April 28, 2021, 05:33:54 pm »
I vote for slower the update rate as temperature can't change very fast any way.
 
The following users thanked this post: mindcrime

Online Zero999

  • Super Contributor
  • ***
  • Posts: 19523
  • Country: gb
  • 0999
Re: Hysteresis in float value for temperature display
« Reply #6 on: April 28, 2021, 07:27:21 pm »
1. I am measuring temperature of PT100 whose value is calculated in float inside the code, but on display only integer value is displayed. Now what happens is when 31.9 or 32.0,  display fluctuates between 31 & 32 very rapidly. 

2. I tried used round off from maths library, but again display fluctuates at 34.5 and 34.4. display keep fluctuates at 34 & 35.

3. how to add some hysteresis to this float value so that:
a) temperature keep on showing 31 if temperature goes from 31 to 31.9
b) at 32.0, it shows 32 only
c) but when now temperature falls to 31.9, it don't fall back to 31 on display, but keep it showing 32 until temperature falls below 31.5 ?
d) is there any math function for it in library?
If your display shows 32 31, when the input is 31.9, then the rounding is broken. How are you converting the floating point to an integer? It sound like you're simply truncating, rather than properly rounding the result.
« Last Edit: April 28, 2021, 09:07:42 pm by Zero999 »
 

Offline BeBuLamar

  • Super Contributor
  • ***
  • Posts: 1200
  • Country: us
Re: Hysteresis in float value for temperature display
« Reply #7 on: April 28, 2021, 08:00:50 pm »

If your display shows 32, when the input is 31.9, then the rounding is broken. How are you converting the floating point to an integer? It sound like you're simply truncating, rather than properly rounding the result.

it's rounding correctly 31.9 should be rounded off to 32. Truncating would be 31.
 

Offline Manul

  • Super Contributor
  • ***
  • Posts: 1109
  • Country: lt
Re: Hysteresis in float value for temperature display
« Reply #8 on: April 28, 2021, 08:07:50 pm »
To add hysteresis is not hard, usually it is done symetrically around 0.5, so for example the rounding point is 0.6 when going up, and 0.4 when going down.

Code: [Select]
double Temperature;  //input
int IntValue; //last rounded value, needs to be preserved, for example, declared as global, or static local variable

if (IntValue <= floor(Temperature)) {
    IntValue = round(Temperature - 0.1);
} else {
    IntValue = round(Temperature + 0.1);
}
 
The following users thanked this post: Galaxyrise

Online Zero999

  • Super Contributor
  • ***
  • Posts: 19523
  • Country: gb
  • 0999
Re: Hysteresis in float value for temperature display
« Reply #9 on: April 28, 2021, 09:07:08 pm »

If your display shows 32, when the input is 31.9, then the rounding is broken. How are you converting the floating point to an integer? It sound like you're simply truncating, rather than properly rounding the result.
it's rounding correctly 31.9 should be rounded off to 32. Truncating would be 31.
Yes, you're right. That's what he said. I'll edit it.

To add hysteresis is not hard, usually it is done symetrically around 0.5, so for example the rounding point is 0.6 when going up, and 0.4 when going down.

Code: [Select]
double Temperature;  //input
int IntValue; //last rounded value, needs to be preserved, for example, declared as global, or static local variable

if (IntValue <= floor(Temperature)) {
    IntValue = round(Temperature - 0.1);
} else {
    IntValue = round(Temperature + 0.1);
}
Yes, that's really the correct way to round, if the value is changing.
« Last Edit: April 28, 2021, 09:09:04 pm by Zero999 »
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 16615
  • Country: us
  • DavidH
Re: Hysteresis in float value for temperature display
« Reply #10 on: April 29, 2021, 09:54:00 pm »
Hysteresis is the way to go and should be applied to rotary encoders as well.  I wish they would include it for PC fan controls.
 

Offline wizard69

  • Super Contributor
  • ***
  • Posts: 1184
  • Country: us
Re: Hysteresis in float value for temperature display
« Reply #11 on: April 30, 2021, 01:55:51 am »
It depends upon what you want to achieve here.   For example the use of a slower update rate will reduce the flicker.   Many commercial temperature display units will implement a sampling system that might give your an averaged reading of every ten or so samples.   That is the meter update rate is not the sample rate.

The bigger question is why is this a problem and why display only the integer value.   If the fractional part was displayed, whomever is reading the display would know immediately that the readings are on the edge.

Others have already discussed rounding methods that would reduce this some but from my perspective it just changes the point where you have a transition.   You would just move your problem to 31.5 or similar half way point.   It really comes down to how stable you want that reading to be and what the real problem is here but I suspect that some sort of filtering (possibly averaging or a running average) is needed.   So is it a question of flickering at all or flickering back and forth to close to 32?

By the way I'm not sure why the Math library you are using didn't give you the results you wanted.   Most seem to round at 0.5.
 

Offline Manul

  • Super Contributor
  • ***
  • Posts: 1109
  • Country: lt
Re: Hysteresis in float value for temperature display
« Reply #12 on: April 30, 2021, 02:37:47 pm »
It is all about signal and noise and the problem is either real or aesthetical.

If a slow signal comes to logic gate, there will be digital flicker on the output, which might mess up the otherwise correctly working circuits (real problem). In some cases it might also start oscillating. The standard solution is schmitt trigger inputs (with hysteresis), so the rising edge and falling edge thresholds are not the same. Logic gate is like 1 bit ADC. And the principle is same, does not matter how much bits there are. At least the LSB bit will flicker if signal is randomly crossing the threshold of that bit. Some amount of noise is fundamental part of nature, so this is unavoidable.

If analog signal is periodically digitized, there will be bit flicker which is not correlated to the change of a true signal. Bit reduction or rounding does not remove that, because bit flicker will unavoidably propagate to higher bits at some threshold points. Slow sampling or long averaging does remove flicker in a sense that the true signal is expected to change during that time, so it masks the flicker. But it might not be an optimal, preferred solution. Even if the problem is purely aesthetical, like outputting the data to the screen, LED bar graph, things like that. Personally I do not like transition flicker. The solution is to measure the noise and apply just enough hysteresis to cancel it. Too much hysteresis is of course destroying signal information, so it is important to not overdo. The same hysteresis idea like in the example algo I posted above can be used to round to float, not just integer.
 

Offline RJSV

  • Super Contributor
  • ***
  • Posts: 2121
  • Country: us
Re: Hysteresis in float value for temperature display
« Reply #13 on: May 09, 2021, 10:52:44 pm »
Manul gave a good reply: You want to use a hysterisis value just big enough, like 0.2 degrees, that example would use 29.6 degrees, crossed by a rising (set of readings), as your RISING EDGE event.
Then, also, use 29.4 degrees as your threshold, in the case of a FALLING EDGE event. You won't need to keep track of which direction of reading, is being tracked: Just compare for > (greater than) XX.6 to find out if should round up. Plus, you also check for the second case: Any reading XX.4 or lower will signify you should round off downward.
??? Did I re-state the info given by Manul clearly ?

  I recall an older WIND SPEED computer, had featured a simple LOW PASS Filter, as a higher resolution 'improvement' was exhibiting the very same value flickers. Sorry I don't have a LP filter code example, but I believe the firmware performed a type of 'averaging' where older values had less 'weight'.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf