1

I am trying to find a way to calculate the frequency of sine wave which is presented in array form, based on indexes by taking differences of indexes. Known to me is the time it takes between two adjacent indexes so I could just multiply this time constant with the difference in the indices between two max points (or min points).

Here is my approach:

float find_freq(uint16_t array[500])
{
    int i = 0;
    int max1 = 0;
    int max2 = 0;
    int max1_index = 0;
    int max2_index = 0;
    int min1 = 0;
    int min2 = 0;
    int min1_index = 0;
    int min2_index = 0;
    int foundperiod = 0;
    int samples = 0;

    while(foundperiod == 0)
    {
        uint16_t current_element = array[i];
        uint16_t next = array[i+1];
        if (current_element < next && min1 == 0)
        {
            min1 = 1;
            min1_index = i;
        }
        if (current_element > next && max1 == 0)
        {
            max1 = 1;
            max1_index = i;
        }
        if (current_element < next && min1 == 1)
        {
            min2 = 1;
            min2_index = i;

        }
        if (current_element > next && max1 == 1)
        {
            max1 = 1;
            max1_index = i;
        }
        i++;
        if (max1 == max2 == min1 == 1 || min1 == max1 == min2 == 1)
        {
            foundperiod = 1;
        }
    }
    if (max1 == max2 == min1 == 1)
    {
        samples = max2_index - max1_index;

    }
    else if (min1 == max1 == min2 == 1)
    {
        samples = min2_index - min1_index;
    }
    
    //Irrelevant part
    uint16_t n = 55000;
    int cycles = 3;
    float frequency = 1 / (samples*(n/cycles));
    return frequency;
}

fails on the part before the while loop exits

if (max1 == max2 == min1 == 1 || min1 == max1 == min2 == 1)
    {
        foundperiod = 1;
    }

even if my sine wave array has correct values, the while loop exists incorrectly so I'm guessing this syntax is wrong? I want to stop when I have found a single wave, i.e a max, min and another max point or a min, max and another min point. sine data has noise so the min points and max points will not be equal, however this noise is very small.

Laurel
  • 5,965
  • 14
  • 31
  • 57
user1397215
  • 321
  • 1
  • 6
  • 18

3 Answers3

2

The operator == returns a logic result either 0 or 1.

max1 == max2 == min1 == 1

will be interpreted as

( ( max1 == max2 ) == min1 ) == 1

When min1 is equal to 0 , max2 is equal to 1, max1 is equal to 0, the expression will be caculated as

( ( 0 == 1 ) == 0 ) == 1
( 0 == 0 ) == 1
1 == 1
1

and your loop will exit.

Aean
  • 759
  • 1
  • 6
  • 16
0

You probably want

if (max1 == max2 && max1 == min1 && max1 == 1 || min1 == max1 && min1 == min2 && min1 == 1)
{
    foundperiod = 1;
}
deviantfan
  • 11,268
  • 3
  • 32
  • 49
0

Oh, yes, you cannot use == that way. C, not being truly typesafe, happily converts bools to ints. a == b == c is compiled as (a==b) == c, where a==b is 0 (false) or 1.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • In older C implementations, there is no bool to begin with, so no conversion takes place; conditionals are simple ints. Even C99's bool is an integer type with special properties. – Peter - Reinstate Monica Mar 19 '14 at 10:55
  • And digging into the C99 standard: 6.5.9 (in the draft) states that the result of the equality operators (i.e. == and !=) is int, actually. So there is no conversion in C99, either ;-). – Peter - Reinstate Monica Mar 19 '14 at 11:04