【问题标题】:How to check if value is between two floats? [closed]如何检查值是否在两个浮点数之间? [关闭]
【发布时间】:2020-03-16 19:08:44
【问题描述】:

我正在编写一个程序,该程序从热敏电阻获取温度,然后需要确定它所处的温度范围,然后打开特定颜色的 LED。我遇到的问题是,当温度下降到一定范围内时,不止一个灯会亮起,而我只想要 RGB LED 的 3 个灯中的一个。

现在,我检查温度值的 if 语句是:

if (-40.0 < tempValue && tempValue < 20.5)
{
    //turn blue light on
}

else if (20.5 < tempValue && tempValue < 37.3)
{
    //turn green light on
}

等... 其中 tempValue 是从热敏电阻获得的温度。

在阅读了一堆关于浮点数并比较它们/相等性陈述的帖子后,我知道这样做肯定存在“常规”比较方式的问题,但我不确定如何根据具有最大值和最小值的给定范围。

【问题讨论】:

  • 请注意,如果温度等于 20.5,则两个灯都不亮。请注意,20.5 可以精确表示,-40.0 也可以,但 37.3 不能精确表示。
  • 您的代码几乎没有任何问题,只是您可能想用&lt;= 替换20.5 比较之一。此外,您可能需要添加一些滞后,因为在 20.5 附近时您会变得疯狂闪烁。
  • 在打开新灯之前,您是否需要关闭任何已经打开的灯?或者,至少,如果新灯不同,请将其关闭;如果没有变化,请不要关闭再打开,以免闪烁。
  • 比较似乎很好,因为你使用 else if 因此只有 1 个分支应该执行。也许问题是没有滞后,所以当温度接近 25 时,你可能会读到 24.99... 然后 25.001.. 然后再读 24.99.. 一些东西,如果程序足够快,那么两个 LED 都会闪烁。所以它可能是由噪音引起的。
  • 我敢说浮点比温度测量设备的精度更高,所以只要你不触发相等事件,温度读数是37.3还是可能无关紧要37.29999999.

标签: c floating-point comparison temperature


【解决方案1】:

如何根据给定范围内的最大值和最小值检查温度(?)

我只想要 RGB LED 的 3 个中的一个。

鉴于 N 种颜色中只有一种是所需的结果,并且范围显然是相邻的,我建议使用边界列表而不是最小/最大对。这很容易确保只选择一种颜色,并防止“打开多个灯”。

那么边界在 -40.0, 20.5, 37.3

#include <math.h>

int TemperatureToColor(double tempValue) { 
  const double Temperature Limit[] = {-40.0, 20.5, 37.3, HUGE_VAL};
  size_t n = sizeof Limit/sizeof Limit[0];
  // Assume if less than -40.0, use red.  
  // Assume if more than 37.3, also use red.  
  const int color[n] = {RED, BLUE, GREEN, RED};
  for (size_t i = 0; i<n; i++) {
    if (tempValue <= Limit[i]) {
      return color[i];
    }
  }
  return BLACK;  // tempValue is not-a-number, or maybe RED in this odd case
}

细节:可以对边界情况进行一些调整。

【讨论】:

  • 这与 OP 的问题无关。这只是安排代码的一种不同方式,而不是对他们的测试进行根本性的改变(除了更正&lt;= 而不是&lt;),并且没有回答计算中累积的舍入误差如何影响它们。 (虽然 OP 报告“不止一个灯亮”,但从显示的else if 代码中这是不可能的,因此还有其他一些问题。)
【解决方案2】:

应该是唯一一个亮着的,但是所有的灯都亮着,所以它看起来是白色的(带有一点蓝色

造成这种情况的一个常见因素是噪音。 LED 的 RGB 灯开启时间可以在启用后持续。在温度读数不稳定的情况下,当接近过渡点时,绿色/蓝色会快速连续打开/关闭。即使只启用了一个灯,它在视觉上也会显示为多个灯亮着。人眼的持久性也增加了这一点。

解决方案包括:

  • 将采样率降低到 1.0 赫兹以限制 LED 变化率。

  • 为颜色选择添加滞后。一旦选择了一种颜色,温度的变化必须比颜色变化考虑的颜色范围多 1.0 度。

  • 低通滤波器:不使用原始温度读数,而是使用最后 M 个样本的运行平均值

  • 上述组合:一旦颜色发生变化,它会保持该颜色至少一段时间(例如 1.0 秒),除非温度变化极端(例如 5 度超出范围)。在该最短时间之后,照常行事。

我预计关于 RED 的问题是由于未发布的代码错误造成的。

【讨论】:

  • 因此,出于某种非常奇怪的原因,我不得不关闭 LED - 之后 - 我写信给我的 LCD,但我不明白。现在,唯一的问题是在检查温度的周期之间(5 秒 LED/LCD 开启,然后它再次启动循环)有一个小的白色 b/c 闪烁,所有灯都因某种原因被打开。当温度在循环期间/循环之间发生变化时,没有闪烁,它只是直接从蓝色变为绿色,没有闪烁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-03-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2012-05-27
相关资源
最近更新 更多