Magnitude spectrum:
This sample implements a single-channel magnitude spectrum. The code is split into two tasks: a control task, which collects the discrete input signal of a hardware module, e.g. EL3632, and a CM task, which calculates the spectrum. The block diagram below shows the analysis chain implemented in the sample.
The source code for the sample is available for download from here:
MagnitudeSpectrum_Sample.zip
Block Diagram
Program parameters
The table below shows a list of important parameters for the configuration of the magnitude spectrum function block.
FFT-length | 4096 |
Window size | 3200 |
Buffer size | 1600 |
Window type | eCM_HannWindow |
Scaling type | eCM_ROOT_POWER_SUM |
Scaling in decibels (dB) | FALSE |
Global Constants
These parameters are defined as constants in the list of global variables.
VAR_GLOBAL CONSTANT
cOversamples : UDINT := 10; // oversampling factor
cBufferLength : UDINT := 1600; // size of buffer for spectrum
cWindowLength : UDINT := 3200; // size of window
cFFTResult : UDINT := 2049; // size of spectrum result
cFFTLength : UDINT := 4096; // spectrum lines
END_VAR
Code for control task
The following code snippet shows the declaration in the MAIN program:
PROGRAM MAIN
VAR CONSTANT
cInitSource : ST_MA_MultiArray_InitPars := ( eTypeCode := eMA_TypeCode_LREAL, nDims := 1, aDimSizes := [cBufferLength]);
END_VAR
VAR
nInputSelection : UDINT := 1; // Switch between hardware and function generator
nSample : UDINT;
aEl3632 AT %I* : ARRAY[1..cOversamples] OF INT; // Input from hardware e.g. EL3632
aBuffer : ARRAY[1..cOversamples] OF LREAL;
fbSource : FB_CMA_Source :=( stInitPars := cInitSource, nOwnID := eID_Source, aDestIDs := [eID_Spectrum]); // Initialize source buffers
fbSink : FB_CMA_Sink := (nOwnID := eID_Sink);
aSpectrumResult : ARRAY[1..cFFTResult] OF LREAL; // Copy result
END_VAR
Method calls MAIN program:
fbSource.Input1D(pDataIn := ADR(aBuffer),
nDataInSize := SIZEOF(aBuffer),
eElementType := eMA_TypeCode_LREAL,
nWorkDim := 0,
pStartIndex := 0,
nOptionPars := 0);
fbSink.Output1D(pDataOut := ADR(aSpectrumResult),
nDataOutSize := SIZEOF(aSpectrumResult),
eElementType := eMA_TypeCode_LREAL,
nWorkDim := 0,
nElements := 0,
pStartIndex := 0,
nOptionPars := 0,
bNewResult => bCalculate);
Code for CM Task
Declaration in MAIN_CM program:
PROGRAM MAIN_CM
VAR CONSTANT
cInitSpectrum : ST_CM_MagnitudeSpectrum_InitPars := (nFFT_Length := cFFTLength,
nWindowLength := cWindowLength,
bTransformToDecibel:= FALSE,
eWindowType := eCM_HannWindow,
eScalingType := eCM_RMS);
END_VAR
VAR
fbSpectrum : FB_CMA_MagnitudeSpectrum :=(stInitPars := cInitSpectrum,
nOwnID := eID_Spectrum,
aDestIDs := [eID_Sink]);
END_VAR
Method calls in MAIN_CM program:
fbSpectrum.Call();
The result of the sample code can be checked for a sinusoidal signal of arbitrary amplitude and frequency as the input signal. The variable, fRmsValue above should be exactly equal to amplitude/SQRT(2).
Each frequency value can be assigned to the corresponding array
index of the spectrum result. Calculation formula:
sample rate = oversampling factor / sampling task cycle time
index = frequency * (FFT length / sample rate)
Requirements
Development environment |
Target system type |
PLC libraries to include |
---|---|---|
TwinCAT v3.1.4013 |
PC or CX (x86, x64) |
Tc3_CM, Tc3_CM_Base, Tc3_MultiArray |