私の質問は、おそらく一般的な能力テストまたはそのようなものに属します. 組み込みデバイスとは直接関係ありません。
無限に回転できる可変抵抗器が与えられました10Ω
。ADC は、0 ~ 1023 サンプリングの値の範囲に設定されます。これにより、光の明るさ/強度を制御する必要があります。
1024/32
ADC 値の範囲は、明るさのレベルのために 32 段階に分割されます。問題は、先端に到達するためにポットを 16 回回転させる必要があることです。これは非常に嫌がらせです。ポットのハードウェアを変更することはできませんが、ファームウェアを変更することはできません。
私は次のようにすることを考えました、ここから私を助けてください:
[0 1023] 内、たとえば 32 ステップの範囲ウィンドウを選択します。ここでは、ADC ノイズを無視します。
次に、その 32 ステップ ウィンドウに 32 ステップがあります。
0 から開始すると、強度は 32 まで増加します。32 は可能な最大強度です。さらに回転すると、強度は 1023 までずっと 32 で最大のままになるはずです。
そして、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);
}
ありがとう