1

Quick Summary:

I'm looking for an algorithm to display a four-digit speed signal in such a way that the minimum number of (decimal) digits are changed each time the display is updated.

For example:

Filtered
 Signal      Display
--------------------
  0000        0000
  2345        2000
  2345        2300
  2345        2340
  0190        0340
  0190        0190
  0190        0190

Details:

I'm working on a project in which I need to display a speed signal (between 0 and 3000 RPM) on a four-digit LCD display. The ideal display solution would be an analog gauge, but I'm stuck with the digital display. The display will be read by a machine operator, and I would like it to be as pleasant to read as possible.

The operator doesn't really care about the exact value of the signal. He will want to know what the value is (to the nearest 10 RPM), and he will want to see it go up and down in response to changes in the operation of the machine. He will not want to see it jumping all over the place.

Here is what I have done so far:

  • Round the number to the nearest 10 RPM so that the last digit always reads 0
  • Filter the signal so that electrical noise and normal sensor fluctuations don't cause the reading to jump around more than 10 RPM at a time.
  • Added a +/-10 RPM hysteresis to the signal to avoid the cases where it would wobble over the same value (for example: 990 - 1000)

This has cleaned things up nicely when the signal is steady (about 75% of the time), but I still see a lot of unnecessary variation in the signal when it is moving from one steady state to another. As the signal changes from 100 RPM to 1000 RPM (for example), it passes through a lot of numbers along the way. Since it takes a moment to actually read and comprehend the number, there seems to be little point in hitting all of those intermediate states. I tried simply reducing the update rate of the display, but that did not produce satisfactory results. It made the display "feel" sluggish and jumpy, all at the same time. There would be a noticeable delay before the numbers would change, and then they would move in big leaps (100, 340, 620, 980, 1000).


Proposal:

I would like the display to behave as shown in the example:

  1. The display is updated twice per second
  2. A transition from one steady state to another should not take longer than 2 seconds.
  3. If the input signal is higher than the currently displayed value, the displayed signal should increase, but it should never go higher than the input signal value.
  4. If the input signal is lower than the currently displayed value, the displayed signal should decrease, but it should never go lower than the input signal value.
  5. The minimum number of digits should be changed per update (preferably only one digit)
  6. Higher-order digits should be changed first, so that the difference between the display signal and the input signal is reduced as quickly as possible

Can you come up with, or do you know of an algorithm which will output the "proper" 4-digit decimal number according to the above rules?

The function prototype, in pseudo-code, would look something like this:

int GetDisplayValue(int currentDisplayValue, int inputSignal)
{
    //..
}

Sorry for the wall of text. I wanted to document my progress to date so that anyone answering the question would avoid covering ground that I've already been through.

e.James
  • 116,942
  • 41
  • 177
  • 214
  • I think you made a typo in the penultimate display number? According to your algorithm it should be 0140 (one digit at a time). – VVS May 14 '09 at 15:47
  • No, that was intentional. I don't want the display number to drop below the input value. (Point #4.) The idea is that the display will only show values between the currently displayed value and the current input value. – e.James May 14 '09 at 16:55

4 Answers4

1

If you do not need the data expressed by the 4th digit, and are strictly bound to a 4 digit display, have you considered using the 4th digit as an increase/decrease indicator? Flash some portion of the top or bottom of the zero at 2Hz* to indicate that the next change of the gauge will be an increase or decrease.

I think you could also do well to make a good model of the response of your device, whatever it is, to adjustments, and use that model to extrapolate the target number based on the first half second of the two second stabilization process.

*this assumes that you have the two updates per second you posited. Most 4 digit displays are multiplexed, so you could probably flash it at a much higher frequency with a little driver tweaking.

Sparr
  • 7,489
  • 31
  • 48
0

I think your proposal to change one digit at a time is strange, because it actually provides the user with misinformation... what I would consider would be actually to add much MORE state changes, and implement it so that whenever the signal changes, they gauge moves towards the new value in increments of one. This would provide an analog-gauge like experience and "animation" of the change; the operator would very soon recognize subconsciously that digits rotating in sequence 0,1,2... denote increasing speed and 9,8,7,... decreasing speed.

E.g.:

Filtered signal      Display
0000                 0000
2345                 0001
                     0002
                     ...
                     2345

Hysteresis, which you have implemented, is of course very good for the stable state.

Antti Huima
  • 25,136
  • 3
  • 52
  • 71
  • I like your creative thinking, but I'm not sure I agree with your reasoning. In your example, it would take almost 40 seconds for the display to count from 0000 to 2345, assuming a 60 Hz refresh rate, which is (approximately) the highest frequency that the human eye can process. – e.James May 13 '09 at 21:46
0

This is a delicate question, and my answer does not cover the algorithmic aspect.

I believe that the behaviour that you represent in the table at the beginning of your posting is a very bad idea. Lines 2 and 5 display data points that are and never were in the data, i.e. wrong data, for the sake of user experience. This could be a poor choice in the domain of machine operation.

A lower update rate may "feel sluggish" but is well defined (only "real" data and at most n milliseconds old). A faster update rate will display many intermediate values, but the most significant digits shouldn't change to quickly. Both are easier to test than any pretty false value generation.

Christoph
  • 1,927
  • 15
  • 14
0

This will incorporate more or less slowly the sensor value into the displayed value:

display = ( K * sensor + (256 - K) * display ) >> 8

Choose K between 0 (display never updated) and 256 (display always equal to sensor).

Eric Bainville
  • 9,738
  • 1
  • 25
  • 27