我怎么知道采样频率?


16

我开始对采样率和波特率等感到困惑。我有这个Arduino代码:

#include <eHealth.h>

extern volatile unsigned long timer0_overflow_count;
float fanalog0;
int analog0;
unsigned long time;


byte serialByte;
void setup() {
  Serial.begin(9600);
}

void loop() { 
  while (Serial.available()>0){  
    serialByte=Serial.read();
    if (serialByte=='S'){        
      while(1){
        fanalog0=eHealth.getECG();  
        // Use the timer0 => 1 tick every 4 us
        time=(timer0_overflow_count << 8) + TCNT0;        
        // Microseconds conversion.
        time=(time*4);   
        //Print in a file for simulation
        //Serial.print(time);
        //Serial.print(" ");
        Serial.print(fanalog0,5);
        Serial.print("\n");

        if (Serial.available()>0){
          serialByte=Serial.read();
          if (serialByte=='F')  break;
        }
      }
    }
  }
}

由于没有延迟中断,所以采样率/频率是多少?它基于Arduino ADC的速度吗?当我增加波特率时,我是在增加采样频率还是在串行端口上发送数据的速率?

Answers:


21

Arduino ADC时钟速度在..arduino-1.5.5 \ hardware \ arduino \ avr \ cores \ arduino \ wiring.c中设置

这是相关的部分

#if defined(ADCSRA)
    // Set A/D prescale factor to 128
    // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
    // XXX: this will not work properly for other clock speeds, and
    // this code should use F_CPU to determine the prescale factor.
    sbi(ADCSRA, ADPS2);
    sbi(ADCSRA, ADPS1);
    sbi(ADCSRA, ADPS0);

    // Enable A/D conversions
    sbi(ADCSRA, ADEN);
#endif

对于16 MHz的Arduino,ADC时钟设置为16 MHz / 128 = 125 KHz。AVR中的每次转换需要13个ADC时钟,因此125 KHz / 13 = 9615 Hz。

这是最大可能的采样率,但是应用程序中的实际采样率取决于连续转换调用之间的间隔。
由于您读取结果并通过串行端口发送结果,因此延迟会随着波特率的降低而增加。波特率越低,发送相同长度的数据所需的时间就越长,调用下一次ADC转换所花费的时间也就越长。

可以使用调试器或模拟器来确定应用程序中的实际采样率,但更简单的解决方案是每次执行转换时都切换数字引脚并测量数字引脚切换的频率。


另外,我的时间戳之间的时间从1300一直增加到16400,确定它们应该保持不变吗?那是9600,在115200,经过很多时间,它们仅增加到大约1500。
user3284376 2014年

@ user3284376关于您的时间戳代码,我认为它不能一直工作(可能会在错误的时间因某些中断而产生偏差)。我建议您发布一个有关如何在Arduino上获得高精度定时的具体问题,并将代码的相关部分放在那里。
jfpoilpret 2014年

7

我还想为一个项目获得高采样率。事实证明,可以将ADCSRA寄存器的ADPS2,ADPS1,ADPS0位配置为获得76923 s / s或76.8 ks / s的采样率。但是,请注意,我正在以自由运行模式运行arduino的ADC,以下几行对我有用。

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

void setup() {
// Set the Prescaler to 16 (16000KHz/16 = 1MHz)
// WARNING: Above 200KHz 10-bit results are not reliable.
//ADCSRA |= B00000100;
sbi(ADCSRA, ADPS2);
cbi(ADCSRA, ADPS1);
cbi(ADCSRA, ADPS0);

// Set ADIE in ADCSRA (0x7A) to enable the ADC interrupt.
// Without this, the internal interrupt will not trigger.
//ADCSRA |= B00001000;
sbi(ADCSRA,ADIE)
}

在此频率下,通常的10位结果是不可靠的。这意味着增加采样率会降低结果的精度。所以我只使用高8位,因为在此预分频器中,高8位是可靠的。您可以在此页面上详细介绍,这家伙真是太棒了!他使用UNO http://www.instructables.com/id/Girino-Fast-Arduino-Oscilloscope/制作了高采样率示波器


3

每个循环都通过9600bps串行链路打印8个字符。每个字符占用10位(1个开始,8个字符,1个停止)。这意味着您只能通过此循环〜120次/秒。

analogRead()函数理论上可以以大约9600次/秒的速度采样,实际上,大约是8600次/秒。

您受到串行通信的束缚。


那么增加到115200,给出1440次/秒,是采样率吗?
user3284376 2014年

给予或接受,是的。您需要记住,串行要求另一端响应,因此您依赖于PC响应。这不是确定性的,因此会产生抖动。
Cyber​​gibbons 2014年

您在Arduino端上是正确的,一切看起来都很好,但是在Python上,它要慢得多,我需要做些什么来提高计算机端的性能?
user3284376 2014年

您不必将其视为PC上串行性能的问题,而是如何使采样与数据发送分离。
Cyber​​gibbons 2014年

1
@Cyber​​gibbons-不,因为它是在Uno上运行的,USB和串行接口已解耦,所以除了发出'S'字符和不发出'F'字符外,对PC的依赖也没有。此处发布的草图及其运行平台将很高兴在USB串行配套微型计算机上抛出串行数据,而忽略了USB另一端的数据是否跟上。
克里斯·斯特拉顿

3

以9600的波特率通过串行发送11位,但是对于采样,我将其存储在尽可能少的延迟的数组中,然后完成后,我将其通过串行端口发送,以供python脚本读取。我正在使用matplotlib进行FFT。我监听0-5V信号,然后不使用delay()函数,而是将AnalogRead()值存储到该数组中。在瞬间完成读取,然后开始串行数据转储。当我使用另一个连接的Arduino的tone()校准输入频率时,我意识到必须将索引除以8915,才能使精度达到0.1 Hz之内。因为必须除以采样频率才能获得适当的索引间隔,所以我的猜测是Arduino采样频率(至少在我的代码中是8915Hz)。


1

参考有关采样率和波特率之间差异的部分,它们是不同的度量。

采样率是设备(arduino)可以重新创建输入模拟值的数字表示的频率。

波特率是在通信通道中传输信息的速率。它描述了微控制器与外界(计算机)之间的通信速率。

我建议使用这个electronics_stack_exchange链接。 /electronics/135056/sampling-rate-data-rate-and-bandwidth


0

8915Hz-非常接近125000/14〜= 8928.6我最初的猜测是,相邻转换之间完全需要一个间隙。一个ADC时钟用于采样,而13个ADC时钟用于转换本身。小错误可能是Arduino的时钟源不完善的结果。我还不确定。现在,这个主题对我来说是实际的,因为采样数据必须馈入数字滤波器。


1
我不确定当您说“这个话题对我来说现在是实际的,因为采样数据必须馈入数字滤波器时”的意思。您有类似的问题吗?
VE7JRO

每次转换都在ADC时钟的上升沿开始,并且至少有一个ADC时钟周期丢失了执行代码。因此,是的,analogRead()在紧密循环中调用时,8928.6 Hz是最快的,而在自由运行模式下,则是非常一致的9615.4 Hz。
Edgar Bonet
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.