2

I am about to Fourier analyse some data I've taken, but i need to know at which sampling rate the data was written to the serial monitor. I've found a lot of threads about how to increase it and such but not a single one that lays down some information about what the sampling-rate is.

My code is very simple, here it is:

      // the setup routine runs once when you press reset:
  void setup() {
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);
  }

  // the loop routine runs over and over again forever:
  void loop() {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);
    // print out the value you read:
    Serial.println(sensorValue);
  }
  • Roughly 9600 sampl/s, but the sampling rate will not be constant because of the timer interrupt. For an example on how to get a steady and controlled sampling rate on an AVR-based Arduino, see this example of configuring the ADC in free-running mode. – Edgar Bonet Jun 4 '16 at 16:56
  • Thanks, will look into it after dinner. If it solves it, i'll get back to you and mark it as answer :) – DakkVader Jun 4 '16 at 16:58
  • 1
    BTW, could you please tag your question with the type of Arduino? It may make a difference. My comment above applies to most (if not all) AVR-based Arduinos, but not to ARM-based ones. Oh, and the Serial.println() will likely slow down the acquisition by a factor 50 or so once the Serial output buffer fills out. – Edgar Bonet Jun 4 '16 at 17:32
  • 1
    Yeah, just realized that the serial.println does NOT print 9600 values/sec, This messes up my data. Basically what i want to do is do some tests on some different sounds i expose it to and then find those frequencies with fourier analysis. – DakkVader Jun 4 '16 at 17:47
  • 1
    Note that you can do other stuff while a conversion is taking place. The implementation of analogRead just wait/block until it's done. What I've done is some cases, is read the data from a previous conversion, start a new conversion, and process the data from the previous conversion , while the new conversion is running (in the background). – Gerben Jun 4 '16 at 18:34
2

The ADC in default configuration will take 104 µs to make a sample (which agrees with Edgar Bonet's comment of roughly 9600 per second).

You can speed that up somewhat by changing the ADC prescaler from the default of 128. See ADC conversion on the Arduino (analogRead). A prescaler of 32 will reduce that to 26 µs and still give quite acceptable results.

You can also run the ADC asynchronously (in the background) so you can transmit the previous result while obtaining the next one. A higher baud rate than 9600 baud would be highly recommended in this case.

People have been doing FFT analysis using the Arduino Uno and similar. I suggest you Google for relevant posts about that.

  • Yeah, i've done som reading now. The problem i currently have is that i know the rate at which the analogread is updated, the problem is that the serial.println does not print at nearly the same speed which gives me an unknown samplingrate of the data i've access to. Currently i'm considering buying a national instruments Data acquisition card. I've used them in uni and they suit my needs. Also, i can get the labview-software from school – DakkVader Jun 6 '16 at 11:34
  • @DakkVader: You can send the data to the computer in real time if you sample at 9600 S/s and send only the 8 most significant bits, in binary form (Serial.write()), at 115200 bps. Otherwise you could buffer the samples in RAM at whatever sampling rate you want and send them later, but this will limit you to short sampling runs. – Edgar Bonet Jun 6 '16 at 12:17
  • Could you elaborate on this ? Basically i'd like to get whatever information analogread can get, at it's given sampling-rate. Serial.print won't give me at the true rate – DakkVader Jun 6 '16 at 16:38
0

I loaded this program on an arduino uno and measured with oscilloscope the time from the rising edge to the falling edge of the signal on pin13.

void setup() {

    Serial.begin(9600);
    pinMode(13,OUTPUT);
}

void loop() {
    PORTB = B00100000; //pin13 HIGH
    int sensorValue = analogRead(A0);
    PORTB = B00000000; //pin13 LOW
}

results:

time: 110.4 uS relevant freuency: 9.06 kHz


in case you are interested in fast analogRead with Due, I suggest you take a look at this. The author stated that an analogRead with Due takes about 40uS and he also describes a couple of ways to make it much faster.

  • Your figure of 110 µs agrees pretty-much with my quoted 104 µs. The code in analogRead does more than just the read, so the other 6 µs would be setting up for the read, waiting for it to finish, and then storing the results. Also, there is an extra time before a conversion starts. The conversion starts on the leading edge of the ADC clock, not the moment the code asks for it. In the case of a scaler of 128, there could be 127 extra (processor) clock cycles added, because the hardware has to wait for the next ADC clock cycle. This could add 7.938 µs to the conversion time. – Nick Gammon Jun 6 '16 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.