[H8-ML(5277)] Re: センサーからのアナログ入力(きっと初級)
From: Shigeru Makino <mac@xxxxxxx>
Date: 2005年01月05日(水)11時14分25秒
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


スレッド概略
[5275(R)](起点)
 └[表示中]
   ├[5279(1)]
   └[5291(2)]


投稿順に移動
[←前の記事へ(P)]
[→次の記事へ(N)]


リスト表示へ
[このスレッド(T)]
[本記事の前後(L)]