首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >外部光传感器的输入频率

外部光传感器的输入频率
EN

Stack Overflow用户
提问于 2012-05-13 21:06:47
回答 1查看 308关注 0票数 1

背景:我有一个IOIO,我用它来测量光电二极管的输出,然后将其转换为数字输出。我需要找出信号在1和0之间变化的频率。有人给了我一些代码,我可以用来测量频率,但我不知道如何将其集成到我现有的应用程序中。我知道我实现它的方式不会起作用,因为更新变量的UI线程正在等待另一个计算频率的线程的返回,所以这个线程只有在它开始运行时才会得到二极管的值。那么,如何使频率线程具有二极管的实时值,并在计算出频率后将其传递回UI线程进行显示呢?

下面是我的UI线程(FrequencyApp.java):

代码语言:javascript
复制
    public class FrequencyApp extends IOIOActivity {
private TextView textView_;
private TextView textView2_;
private TextView textView3_;
private ToggleButton toggleButton_;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    textView_ = (TextView)findViewById(R.id.TextView);
    textView2_ = (TextView)findViewById(R.id.TextView2);
    textView3_ = (TextView)findViewById(R.id.FrequencyLabel);
    toggleButton_ = (ToggleButton)findViewById(R.id.ToggleButton);

    enableUi(false);
}

class Looper extends BaseIOIOLooper {
    private AnalogInput input_;
    private DigitalOutput led_;
    volatile int diode;
    private long frequency;


    @Override
    public void setup() throws ConnectionLostException {
        try {
            input_ = ioio_.openAnalogInput(31);
            led_ = ioio_.openDigitalOutput(IOIO.LED_PIN, true);
            enableUi(true);
        } catch (ConnectionLostException e) {
            enableUi(false);
            throw e;
        }
    }

    @Override
    public void loop() throws ConnectionLostException {
        try {
            led_.write(!toggleButton_.isChecked());


            float reading = input_.getVoltage();

            if(reading  > 1){
                diode = 1;
            } else { 
                diode = 0;
            }
            if(toggleButton_.isChecked()){
                FrequencyThread frequencyTaskThread = new FrequencyThread();
                frequencyTaskThread.setPriority(Thread.NORM_PRIORITY-1); //Make the background thread low priority. This way it will not affect the UI performance
                frequencyTaskThread.start();
                frequency = (long) frequencyTaskThread.run(diode);
                frequencyTaskThread.stop();
            }
            setText(Float.toString(reading), Long.toString(diode), Long.toString(frequency));
            Thread.sleep(100);
        } catch (InterruptedException e) {
            ioio_.disconnect();
        } catch (ConnectionLostException e) {
            enableUi(false);
            throw e;
        }
    }
}

@Override
protected IOIOLooper createIOIOLooper() {
    return new Looper();
}

private void enableUi(final boolean enable) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            toggleButton_.setEnabled(enable);
        }
    });
}

private void setText(final String str,final String str2,final String str3 ) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            textView_.setText(str);
            textView2_.setText(str2);
            textView3_.setText(str3);
        }
    });
}

}

以下是计算频率的线程(FrequencyThread.java:

代码语言:javascript
复制
    public class FrequencyThread extends Thread {
public float run(int diode){
// 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 interval = .01 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);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
}
// 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 = (float) (0.5 * count / (duration/1000));
return frequency;
}

}

EN

回答 1

Stack Overflow用户

发布于 2012-05-13 22:11:19

设置它最简单的方法可能是使用Handler将消息从FrequencyThread发送到主线程。这种方式可能更倾向于使用AsyncTask来抽象线程/处理程序,并使整个情况更容易处理。这样做可能需要您将IOIOLooper内容放入AsyncTask中,但我没有使用该板或其Java API的经验。

此外,您不应该在setText()方法中使用"runOnUiThread“或Runnable。这似乎只是从主线程调用的。

您要做的是重写处理程序handleMessage()以调用setText()。然后在FrequencyThread内部调用handler.sendMessage(),传递回数据和/或消息(即错误)。

我试着使用你发布的代码来做一个例子,但是我很难如实地理解它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10571989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档