質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.38%

  • C

    4814questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リアルタイムで波形の最大値を求めたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,299

sotooki

score 9

 前提・実現したいこと

dsPICのプログラムを用いてA/D変換された4000点の計測データの最大値と何点目で最大値であったかを求めようとしています。
A/D変換前のオシロスコープの波形

 発生している問題・エラーメッセージ

リアルタイムで前後のデータを比較し、値の高いデータを”山登り法”を用いて求めていますが、ノイズが混入しているため、時々異なる値が最大値として出力されてしまいます。

イメージ説明

 該当のソースコード

void __attribute__((__interrupt__, __shadow__))_T2Interrupt(void)//割り込み処理関数
{

 IFS0bits.T2IF=0;//割込みフラグクリア
 dds_CTRL=1;
 delay_ns(50);
 dds_CTRL=0;
 SigIn[0] = ReadADC12(0);// Input to A/D converter ()
 Data_new = SigIn[0]+0x8000;//0~FFFFで与える 
 n=n+1;

 // 最大値検出(トーナメント) //
 if(Data_new > TopDataV)//山登り法を用いた前後の計測値の比較
 {
  TopDataV = Data_new;
  TopDataf = n;
 }

/***  掃引終了判定* **/
 if(n>=4000)//4000点比較したら最大値を格納
 {
   count=count+1;
  Vmin[count]=TopDataV;//最大値格納
  fmin[count]=TopDataf;//最大値が何点目であったか格納

  dds_Int=1;
  delay_ns(50);
  n=0;
  dds_Int=0;

 }
}

 試したこと

4000点をいったん配列に格納しようと試みましたが、メモリが足りませんでした。

 補足情報(FW/ツールのバージョンなど)

dsPIC
C言語
MPLAB

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ozwk

    2018/06/07 16:04

    一定波高の模擬入力パルスを入れているが、測定値がずれるのをなんとかしたいという話でしょうか? であれば、どのぐらいずれてますか?

    キャンセル

  • sotooki

    2018/06/07 18:12

    形は変わりませんが一定波高ではなく、計測によって上下左右にシフトする波形を計測しております。

    キャンセル

回答 3

checkベストアンサー

0

4000点の配列を、ローカル変数で確保せずに、グローバル変数(関数の外)で確保してみましょう
イマドキのPCでは数万点程度ではびくともしませんぜ


って、PICなの?それじゃ無理やねー
せいぜい十数点程度のバッファを持って、移動平均しながら最大値求める、ってテですかね

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/07 18:27

    オーバーフローは問題なさそうです。
    先ほどの指摘部分を改善してみましたがやはり動作が確認できません。
    あとは何が考えられますでしょうか。

    キャンセル

  • 2018/06/07 18:38

    最大値の時の位置を求めるなら、nの値をとってこないといかんのでは。

    開発環境はなんか知らんけど、デバッグ機能はないの?
    途中でプログラム止めて変数の内容をモニタできるとかできればいいんだけど。

    キャンセル

  • 2018/06/08 12:33

    この質問からはちと外れるけど、アドバイスをいくつか。
    タイマ割り込みルーチンの中では、時間のかかる処理をしないようにしよう
    ・A/Dの起動後、データを取るまでウェイトしてるけど、これをデータとった後、A/Dの起動をかけるようにすればウェイトはいらなくなります(次のタイマ割り込みでデータ取得)
    ・変数の初期化はメインルーチンで実行すれ。
    ・バッファの容量を16とか32みたいな数字にしてるのはちゃんと理由があります
    cnt &= ~0xf; // if がいらない
    average_new = sum >>4; // 割り算いらない

    キャンセル

0

こんにちは。

単に最大値ではダメなのでしょうか?
極大点を求めるわけでないのであれば、単なる最大値で良いはずです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/08 22:42

    > 山登り法のWikipediaの記事は大嘘
    https://ja.wikipedia.org/wiki/%E5%B1%B1%E7%99%BB%E3%82%8A%E6%B3%95
    こちら確認してみましたが、プログラムはきちんと山登り法のもので最大値を求めるようなことはありませんね。
    (そもそも最大値が求められれば苦労しない)
    > 全く逆です。単なる最大値・最小値を求める方法では極値を求めることができないので、色々工夫して極値を求めるのですよ。
    失礼ながら、1次元などの全数探索が容易な場合だけを考えていらっしゃいませんか?

    キャンセル

  • 2018/06/09 00:27 編集

    ikadzuchiさん、コメントありがとうございます。

    Wikipediaのコードを良く見てみました。確かに山登り法になっていますね。私の見方が甘かったようです。訂正ありがとうございます。(WikipediのプログラムのcurrentNodeはbestNodeの間違いですね。)

    > 失礼ながら、1次元などの全数探索が容易な場合だけを考えていらっしゃいませんか?

    全くその通りです。
    当たり前と思いますが、最大値を求める時は全数探索します。どうしても全数探索が困難な場合に限って極値で代用することもあるかもしれませんが、それは一般的ではないと思います。特に説明がない以上一般的なケースを想定するのが適切と思います。

    キャンセル

  • 2018/06/10 02:10

    なるほど。私は山登り法(など局所探索法)を使うのは次元数が多く全数探索が現実的でない場合が一般的かなと思ったもので。
    currentNote・bestNodeは確かにおかしいですね。

    キャンセル

0

とりあえず、異常値を捨てる という方針ではいかがでしょうか?
思い切って、以下のどれかで捨てては?
a. 2700 以上の値は捨てる。
b. 直前の値より300以上大きな値は捨てる。
c. 折角のDSPicなので、周波数成分を求めて、ハイパスフィルタする。

真剣に対策をとるなら、何が原因で大きく外れたように見える値が測定されるか分析したほうがいいです。
目立たないだけで小さい方にも異常値があるかもしれません。もともと全く測定できていないかもしれないです。(ランダムノイズを分析している)
素人でも思いつく外れる原因は、
a. 測定範囲オーバーフロー。
b. 計算途中でオーバー・アンダーフロー
c. データ取り込みのタイミングエラー
d. 電源などのノイズ。測定系の電圧が瞬間的に低くなっているなど。 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/08 00:01

    ノイズの計測データはVBを用いてエクセル出力したのもので、VBのプログラムでa,bのような考え方でノイズを無くすことには成功しました。
    現在はdsPIC内でこのノイズを解消したいと思い、今回質問いたしました。
    データ取り込みのタイミングエラーは考えられると思います。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.38%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    4814questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。