背景:我有一个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);
}
}
答案 0 :(得分:1)
这里有几个问题。
首先,Android是一个多任务系统,您可以发现您的计时线程长时间处于睡眠状态,错过了一些信号转换。是否无法通知前导(或尾随)边缘过渡而不是在循环中对输入进行采样?
你在看什么频率? 100 ms的采样间隔是否足够好?
不要指望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);
答案 1 :(得分:1)
解决一些时间准确性的两个极端建议是爱德华提出的:
在中断期间测量IOIO板上的间隔时间,您可以在其中完成(至少接近)实时操作。将这些时间度量报告给Android设备。
跳过ioio板,构建一些简单的信号,将信号作为开启或关闭的音调传送到耳机连接器。使用音频系统的内置定时保证录制音频,然后分析音频缓冲区(不再需要实时)以确定间隔音频采样次数的时间间隔(以相对于任何您的相对可靠性)可以做一个Android应用程序)音频采样率。您还可以使用光传感器轻松获得模拟输入,以改变音频振荡器的频率。