Full Cycle DFT with atmega2560

I have implemented Full cycle DFT algorithm in arduino 2560. It works well with fundamental(50Hz). It attenuates all even harmonics. But surprisingly lets through all odd harmonics. What am I doing wrong? Here is my code

//Full Cycle DFT Experiment- Sampling Frequency is 1KHz and Number of samples is N=20
// Sample Mode-ADC
#define Sampling_Interval 1000 // unit us - 1KHz
#define Samples 20
#define Scaling 3.45
const int analogInPin = A0;
long startTime;
long endTime;
uint16_t n,i;
float result;
float FCDFT(int16_t arry[]);
int16_t values[Samples];
char real_coeff[Samples];
char imag_coeff[Samples];
void setup()
{
Serial.begin(9600);
pinMode(4, OUTPUT);
startTime=0;
endTime=0;
n=0;
for(i=0;i<Samples;i++)
{
real_coeff_= cos(23.14159i/20);//LUT_
imag_coeff_= sin(23.14159i/20);
* }*
}
void loop()
{
* while(1)*
* {*
* startTime=micros();*
* if((startTime-endTime)>=Sampling_Interval)
_
{*

* endTime = micros();*
* if (n<Samples)*
* {*
* values[n] = analogRead(analogInPin);*
* n++; *
* }*
* else if(n==Samples)*
* {*
* result= FCDFT(values);*
* n=0;*
_ Serial.println(result*Scaling);_

* }*
* } *
* }*
}
float FCDFT(int16_t arry[])
{
* float real = 0;*
* float imag = 0;*
* float voltage =0;*
* unsigned char k;*
* unsigned char AVG=3;*
* for (k = 0; k<Samples; k++)*
* {*
_ voltage = arry[k] * (5.0/1023.0);
real= real+voltagereal_coeff[k];
imag= imag+voltageimag_coeff[k];

* }*
return sqrt(0.01realreal +0.01imagimag);_

}

That does not seem to be a DFT to me.

P.S. Please use "code" tags to properly display your code.

Hi,

Certainaly I am a newbie. I just referred to the link https://digital.library.adelaide.edu.au/dspace/bitstream/2440/77855/8/02whole.pdf , page 31.The code is a single point DFT with moving data window. Let me know what is the wrong?

gary36:
Hi,

Certainaly I am a newbie. I just referred to the link https://digital.library.adelaide.edu.au/dspace/bitstream/2440/77855/8/02whole.pdf , page 31.The code is a single point DFT with moving data window. Let me know what is the wrong?

You have lost me with " It works well with fundamental(50Hz). It attenuates all even harmonics. But surprisingly lets through all odd harmonics" . With your code how do you get values for anything but the 50Hz value? Using a sample rate of 1KHz and taking 20 samples means you are only obtaining the 50 Hz component of the input and not the harmonics of 50 Hz. What am I missing?

Also, I'm uncomfortable with the indexing used in equations 2.1 and 2.2 in your reference. The indexing is normally k within 0 to (N-1) and not within 1 to N , Since I have not read the whole reference I can't be sure it is wrong but should be worth checking.

hi
Strangely, the code works well when I include the cosine/sine within FCDFT function.

void setup()
{
for(i=0;i<Samples;i++)
{
real_coeff_= cos(23.14159i/20);//LUT_
imag_coeff_= sin(23.14159i/20);
* }*
* }*
* for (k =0; k<Samples; k++)*
* {*
voltage = arry[k](5.0/1023.0);_
//real+= voltagereal_coeff[k]; //This does not work

//imag+= voltageimag_coeff[k];
_ real+=voltagecos(23.14159k/20); //This does work_

_ imag+= voltagesin(23.14159k/20);_
_
}*_

OMG! silly mistake

char real_coeff[Samples];
char imag_coeff[Samples];

wrong declaration it should be float. It works now!!

gary36:
OMG! silly mistake

char real_coeff[Samples];
char imag_coeff[Samples];

wrong declaration it should be float. It works now!!

I still don't see how it gets the values for the harmonics of 50 Hz.

Hi

After correcting the datatype, I get only 50Hz and all odd/even harmonics are rejected.

gary36:
Hi

After correcting the datatype, I get only 50Hz and all odd/even harmonics are rejected.

Your published code only evaluates the 50 Hz component. Where is the code the deals with 100Hz, 150Hz, 200Hz etc etc ?

It would sure help if you read How to post code properly and then use the </> icon to create

[code]...[/code]

tags around your code so that it is easier to read. More to the point, it wouldn't suddenly turn into italics and lose your array idexing.

Pete

You forgot the array indices, so only the zeroth entry in each array is being set.

    for(i=0;i<Samples;i++)
   {
   real_coeff= cos(2*3.14159*i/20);//LUT
   imag_coeff= sin(2*3.14159*i/20);
  }

jremington:
You forgot the array indices, so only the zeroth entry in each array is being set.

    for(i=0;i<Samples;i++)

{
  real_coeff= cos(23.14159i/20);//LUT
  imag_coeff= sin(23.14159i/20);
  }

and the magic 20s should be replaced by "Samples" so that when the OP changes the number of points used in the DFT the code will still work.