Mbed frequency measurement discrepancies

26 Jul 2010

Hi,

I was curious as to how accurately the Mbed could read and store analog frequency data. I ran a few tests, and found that the data was gibberish. In general I get a file full of values you might expect from a square wave, a list of 0s then a list of 0.7s. However analyzing the data reveals some strange results. My design is fairly simple, the program is included at the end. I have a function generator hooked up to an analog input. The Mbed is grounded to the same ground as the input ground. I have the generator set to a steady 10 or 20 Hz square wave (verified by oscilloscope) and properly offset so that the bottom of the square wave is truly 0, ground. The output data file looks as it should but once I try to find the input frequency from this data, I get insane results. My method is this:

count the number of data points taken in a full oscillation of the wave (from the beginning of a trough to the beginning of the next trough) and multiply is by the sampling rate set in the program. That yields the period of the wave, and the reciprocal of that is the frequency. So here is a table of values I got from this method.

@10Hz, square wave

sampling rate(us) #samples/period period(ms) frequency(hz)
100 112 11.2 89
200 116 23.2 43
300 115 34.5 29
400 117 46.8 21.4
500 85 42.5 23.5
600 88 52.8 18.9
700 85 59.5 16.8
800 82 65.6 15.2
900 74 66.6 15.0
1000 64 64 15.6

@20Hz, square wave

sampling rate(us) #samples/period period(ms) frequency(hz)
100 55 5.5 181
200 68 13.6 73
300 66 19.8 50.5
400 50 20 50
500 44 22 45
600 32 19.2 52
700 31 21.7 46
800 36 28.4 34
900 39 35.1 28

So clearly something is wrong. Does anyone have experience using the Mbed for frequency measurements and encountered this problem or done something differently?

 

Here is the program I used, written by D. Wendelboe, thanks

#include "mbed.h"

#define ON   1
#define OFF  0

LocalFileSystem local("local");
AnalogIn myinput(p18);
DigitalOut myled(p5);
DigitalOut led1(LED1);
DigitalOut led2(LED2);

float analog_value;
int count = 0;

int main() {

    FILE *fp = fopen("/local/analog.txt","w");  // Open a file to save samples
    printf("File analog.txt is open.\r\n");

    while (count < 500) {
        analog_value = myinput.read();  // Read analog (range 0.0 to 1.0)
        if (analog_value > 0.6)         // If value is above 0.3, then store
        {                               // it as an "above" value.
            fprintf (fp, "%3i: %f [above]\r\n", count+1, analog_value);
            led1 = ON;     // Turn LED ON if sample was stored.

        } else {           // Below 0.3, store it as a "below" value.
            fprintf (fp, "%3i: %f [below]\r\n", count+1, analog_value);
            led1 = OFF;    // Turn OFF if sample was not stored.
        }
        count++;           // Increment sample counter.
        wait_us(900);
    }
    fclose(fp);            // Close the sampe file after 100 samples read.
}