macです。
<concon@xxxxxxxxxxxxxxx> wrote:
> 水平を保つための加速度センサーACB302をつんだ
> 自動車模型が磁石で黒板に張り付いており、約2mの
> ケーブルでH8/3687につながれています。
意外と難しいことなのですが、
これを最初の質問に書いておけば、
答えるほうはすごく楽です。
でも、質問する時点では「当面の壁」の、
直近から見ているので、うまく書けないのですよね。
> まず、こういう配線でよいのかな?ということと、
> モーターのpwm信号のノイズが乗っているせいなのか、
> 左に傾いても、右のモーターが動いてしまう場合があり、
> それでも全体としては、なぜか正常に動きます。
ノイズの影響と見るのが妥当でしょう。
> センサーの電源電圧が変化しないように1000μF
> のコンデンサをつけて、電源が安定するまで始動するの
> を待つようにしているのですが、始動前のセンサーの値より、
> 始動後の値のほうが、2%から2.5%大きくなるので、
> プログラム上で初期値を捏造(ねつぞう)しています。
> これもなんだか生き物を扱っているようでしっくりきません。
1000uFは明らかに過大です。
ケミコンは大きくなればなるほど、
高周波特性が悪くなり、デジタル回路から発生する、
高周波ノイズを除去しにくくなります。
+V --Coil--+---+--->Sensor
| |
=== ===
| |
+---+--GND
コンデンサは10uF + 0.1uF程度が適当です。
Coilは1mH程度でよいでしょう。
次に、H8のAD側です。
簡単なものでかまわないので、
LPF (Low Pass Filter)を入れます。
From sensor ---R--+---ADC
|
C
|
GND
Cut off freqは、
fc = 1 / (2πRC)です。
R=1kΩとして、
C=0.1uF
C=1/(2π*1e3*1e-6)
fc = 1591Hz
おまけに、AD変換を数回やって、
最大最小は捨てます。
#define N_AD 5
int GetAd(int ch)
{
int n, min, max, sum
min = 0x7fff;
max = - min;
int n = N_AD;
sum = 0;
while(n--) {
sum += (ad = adc(ch));
if (ad > max) {
max = ad;
}
if (ad < min) {
min = ad;
}
}
return((sum - max - min) / (N_AD - 2));
}
オリンピックの体操などの得点計算ですね。
サンプル数が少ないときのノイズ除去に、
ただ平均するより、かなり効きます。
できれば中央値(median)を採りたいところですが、
組み込み用だとメモリーリソースや、
並べ替えの処理の負荷が気になるし、
サンプル数が少ないときは、
「オリンピック」方式と大差ありません。
-- mac