CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

CCS C Conversion Help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

CCS C Conversion Help
PostPosted: Tue Feb 14, 2006 8:32 am     Reply with quote

Hello all,

I've been trying to convert a couple of pieces of code available on the web for DFTs and have been having problems because of my limited knowledge of C. One of the pices of code is below with the original code in comments then my code, and my questions within the code near the areas that are troubling me. Any help would be greatly appreciated, as I'm on day two with little progress and my ICD-U40 just went south...

Here is the link to the article with the original code:
http://www.elecdesign.com/Articles/Index.cfm?AD=1&ArticleID=5575

The general:

3.236
18F4620

I'm reading 8bit values from the ADC of a clean sine wave @105hz. So values are from 10 to about 240. When I try to use the code I get some negative results for the DFTs. I think I have a problem when I've modified the code from it's original form.... Problems seem to be variable scope, pointers, data types, etc. THis is not the code in it's entirety, but the troublesome part.



Code:

/*
hrft
A C Program For Spectrum Magnification: When The FFT Is Not Enough
Version 1.0
March 27, 2003
by
Stefan Hollos, [email protected]
Richard Hollos, [email protected]
Exstrom Laboratories LLC
P.O. Box 7651
Longmont, CO 80501
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

/*
Calculates the Fourier transform over Nf points from
 frequency
f1 to frequency f2, of N (N>1) samples of a signal taken at
sps samples per second. The values of cos(n*Omega) &
 sin(n*Omega)
are calculated using Chebyshev polynomials.
*/

//void hrft( int N, double *q, double Omega, double *Qr, double *Qi )
//Why if N and Omega are defined in MAIN are they passed to the
//function? Aren't they available for GLOBAL use anyway?
//Also, if I define the array "q" do I need to pass "q" to the function?
//I've tried with and without.

void hrft( int L_N, FLOAT *q, FLOAT L_Omega, FLOAT *Qr, FLOAT *Qi )
{
  int n;
  //double C0, S0; /* cos(Omega) & sin(Omega) */
  //double T0, T1, T2; /* Type I Chebyshev polynomials */
  //double U0, U1, U2; /* Type II Chebyshev polynomials */
  //double Cn, Sn; /* cos(n*Omega) & sin(n*Omega) */
  FLOAT C0, S0; /* cos(Omega) & sin(Omega) */
  FLOAT T0, T1, T2; /* Type I Chebyshev polynomials */
  FLOAT U0, U1, U2; /* Type II Chebyshev polynomials */
  FLOAT Cn, Sn; /* cos(n*Omega) & sin(n*Omega) */

  C0 = cos(L_Omega);
  S0 = sin(L_Omega);
  T0 = 1.0;
  T1 = C0;
  U0 = 1.0;
  U1 = 2.0*C0;


  /* this takes care of n = 0,1 */
  *Qr = q[0] + q[1]*T1;
  *Qi = q[1]*S0*U0;

  //I added this for debugging and got compilation errors
  //Only way it will compile is with format %u
  //Aren't Qr and Qi FLOATS?
  printf("%f %f\n\r", Qr, Qi);


  C0 *= 2.0;
  for( n = 2; n < L_N; ++n )
  {
    T2 = C0*T1 - T0;
    T0 = T1;
    T1 = T2;
    U2 = C0*U1 - U0;
    U0 = U1;
    U1 = U2;
    Cn = T2;
    Sn = S0*U0;
    *Qr += q[n]*Cn;
    *Qi += q[n]*Sn;
  } /* end for n */
} /* end function hrft */

/****************************************************/

int main()
{
  double f1, f2;
  int Nf;
  double df;
  //int N;
  int N = 64;
  //int i, n;
  //n is declared locally in the function
  int i;
  //double sps;
  //double Omega;
  //double dOmega;
  //double *q;
  //double Qr, Qi;
  FLOAT sps;
  FLOAT Omega;
  FLOAT dOmega;
  //Big problems here....
  //I don't want to use malloc, so I just define the array
  FLOAT q[64];  //I store my ADC values here for processing
  FLOAT Qr, Qi;


  /* allocate a double array of size N */
  //Don't use this.....
  //q = (double *)malloc( N * sizeof(double) );

  df = (f2-f1)/((FLOAT)(Nf-1));

  //Omega = 2.0 * M_PI * f1 / sps;
  //dOmega = 2.0 * M_PI * df / sps;
  Omega = 2.0 * 3.1415927 * f1 / sps;
  dOmega = 2.0 * 3.1415927 * df / sps;

  for( i = 0; i < Nf; ++i )
  {
    hrft( N, q, Omega, &Qr, &Qi );
    fprintf( fp, "%lf %lf\n", Qr, Qi );
    Omega += dOmega;
  } /* end for i */

}


So, to recap my confusion.... The inability to use the printf statement on the FLOATs or the values I THINK are floats, baffles me. To avoid using "malloc" have I done the conversion correctly? Why are global variables passed to the function?

Thanks,

John


EDIT:

BTW, here is some more kind of bizarre results. When I add the following code the printf code works as expected.

Code:


FLOAT test1;
FLOAT test2;

  test1 = q[0] + q[1]*T1;
  test2 = q[1]*S0*U0;
  printf("Qr=%f Qi=%f\n\r", test1, test2);

Ttelmah
Guest







PostPosted: Tue Feb 14, 2006 9:13 am     Reply with quote

No. Qr, and Qi, are _not_ floats. They are _pointers_ to floats.
*Qr, is the float _pointed to_, by Qr.

Use:
printf("%f %f\n\r", *Qr, *Qi);

Best Wishes
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Tue Feb 14, 2006 9:22 am     Reply with quote

Thanks RJ,

I just looked at "Absolute Beginner's Guide to C" and just figured that out. I was in the process of changing that around.

Any ideas on the declaration of the array and how it gets passed to the function?

Thanks guys,

John
Ttelmah
Guest







PostPosted: Tue Feb 14, 2006 10:06 am     Reply with quote

I don't quite understand the other part of your question. You declare an array 'q[64]'. Now in C, there is a 'shorthand', that the name of an array, is it's address. So the address of this gets passed to the function.
Now 'q', is not a global array. It is a local array to _main_. You could declare it as 'global', by declaring it outside main, and then you would not need to pass it's address to the function, but could access it directly. For the single array, this might well be easier.

Best Wishes
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Tue Feb 14, 2006 12:39 pm     Reply with quote

Made that change to the declaration of the array and modified the function and the call appropriately.

Started a methodical verification of the math and discovered PIC has a hard time with the sin and cos calcs, as I expected. I'm going to move to a lookup table and continue on with the "math validation".

Thanks again for the help,

John
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Tue Feb 14, 2006 12:59 pm     Reply with quote

Disregard the last post. My cheapy scientific calculator was giving me bad numbers. I'll stick to my TI-89 from now on.....

PIC calcs were real good.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group