Vai al contenuto
PLC Forum


trasformata fourier FFT per manutenzione predittiva


fdevid

Messaggi consigliati

Buongioro a tutti,

ho provato a creare/copiare  una FFT su awl ma c'è qualcosa che non va ... qualche bravo ingegnere mi saprebbe aiutare ?

PS: il dato in ingresso L deve essere in potenza di 2 ma purtroppo non mi funziona

 

FUNCTION_BLOCK FB856 

//TITLE   = 'FFT'
//VERSION : '1.0'
//AUTHOR  : FD
//NAME    : FFT
//FAMILY  : ML


VAR_INPUT 
      L  : INT ;                 // Lenght of data 
END_VAR

VAR_OUTPUT 

END_VAR

VAR_IN_OUT 
      x_real: ARRAY[0..512] OF REAL;
      x_complex: ARRAY[0..512] OF REAL;
END_VAR

VAR 
      tmp_real      : ARRAY[0..512] OF REAL;  // temporary storage for real components
      tmp_complex   : ARRAY[0..512] OF REAL;  // temporary storage for imaginary components
      N             : INT  ;                  // Lenght of current computed FFT vector 
      w_real        : ARRAY[0..64] OF REAL; ; // Twiddle factors real component  
      w_complex     : ARRAY[0..64] OF REAL; ; // Twiddle factors imaginary componentt
      k             : INT  ; // Loop index  
      ind           : INT  ; // Index of the first ( even) sum element
      w_ind         : INT  ; // Twiddle factor index
      span          : INT  ; // Block index
      LpN           : INT  ; // Total data lenght divide by current N. Saved for optimization reasons
      w_r           : REAL ; // Selected twiddle factor real component  
      w_c           : REAL ; // Selected twiddle factor imaginary component
      A_r           : REAL ; // Even element real componet
      A_c           : REAL ; // Even element imaginary componet
      B_r           : REAL ; // Even element real componet
      B_c           : REAL ; // Even element imaginary componet
      
      FOR_TMP       : INT  ; // Temporary 
END_VAR

(* ------------------------------- *)
(*            START                *)
(* ------------------------------- *)

BEGIN    
N := 2;


WHILE N <= L DO //(* Twidddle factor precalculation *)

     FOR k := 0 TO N/8 BY 1 DO
            w_real[k] := cos(2.0*3.14159265359*int_to_real(k)/int_to_real(N));
            w_complex[k] := sin(2.0*3.14159265359*int_to_real(k)/int_to_real(N));
     end_for;
        
        ind := 0;
        w_ind := 0;
        span := 1;
        LpN := L/N;


        for k := 0 to L-1 do

                 //(* Selecting RIGHT twiddle factor
                 //   Cases are split in two just TO halve condition evaluations *)
            IF w_ind <= N/2 THEN
                IF w_ind <= N/8 THEN
                    w_r := w_real[ w_ind ];
                    w_c := -w_complex[ w_ind ];
                ELSIF w_ind <= N/4 THEN
                    w_r := w_complex[ N/4-w_ind ];
                    w_c := -w_real[ N/4-w_ind ];
                ELSE
                    w_r := -w_real[ N/2-w_ind ];
                    w_c := -w_complex[ N/2-w_ind ];
                END_IF;    
            ELSE
                IF w_ind <= 5*N/8 THEN
                    w_r := -w_real[ w_ind-N/2 ];
                    w_c := w_complex[ w_ind-N/2 ];
                ELSIF w_ind <= 3*N/4 THEN
                    w_r := -w_complex[ 3*N/4-w_ind ];
                    w_c := w_real[ 3*N/4-w_ind ];
                ELSIF w_ind <= 7*N/8 THEN
                    w_r := w_complex[ w_ind-3*N/4 ];
                    w_c := w_real[ w_ind-3*N/4 ];
                ELSE
                    w_r := w_real[ N-w_ind ];
                    w_c := w_complex[ N-w_ind ];
                END_IF;
          
            END_IF;

            A_r := x_real[ ind ];
            A_c := x_complex[ ind ];
            B_r := x_real[ ind+LpN ];
            B_c := x_complex[ ind+LpN ];

            //(* Separation of real and imaginary components *)
            tmp_real[ k ] := A_r + B_r*w_r - B_c*w_c;
            tmp_complex[ k ] := A_c + B_r*w_c + B_c*w_r;

           // (* Indexing
           //    Index is the index OF even element. Odd element is always with index
           //    offset OF LpN from even element. *)
           // ind := ind + 1;
            IF ind + LpN = L THEN (* Transition from first half to second *)
                ind := 0;
                w_ind := w_ind + 1;
                span  := 1;
            ELSIF ind + LpN = span*LpN*2 THEN (* Transition between spans *)
                ind := ind + LpN;
                w_ind := w_ind + 1;
                span := span + 1;
            END_IF;
        
        END_FOR;
      
         N := N*2;
        
        //(* Copy all elements from temp to data vector *)
        FOR k := 0 TO L-1 DO
            x_real[ k ] := tmp_real[ k ];
            x_complex[ k ] := tmp_complex[ k ];
        END_FOR;
END_WHILE;

END_FUNCTION_BLOCK
 

Link al commento
Condividi su altri siti


  • 1 year later...

Ciao

 

Qualcuno è ruscito a risolvere il problema?

 

i n t  potenza2 ( i n t  n ) // l a funz i one   c o n t r o l l a s e i l numero in argomento e una potenza

 

Link al commento
Condividi su altri siti

  • Livio Orsini locked this discussione
Ospite
Questa discussione è chiusa alle risposte.
×
×
  • Crea nuovo/a...