移動平均と云う言葉の意味が良く解りませんが、自己流に解釈します。(またかよ)
前回までで dsPICの[X]リングメモリに ADCからのデータを順次書き込みました。
そして其の中の1番古いデータと1番新しいデータを読み出し、適当に?加算してエコー装置だと・・・
実際に音声等を通して聴くと、確かにエコーっぽくなるので其れほど間違ってはないと思います。
そして其の中の1番古いデータと1番新しいデータを読み出し、適当に?加算してエコー装置だと・・・
実際に音声等を通して聴くと、確かにエコーっぽくなるので其れほど間違ってはないと思います。
そこで今回はリングメモリ内のデータを2個等とケチな事は云わず全て読み出してみます。
時間的余裕はサンプリング周波数の逆数になるので頑張らねばなりません。
時間的余裕はサンプリング周波数の逆数になるので頑張らねばなりません。
当然、新しいデータが1個入って来ると、古いデータが1個消えます。
リングメモリ内のデータの数は常に一定(満杯)ですが、個々のデータは1個づつ消える方向に移動します。
「移動平均」の移動とは此れを指しているのかな?と・・・勝手な解釈ですが。
そして平均ですから、常にリングメモリ内の全てのデータを加算して、その数で割ります。
でもそんな事して何か御利益が有りますかね~。
リングメモリ内のデータの数は常に一定(満杯)ですが、個々のデータは1個づつ消える方向に移動します。
「移動平均」の移動とは此れを指しているのかな?と・・・勝手な解釈ですが。
そして平均ですから、常にリングメモリ内の全てのデータを加算して、その数で割ります。
でもそんな事して何か御利益が有りますかね~。
連続して入ってくる信号の中に、時折スムーズな変化ではなく、飛び抜けた値を持つ信号が有る場合は有効な気がします。
急激な変化は他の多数のデータにより平均化されるので、ある種の LPFになるのかと・・・
良く解らない爺さんが屁理屈をコネてても先へ進みませんから、実際にプログラムを組んでみましょう。
又、前回と同じ漫画を・・・
急激な変化は他の多数のデータにより平均化されるので、ある種の LPFになるのかと・・・
良く解らない爺さんが屁理屈をコネてても先へ進みませんから、実際にプログラムを組んでみましょう。
又、前回と同じ漫画を・・・
今0814に新しいデータが入ったとして、リングメモリ内には古い順に下記のデータが詰っています。
816--818--81a--81c--81e--820--822--810--812--814
[W8]
[W8]
これを順次、加算していくプログラムを下に・・・(サブルーチンぐらい使えよ)
asm("mov 0x0300,W0");
asm("mov W0,[W8++]");
asm("mov [W8++],W0");・・・まず最初にW8(816)のデータをW0にコピーして、其の後[W8++]
asm("mov [W8++],W1");・・・W8(818)になったデータをW1にコピーして、其の後[W8++]
asm("add W0,W1,W0");・・・W0にW1を加算してW0にコピー
asm("mov [W8++],W1");・・・W8(81a)になったデータをW1にコピーして、其の後[W8++]
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(81c)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(81e)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(820)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(822)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(810)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(812)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(814)
asm("add W0,W1,W0");
asm("mov W0,[W8++]");
asm("mov [W8++],W0");・・・まず最初にW8(816)のデータをW0にコピーして、其の後[W8++]
asm("mov [W8++],W1");・・・W8(818)になったデータをW1にコピーして、其の後[W8++]
asm("add W0,W1,W0");・・・W0にW1を加算してW0にコピー
asm("mov [W8++],W1");・・・W8(81a)になったデータをW1にコピーして、其の後[W8++]
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(81c)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(81e)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(820)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(822)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(810)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(812)
asm("add W0,W1,W0");
asm("mov [W8++],W1");・・・W8(814)
asm("add W0,W1,W0");
これで具体的な W8の値が判らずともリングメモリ内のデータが全て加算されました。
ここで大事なことは全ての演算が終わった後、W8値が、最初にデータが入った値より必ず1個前に進んでいる事。
常にADCからの新データは、旧データを書き換えていきます。
ここで大事なことは全ての演算が終わった後、W8値が、最初にデータが入った値より必ず1個前に進んでいる事。
常にADCからの新データは、旧データを書き換えていきます。
さて W0に加算結果がコピーされ、今度は平均ですから [10]で割らなくてはいけません。
でも私は割り算が苦手で・・・ここは 10でなく [8]で割ります。(インチキじゃん)
結果はさほど変わらないと思います。(ほんとかよ)
でも私は割り算が苦手で・・・ここは 10でなく [8]で割ります。(インチキじゃん)
結果はさほど変わらないと思います。(ほんとかよ)
asm("asr W0,#3,W0");・・・3bit右にシフトして W0の値を 1/8
asm("mov W0,DAC1LDAT");・・・結果をアナログに変換して左出力
asm("mov W0,DAC1LDAT");・・・結果をアナログに変換して左出力
今回のプログラムは非常に原始的なのでドウナルか心配です。
次回をお楽しみに・・・
次回をお楽しみに・・・
by JA1QVM
PS:2週間近く別荘?に行っていまして、先程無事に帰還しました。
小さいですが我が家が一番です。