Nutsy wrote:
I dont know if its because im so tired... but i can barely understand what that line does :p

I know the feeling

Here's the full code. Ive actually modified it since that post so it reads from two adc port and produces two fft's. That line is taking the 16 bit integer and shifting it into a 32 bit integer which contains a 16 bit real value (the one from the adc) and a 16 bit imaginary value (zero) which is the way the fft function needs its data to be stored.

Hope this explains it and get yourself a good nights sleep!

Steve.

Code: Select all

```
#include "cr4_fft_1024_stm32.h"
#define FFTLEN 1024
#define LED PC13
uint16_t reala; // value from from adc
uint16_t realb; // value from from adc
uint16_t imag = 0;
uint32_t xa[FFTLEN]; // acceleration wave form
uint32_t ya[FFTLEN]; // fft spectra
uint32_t xb[FFTLEN]; // acceleration wave form
uint32_t yb[FFTLEN]; // fft spectra
double avg;
double res = 3.3/4096.0; // 12 bit resolution at 3.3V ref
double sen = 0.3; // accelerometer sensitivity in volts/g
double twopi = 6.283185307179; // 2 X Pi used for fft
double gconv = 9806.65; // gravity in mm/s/s
double hz = 5; // 5 hz per bin
void adcsample()
{
unsigned long start_time;
unsigned long next_time;
unsigned long end_time;
int tot=0;
if(micros()>0xFFF0BDBF) // micros is less than 1 second until rollover
delay(1010); // 1.01 second delay to take micros past rollover
avg=0;
start_time = micros();
next_time = micros()+391;
for(int a=0; a<FFTLEN; a++)
{
reala = analogRead(PA0);
realb = analogRead(PA1);
tot+=reala;
xa[a] = (((uint16_t)(reala*16)) | ((uint32_t)(imag<<16)));
xb[a] = (((uint16_t)(realb*16)) | ((uint32_t)(imag<<16)));
for(;;)
if((long)micros()>next_time)
break;
next_time+=391;
}
avg= (double) tot/FFTLEN;
avg*=res;
}
void inplace_magnitude(uint32_t * target, uint16_t len)
{
for (int i=0;i<len;i++){
int16_t real = target[i] & 0xFFFF;
int16_t imag = target[i] >> 16;
uint32_t magnitude = sqrt(real*real + imag*imag);
target[i] = magnitude;
}
}
void setup() {
pinMode(PA0, INPUT_ANALOG);
pinMode(PA1, INPUT_ANALOG);
pinMode(LED, OUTPUT);
Serial.begin(115200);
}
void loop() {
int loopa;
double acc=0;
double vel=0;
double accb=0;
double velb=0;
delay(5000);
adcsample();
digitalWrite(LED, HIGH); // flash led to indicate adc read
delay(100);
digitalWrite(LED, LOW);
cr4_fft_1024_stm32(ya, xa, FFTLEN); /*computes the FFT of the x[N] samples*/
cr4_fft_1024_stm32(yb, xb, FFTLEN); /*computes the FFT of the x[N] samples*/
inplace_magnitude(ya,FFTLEN);
inplace_magnitude(yb,FFTLEN);
ya[0]=0;
Serial.print(acc,7);
Serial.print("\t");
Serial.println(vel,7);
for(loopa=1; loopa<400; loopa++)
{
acc=(double)ya[loopa]*res*sen;
vel=acc*gconv/(twopi*hz*loopa);
accb=(double)yb[loopa]*res*sen;
velb=accb*gconv/(twopi*hz*loopa);
Serial.print(vel,7);
Serial.print("\t");
Serial.println(velb,7);
}
for(;;);
}
double hanning (int i, int nn)
{
return ( 0.5 * (1.0 - cos (twopi*(double)i/(double)(nn-1))) );
}
```