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