audio - 如何根据频率转换arduino数字输出

标签 audio arduino android-sensors arduino-uno

我正在使用一个模拟输出声音传感器模块,其中传感器模块的输出连接到 arduino,可以看到 arduino 正在进行 Ato D 转换并显示范围为 0 到 1023 的整数。

但我需要计算从传感器获得测量的声音频率。

所以你能帮我吗,hwo从arduino的这个Ato D转换值计算频率。

最佳答案

您真的不需要进行 ADC 转换吗?您需要做的就是检测输入的上升沿,然后对它们进行计数。由于您的传感器将输出低-高-低序列,并且由于 Arduino 会将 HIGH 记录为超过一定电压,这应该足够了。

从连接到板上数字引脚 8 的输入,此代码将测量高达 200 kHz 左右:

// Input: Pin D8 

volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;

// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect) 
{
  overflowCount++;
}  // end of TIMER1_OVF_vect

ISR (TIMER1_CAPT_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = ICR1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  // if just missed an overflow
  if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
    overflowCopy++;

  // wait until we noticed last one
  if (triggered)
    return;

  if (first)
    {
    startTime = (overflowCopy << 16) + timer1CounterValue;
    first = false;
    return;  
    }

  finishTime = (overflowCopy << 16) + timer1CounterValue;
  triggered = true;
  TIMSK1 = 0;    // no more interrupts for now
  }  // end of TIMER1_CAPT_vect

void prepareForInterrupts ()
  {
  noInterrupts ();  // protected code
  first = true;
  triggered = false;  // re-arm for next time
  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;

  TIFR1 = bit (ICF1) | bit (TOV1);  // clear flags so we don't get a bogus interrupt
  TCNT1 = 0;          // Counter to zero
  overflowCount = 0;  // Therefore no overflows yet

  // Timer 1 - counts clock pulses
  TIMSK1 = bit (TOIE1) | bit (ICIE1);   // interrupt on Timer 1 overflow and input capture
  // start Timer 1, no prescaler
  TCCR1B =  bit (CS10) | bit (ICES1);  // plus Input Capture Edge Select (rising on D8)
  interrupts ();
  }  // end of prepareForInterrupts


void setup () 
  {
  Serial.begin(115200);       
  Serial.println("Frequency Counter");
  // set up for interrupts
  prepareForInterrupts ();   
  } // end of setup

void loop () 
  {
  // wait till we have a reading
  if (!triggered)
    return;

  // period is elapsed time
  unsigned long elapsedTime = finishTime - startTime;
  // frequency is inverse of period, adjusted for clock period
  float freq = F_CPU / float (elapsedTime);  // each tick is 62.5 ns at 16 MHz

  Serial.print ("Took: ");
  Serial.print (elapsedTime);
  Serial.print (" counts. ");

  Serial.print ("Frequency: ");
  Serial.print (freq);
  Serial.println (" Hz. ");

  // so we can read it  
  delay (500);

  prepareForInterrupts ();   
}   // end of loop

更多讨论和信息请访问 Timers and counters .

关于audio - 如何根据频率转换arduino数字输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31378726/

相关文章:

c++ - 为什么只打印这些字符串的最后一个字母?

android - 我可以在 Android 上检测物理磁场传感器还是虚拟磁场传感器?

android - 如何以稳定准确的方式读取Android加速度计值?

iphone - 如何自动播放音频文件?

audio - 如何将蓝牙音频 A2DP 路由到音频设备 MediaStream 中? (来自 Electron 应用程序)

macos - 使用 Xcode 5 在 Mac OS X 上进行 Arduino 编程?

android - 是否所有 Android 手机都具有最少的一组传感器

android - 查看特定文件夹中的音频

html - 如何在html5中平衡音频

c++ - 通过 Arduino 上的 gprs shield 接收短信