Go Down

Topic: compiling error (Read 696 times) previous topic - next topic

Vik321

original
Code: [Select]
//
/*
This code has three "print modes":

Line 41 can print to terminal which frequency is most dominant.
Lines 47-49 can print to terminal the values of each bin.
Line 49 will print can print to plotter the visualization of all the bins.
*/
//https://www.norwegiancreations.com/2017/08/what-is-fft-and-how-can-you-implement-it-on-an-arduino/
//https://github.com/kosme/arduinoFFT/blob/master/Examples/FFT_04/FFT_04.ino
#include "arduinoFFT.h"
 
#define SAMPLES 128             //Must be a power of 2
#define SAMPLING_FREQUENCY 1000 //Hz, must be less than 10000 due to ADC
 
arduinoFFT FFT = arduinoFFT();
 
unsigned int sampling_period_us;
unsigned long microseconds;
 
double vReal[SAMPLES];
double vImag[SAMPLES];
 
void setup() {
    Serial.begin(115200);
 
    sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}
 
void loop() {
   
    /*SAMPLING*/
    for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!
     
       vReal[i] = analogRead(0);
       
        vImag[i] = 0;
     
        while(micros() < (microseconds + sampling_period_us)){
        }
    }
 
    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
 
    /*PRINT RESULTS*/
    //Serial.println(peak);     //Print out what frequency is the most dominant.
 
    for(int i=0; i<(SAMPLES/2); i++)
    {
        /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
         
        //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
        //Serial.print(" ");
        Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
    }
 
    //delay(1000);  //Repeat the process every second OR:
    //while(1);       //Run code once
}


in original
Code: [Select]
vReal[i] = analogRead(0);





Vik321

so why


Code: [Select]
amplitude[i] = analogRead(0);

is causing the problems

AWOL

so why


Code: [Select]
amplitude[i] = analogRead(0);

is causing the problems
amplitude is not an array.
It doesn't take a subscript.

lesept

Ok, here are the questions you need to ask yourself

  • What is it you measure with your sensor, using analogRead ? Amplitude or real part?
  • What do you want to display to the user or make calculations on?


If you can answer these questions, then you can write your code.

If you want to display or calculate something from the real and imaginary parts, such as the FFT, then you need to store those values in arrays and only those values. In this case the amplitude is just an intermediate variable that you use once and don't need to store for later use.

If you need to calculate or display all the amplitude values, then you have to store them in an array.

To declare an array, so as you already did
Code: [Select]
double whatever[SAMPLES];
And to store or use the i-th value of this array, use whatever [ i ]

All the variables you don't store in arrays, you just declare them as global variables or local when you need to use them

I hope this is clear, because I am not a native English speaker (at all)
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

johnwasser

The results
@johnwasser

noise, no respond to input signal
I think the problem is in your math.  I take no blame for your math mistakes. :)
WHY are you mashing a 32-bit float into an 8-bit int and then storing the result in a 32-bit float?
The sine wave has a range of -1.0 to +1.0.  You divide that value by 2 for some unexplained reason and get a range of -0.5 to +0.5.  THEN you multiply by whatever you got from the analog input, a value from 0 to 1023.  WHAT IS THAT VALUE DOING?  If it is just a 'gain' control to set the amplitude of the signal, you should probably divide it by 1024.0 to get a gain from 0.0 to (about) 1.0 and use the same value for all of the samples!  If it is an audio signal that you want to multiply into the sine signal (for whatever reason) you should probably subtract 512 and divide it by 512.0 to get a -1 to +1 signal.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

Vik321

in case that the numbers are too high, I divided the results by 100 instead of 2, still no respond to input.

Vik321

#22
Mar 25, 2019, 12:29 am Last Edit: Mar 25, 2019, 12:34 am by Vik321
Thanks to your suggestions I get something with this code.
Code: [Select]
#include "arduinoFFT.h"
#include <math.h>
#define SAMPLES 128             //Must be a power of 2
#define SAMPLING_FREQUENCY 5000 //Hz, must be less than 10000 due to ADC
const double signalFrequency = 1000;






arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double amplitude[SAMPLES];
double vReal[SAMPLES];
double vImag[SAMPLES];
double cycles = (((SAMPLES - 1) * signalFrequency) / SAMPLING_FREQUENCY);

void setup() {
  Serial.begin(115200);

  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
}

void loop() {
  int i;
 //float amplitude[i];
  /*SAMPLING*/

  ///////////////////////////////////////
  /*SAMPLING*/
  for (int i = 0; i < SAMPLES; i++)
  {
    microseconds = micros();    //Overflows after around 70 minutes!

   // amplitude = analogRead(0);
   amplitude[i] = analogRead(0);
    //lesept
    //vImag[i] = int8_t((amplitude[i] * (cos((i * (twoPi * cycles)) / SAMPLES))) / 2000.0);
    //vReal[i] = int8_t((amplitude[i] * (sin((i * (twoPi * cycles)) / SAMPLES))) / 5000.0);

       vImag[i] = int32_t((amplitude[i] * (cos((i * (twoPi * cycles)) / SAMPLES))) / 2000.0);
    vReal[i] = int32_t((amplitude[i] * (sin((i * (twoPi * cycles)) / SAMPLES))) / 5000.0);

    //johnwasser, pic sine
    //vReal[i] = int8_t((amplitude * (sin((i * (twoPi * cycles)) / SAMPLES))) / 2.0);
    // vImag[i] = int8_t((amplitude * (cos((i * (twoPi * cycles)) / SAMPLES))) / 2.0);

    //  vReal[i] = int8_t((2 * (sin((i * (twoPi * cycles)) / SAMPLES))) /2.0);
    // vImag[i] = int8_t((2 * (cos((i * (twoPi * cycles)) / SAMPLES))) / 2.0);

    while (micros() - microseconds < sampling_period_us)
    {
    }
  }
  ///////////////////////////////////////////////
  /*FFT*/
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

  /*PRINT RESULTS*/
  //Serial.println(peak);     //Print out what frequency is the most dominant.

  for (int i = 0; i < (SAMPLES / 2); i++)
  {
    /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/

    //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
    //Serial.print(" ");
    Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
  }
}



Vik321

now I need to replace
Code: [Select]
const double signalFrequency = 1000;

by "peak" which is input  frequency, this attempt does not work

Code: [Select]
int  signalFrequency = peak ;
int peak ;


The error
Code: [Select]
peak:6:24: error: 'peak' was not declared in this scope

 int  signalFrequency = peak ;

                        ^~~~

exit status 1
'peak' was not declared in this scope

lesept

You need to read some basic information about the structure of a Arduino program.

In the part before the setup, you can mainly declare variables and libraries. Declaring variables can be just like this
Code: [Select]
int X;
or assign them a value
Code: [Select]
int X=0;
but you cannot put instructions such as
Code: [Select]
X = Y;
especially if Y was not declared before, which is what you tried to do.

So this
Code: [Select]
int  signalFrequency;
int peak ;

is correct, then in the setup or the loop you can have
Code: [Select]
signalFrequency = peak ;
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

wildbill

The compiler is complaining that peak doesn't exist when you try to use it because you declared it after the attempt to use it. Moving the declaration up would make that go away.

However, it's probably not what you want, because peak won't contain anything useful. I'm guessing that you have some other code that reads it. Post it all for better answers.

PaulS

signalFrequency and peak were doubles. Why did you change the type to int?
The art of getting good answers lies in asking good questions.

Vik321

The compiler is complaining that peak doesn't exist when you try to use it because you declared it after the attempt to use it. Moving the declaration up would make that go away.

However, it's probably not what you want, because peak won't contain anything useful. I'm guessing that you have some other code that reads it. Post it all for better answers.
Post #15 = original code /*PRINT RESULTS*/ //Serial.println(peak); //Print out what frequency is the most dominant.
The results are printed without declaring "peak"
 

Vik321

signalFrequency and peak were doubles. Why did you change the type to int?
I am trying a different versions to eliminate the errors

Go Up