无外围电路用 Arduino 测音源的频率


想测量一个声音信号源的频率或是占空比,但是又没频率计?我们可以用一块Arduino去搞定这事情。需要的材料仅是一块普通Arduino,无需外围元件。

特性:
1. 可以测量20~20kHz的信号,超过的话误差越来越大。
2. 误差大致是±5%。玩玩还行。
3. 输出的结果有:频率,占空比,周期,高电平时间,低电平时间。
4. 只能测量单频,复合波形就不行了。

步骤:
1.写下面程序到Arduino里面

/*
Arduino Frequency meter
Ansifa
2013/1/5
*/
int divider[6] = {0, 1, 8, 64, 256, 1024};
int prescaler = 5;
double count = 0;
double middle = 0;
char x = 0;
ISR(TIMER1_OVF_vect)
{
    if (prescaler < 4)
    {
        prescaler++;
    }
}
void interrupt()
{
    if (!x)
    {
        count = TCNT1;
        TCNT1 = 0x000;
        TCCR1B = prescaler;
        attachInterrupt(0, interrupt, FALLING);
    }
    else
    {
        middle = TCNT1;
        attachInterrupt(0, interrupt, RISING);
    }
    x = ~x;
}
void setup()
{
    Serial.begin(57600);
    TIMSK1 = 0x01;
    TCCR1A = 0x00;
    attachInterrupt(0, interrupt, RISING);
}
void loop()
{
    Serial.print("Freq: ");
    Serial.print(16000000.0 / divider[prescaler] / count);
    Serial.print(" Hz\t\tDuty: ");
    Serial.print(middle / count * 100);
    Serial.print(" %\t\tPeriod: ");
    Serial.print(0.0000625 * divider[prescaler]*count);
    Serial.print(" ms\t\tH-time: ");
    Serial.print(0.0000625 * divider[prescaler]*middle);
    Serial.print(" ms\t\tL-time: ");
    Serial.print(0.0000625 * divider[prescaler]*(count - middle));
    Serial.println(" ms");
    if (prescaler > 1)
    {
        prescaler--;
        delay(200);
    }
    delay(100);
}

2.将你的信号从D2和GND引脚输入。由于没有经过任何放大处理,信号必须满足开关Arduino引脚的电平值,就是最好可以有0-5v的振幅。电路图:

3.打开串口监视器,调波特率到57600,即可看到结果。因为没有任何防干扰措施,出现偏差特别大的结果请自行忽略。

4.如果你愿意的话,也可以扩展一下这个电路的性能:
* 振幅不够的话,可以使用运放或者三极管进行预放大;
* 测量频率不够高,可以使用74HEF4060进行分频。74HEF4060可以支持高达2^14=16384级分频,理论可以将量程提高16384倍。但是由于74HEF4060性能限制,可以将输入频率提高到20MHz。但是分频之后就只能看到频率,而测不到波形的占空比了。并且注意不要使用CD4060,那是低速版本。



1 评论

发表评论