以 10 为基数的数字显示算法 - 每次刷新的最小变化

发布于 2024-07-19 14:01:21 字数 1608 浏览 7 评论 0原文

快速摘要:

我正在寻找一种算法来显示四位速度信号,以便每次更新显示时都会更改最小位数(十进制)。

例如:

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

详细信息:

我正在开发一个项目,需要在四位 LCD 显示屏上显示速度信号(0 到 3000 RPM 之间)。 理想的显示解决方案是模拟仪表,但我坚持使用数字显示器。 显示屏将由机器操作员读取,我希望它尽可能读起来愉快。

操作员并不真正关心信号的确切值。 他想知道该值是多少(精确到 10 RPM),并且希望看到该值随机器运行变化而上下变化。 他希望看到它到处乱跳。

这是我到目前为止所做的:

  • 将数字四舍五入到最接近的 10 RPM,以便最后一位数字始终为 0
  • 过滤信号,以便电噪声和正常传感器波动不会导致读数一次跳动超过 10 RPM。
  • 向信号添加了 +/-10 RPM 迟滞,以避免信号在相同值上摆动的情况(例如:990 - 1000)

当信号稳定时(大约 75% 的时间),这可以很好地清理问题,但是当信号从一种稳定状态转变为另一种稳定状态时,我仍然看到信号中有很多不必要的变化。 例如,当信号从 100 RPM 变为 1000 RPM 时,它会沿途经过很多数字。 由于实际阅读和理解这个数字需要一些时间,因此达到所有这些中间状态似乎没有什么意义。 我尝试简单地降低显示器的更新速率,但这并没有产生令人满意的结果。 它使显示屏同时“感觉”缓慢和不稳定。 在数字发生变化之前会有明显的延迟,然后它们会大幅跃进(100、340、620、980、1000)。


建议:

我希望显示的行为如示例所示:

  1. 显示每秒更新两次
  2. 从一种稳定状态转换到另一种稳定状态的时间不应超过 2 秒。
  3. 如果输入信号高于当前显示值,则显示信号应增加,但绝不应高于输入信号值。
  4. 如果输入信号低于当前显示值,则显示信号应减小,但绝不应低于输入信号值。
  5. 每次更新应更改最少位数(最好只更改一位数字)
  6. 应先更改高位数字,以便尽快减小显示信号与输入信号之间的差异

你能想出,或者你知道一种算法,可以根据上述规则输出“正确的”4位十进制数吗?

伪代码中的函数原型看起来会是这样像这样:

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

对不起文字墙。 我想记录我迄今为止的进展,以便任何回答这个问题的人都可以避免覆盖我已经经历过的内容。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

猫卆 2024-07-26 14:01:21

如果你不需要第4位数字表示的数据,并且严格绑定在4位显示上,你是否考虑过使用第4位数字作为增/减指示符? 以 2Hz* 的频率闪烁零顶部或底部的某些部分,以指示仪表的下一次变化将是增加或减少。

我认为您也可以很好地为您的设备(无论是什么)的调整响应建立一个良好的模型,并使用该模型根据两秒稳定过程的前半秒来推断目标数字。

*这假设您每秒有两次更新。 大多数 4 位显示器都是多路复用的,因此您可以通过稍微调整驱动程序以更高的频率闪烁它。

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.

要走干脆点 2024-07-26 14:01:21

我认为您一次更改一位数字的建议很奇怪,因为它实际上为用户提供了错误信息...我会考虑实际上添加更多的状态更改,并实现它,以便每当信号发生变化时,他们仪表以 1 为增量向新值移动。 这将提供类似模拟仪表的体验和变化的“动画”; 操作员很快就会下意识地认识到,按顺序旋转的数字 0、1、2... 表示速度增加,而 9、8、7... 表示速度减小。

例如:

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

您所实施的迟滞当然对于稳定状态非常有好处。

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.

各空 2024-07-26 14:01:21

这是一个微妙的问题,我的回答不涉及算法方面。

我认为您在发帖开头的表格中表示的行为是一个非常糟糕的主意。 为了用户体验,第2行和第5行显示了数据中存在和从未存在过的数据点,即错误数据。 在机器操作领域这可能是一个糟糕的选择。

较低的更新速率可能“感觉缓慢”,但定义明确(仅“真实”数据且最多 n 毫秒)。 较快的更新速率将显示许多中间值,但最高有效数字不应更改得太快。 两者都比任何相当错误的值生成更容易测试。

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.

我最亲爱的 2024-07-26 14:01:21

这将或多或少地缓慢地将传感器值合并到显示值中:

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

在 0(显示从未更新)和 256(显示始终等于传感器)之间选择 K。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文