0

背景:フォトダイオードからの出力を測定するために使用しているIOIOがあります。これは、デジタル出力に変換されます。信号が1と0の間で変化する周波数を見つける必要があります。これまでに試したすべてのことで、テストアプリがハングしました。何か提案はありますか?

現在のコード:

if(diode == 1 && frequencyFound == false){
  startTime = System.currentTimeMillis();
  while((frequencyFound == false)){
     if(diode == 0){
        while(frequencyFound == false){
            if(diode == 1){
                double endTime = System.currentTimeMillis();
                time = endTime - startTime;
                frequency = (long) (1.0 / time);
                frequencyFound = true;
            }
            Thread.sleep(100);
        }
     }
     Thread.sleep(100);
  }
}
4

2 に答える 2

1

エドワードが提起したタイミング精度の懸念のいくつかを回避するためのさらに2つの極端な提案:

  • 割り込み下のIOIOボードでインターバル時間の測定を行います。この場合、おそらく(少なくともほぼ)リアルタイム操作を実行できます。これらの時間測定値をAndroidデバイスに報告してください。

  • ioioボードをスキップして、信号をオンまたはオフにするトーンとしてヘッドセットコネクタにルーティングする簡単なものを作成します。オーディオシステムに組み込まれているタイミング保証を使用してオーディオを録音し、オーディオバッファを分析して(リアルタイムは不要になります)、介在するオーディオサンプル時間の単位での間隔を決定します(他のものと比較して比較的信頼性があります)アンドロイドアプリで行うことができます)オーディオサンプルレート。また、光センサーを使用してオーディオ発振器の周波数を変更することにより、アナログ入力を簡単に取得できます。

于 2012-05-12T18:10:08.920 に答える
1

ここにはいくつかの問題があります。

まず、Android はマルチタスク システムであり、タイミング スレッドが長時間スリープ状態になり、信号遷移を見逃す可能性があります。ループで入力をサンプリングするのではなく、リーディング (またはトレーリング) エッジ遷移を通知する方法はありませんか?

どのような周波数を見ていますか?100 ミリ秒のサンプリング間隔で十分でしょうか?

Thread.sleep() が指定した時間だけスリープすることを期待しないでください。間隔が短すぎると、システムはすぐに復帰することを決定したり、スリープ時間をより長い時間に切り上げたりする場合があります。

タイミング ループは (せいぜい) 100 ミリ秒を超える精度で時間を記録しないため、周波数の推定値は非常に低くなります。

Zapl は正しいです。UI スレッドとは別のスレッドからこれを実行する必要があります。

単一の遷移を監視すると、頻度の非常に不正確な見積もりが得られます。代わりに次のようにしてみてください。

// Find frequency to the nearest hz (+/- 10%)
// It's assumed that some other process is responsible for updating the "diode"
// variable.  "diode" must be declared volatile.
long duration = 1000;   // 1 second
final int interval = 100;    // sampling inteval = .1 second
int oldState = diode;
int count = 0;
final long startTime = System.currentTimeMillis();
final long endtime = startTime + duration;
while (System.currentTimeMillis() < endtime) {
  // count all transitions, both leading and trailing
  if (diode != oldState) {
    ++count;
    oldState = diode;
  }
  Thread.sleep(interval);
}
// find the actual duration
duration = System.currentTimeMillis() - startTime;
// Compute frequency. The 0.5 term is because we were counting both leading and
// trailing edges.
float frequency = 0.5 * count / (duration/1000);
于 2012-05-12T17:03:22.090 に答える