我的问题可能属于一般能力测试或类似的东西。它与嵌入式设备没有直接关系。
我得到了一个可变电阻器,它可以无限旋转并且是10Ω
. ADC 的值范围设置为 0 到 1023 采样。我必须通过它来控制光的亮度/强度。
ADC 值范围分为 321024/32
级亮度级别。问题是锅必须旋转 16 次才能到达四肢。这是非常骚扰。现在是我不能改变锅硬件但固件的时候了。
我想这样做如下,请从这里帮助我:
我将在 [0 1023] 内选择一个范围窗口,例如 32 步。现在让我们忽略 ADC 噪声。
然后我们在这 32 个步骤窗口中有 32 个步骤。
如果我从 0 开始,强度将增加到 32。32 是可能的最大强度。然后如果我旋转更多,强度应该一直保持在 32 的最大值,直到 1023。
一旦它从 1023 开始降低,我的强度就会降低到 (1023-32) 并且将一直保持在 0 强度直到 0。
- 如果我从任何地方旋转回来,它应该遵循上面解释的移动窗口规则。
如何开始呢?
伪代码:
void processADC_data()
{
ushort adc0 = (ushort)ADC_DATA;
adc0_Avg = adc0;
// If Noise
/*
ushort adc0_L = (ushort)(adc0 - 40);
ushort adc0_H = (ushort)(adc0 + 40);
adc0 = (ushort)read_ADC( adc0_L,adc0_H );
adc0_Avg = adc0 * 20 + adc0_Avg * 80;
adc0_Avg /= 100;
*/
IsInceasing = (adc0_last - adc0_Avg) < 0 ;
adc0_last = adc0_Avg;
if (IsInceasing)
{
// Extrimity has to be handled
if (!HasPerformedIncreased)
{
adc0_center = (ushort)(adc0_Avg - window);
HasPerformedIncreased = true;
HasPerformedDecrease = false;
}
else if (HasPerformedIncreased)
{
IsCrossingLimit = ( (adc0_Avg - adc0_center) > window );
if(IsCrossingLimit)
{
adc0_Avg = LIGHT_SENS_MAX;
IsCrossingLimit = false;
}
else
{
adc0_Avg = (ushort)(adc0_Avg / LIGHT_SENS_MAX);
}
}
//judge_brightness(adc0_Avg);
}
else
{
// Extrimity has to be handled
if (!HasPerformedDecrease)
{
adc0_center = (ushort)(adc0_Avg + window);
HasPerformedDecrease = true;
HasPerformedIncreased = false;
}
else if (HasPerformedDecrease)
{
IsCrossingLimit = ( (adc0_center - adc0_Avg) > window );
if(IsCrossingLimit)
{
adc0_Avg = LIGHT_SENS_MIN;
IsCrossingLimit = false;
}
else
{
adc0_Avg = (ushort)(adc0_Avg / LIGHT_SENS_MAX);
}
}
}
brightness(adc0_Avg);
}
谢谢