From 221c39b70333df983d13dbc274352e6eede2c0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Sandstr=C3=B6m?= Date: Tue, 7 Apr 2020 11:42:03 +0200 Subject: [PATCH] Add some docs plc funcs and constants. --- .../ecmcPlugin_FFTApp/src/ecmcFFT.cpp | 20 +++- .../ecmcPlugin_FFTApp/src/ecmcFFT.h | 3 + .../ecmcPlugin_FFTApp/src/ecmcFFTDefs.h | 7 ++ .../ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp | 12 +++ .../ecmcPlugin_FFTApp/src/ecmcFFTWrap.h | 92 +++++++++++++++++-- .../ecmcPlugin_FFTApp/src/ecmcPluginFFT.c | 60 +++++++++++- 6 files changed, 180 insertions(+), 14 deletions(-) diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp index 872242b..4d15fb9 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.cpp @@ -67,7 +67,8 @@ ecmcFFT::ecmcFFT(int fftIndex, // index of this object (if several is cr asynPort_ = NULL; asynEnable_ = NULL; asynRawData_ = NULL; // Input data - asynFFTAmp_ = NULL; // Result + asynFFTAmp_ = NULL; // Result + status_ = NO_STAT; elementsInBuffer_ = 0; fftCalcDone_ = 0; callbackHandle_ = -1; @@ -213,6 +214,7 @@ void ecmcFFT::connectToDataSource() { if( !dataTypeSupported(dataItem_->getEcmcDataType()) ) { throw std::invalid_argument( "Data type not supported." ); } + status_ = IDLE; } void ecmcFFT::dataUpdatedCallback(uint8_t* data, @@ -223,6 +225,7 @@ void ecmcFFT::dataUpdatedCallback(uint8_t* data, return; } if (cfgMode_ == TRIGG && !triggOnce_ ) { + status_ = IDLE; return; // Wait for trigger from plc or asyn } @@ -238,11 +241,16 @@ void ecmcFFT::dataUpdatedCallback(uint8_t* data, //Buffer full if(!fftCalcDone_){ // Perform calcs - calcFFT(); // FFT cacluation () + status_ = CALC; + + // **** Breakout to sperate low prio work thread below + calcFFT(); // FFT cacluation scaleFFT(); // Scale FFT calcFFTAmp(); // Calculate amplitude from complex - triggOnce_ = 0; // Wait for nex trigger if in trigg mode + // **** Breakout to thread above + triggOnce_ = 0; // Wait for nex trigger if in trigg mode + // Update asyn with both input and result asynRawData_->refreshParamRT(1); // Forced update (do not consider record rate) asynFFTAmp_->refreshParamRT(1); // Forced update (do not consider record rate) @@ -265,6 +273,8 @@ void ecmcFFT::dataUpdatedCallback(uint8_t* data, return; } + status_ = ACQ; + size_t dataElementSize = getEcDataTypeByteSize(dt); uint8_t *pData = data; @@ -645,3 +655,7 @@ void ecmcFFT::triggFFT() { void ecmcFFT::setModeFFT(FFT_MODE mode) { cfgMode_ = mode; } + +FFT_STATUS ecmcFFT::getStatusFFT() { + return status_; +} diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h index e0cf4b7..0ae1ca1 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFT.h @@ -42,6 +42,7 @@ class ecmcFFT { void connectToDataSource(); void setEnable(int enable); void setModeFFT(FFT_MODE mode); + FFT_STATUS getStatusFFT(); void clearBuffers(); void triggFFT(); @@ -67,6 +68,7 @@ class ecmcFFT { int objectId_; // Unique object id int triggOnce_; double scale_; // Config: Data set size + FFT_STATUS status_; // Status/state (NO_STAT, IDLE, ACQ, CALC) // Config options char* cfgDataSourceStr_; // Config: data source string @@ -77,6 +79,7 @@ class ecmcFFT { int cfgEnable_; // Config: Enable data acq./calc. FFT_MODE cfgMode_; // Config: Mode continous or triggered. + // Asyn ecmcAsynDataItem* asynEnable_; // Enable/disable acq./calcs ecmcAsynDataItem* asynRawData_; // Raw data (input) array (double) diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTDefs.h b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTDefs.h index 13114fb..e4b9706 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTDefs.h +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTDefs.h @@ -32,6 +32,13 @@ typedef enum FFT_MODE{ TRIGG = 2, } FFT_MODE; +typedef enum FFT_STATUS{ + NO_STAT = 0, + IDLE = 1, // Doing nothing, waiting for trigg + ACQ = 2, // Acquireing data + CALC = 3, // Calc FFT +} FFT_STATUS; + /** Just one error code in "c" part of plugin (error handled with exceptions i c++ part) */ #define ECMC_PLUGIN_FFT_ERROR_CODE 1 diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp index bba8039..0986661 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.cpp @@ -110,3 +110,15 @@ int modeFFT(int fftIndex, FFT_MODE mode) { } return 0; } + +FFT_STATUS statFFT(int fftIndex) { + try { + return ffts.at(fftIndex)->getStatusFFT(); + } + catch(std::exception& e) { + printf("Exception: %s. FFT index out of range.\n",e.what()); + return NO_STAT; + } + return NO_STAT; +} + diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h index 11a2690..fe4650c 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcFFTWrap.h @@ -17,14 +17,92 @@ extern "C" { # endif // ifdef __cplusplus -// To one fft object -int createFFT(char *source); -int enableFFT(int fftIndex, int enable); -int clearFFT(int fftIndex); -int triggFFT(int fftIndex); -int modeFFT(int fftIndex, FFT_MODE mode); -// To all fft objects +/** \brief Create new FFT object + * + * The plugin supports creation of multiple FFT objects\n + * (if loaded several times).\n + * The different fft are adressed by fftindex (in other functions below).\n + * The first loaded fft get index 0 and then increases for each load.\n + * This function call will create the custom asynparameters dedicated for this plugin.\ + * The configuration string needs to define a data source by:\n + * "SOURCE=;"\n + * Example:\n + * "SOURCE=ec0.s1.AI_1";\n + * \param[in] configStr Configuration string.\n + * + * \return 0 if success or otherwise an error code.\n + */ +int createFFT(char *configStr); + +/** \brief Enable/disable FFT object + * + * Enable/disable FFT object. If disabled no data will be acquired\n + * and no calculations will be made.\n + * \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n + * \param[in] enable enable/disable (1/0).\n + * + * \return 0 if success or otherwise an error code.\n + */ +int enableFFT(int fftIndex, int enable); + +/** \brief Clear FFT object\n + * + * Clears buffers. After this command the acquistion can start from scratch.\n + * \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n + * + * \return 0 if success or otherwise an error code.\n + */ +int clearFFT(int fftIndex); + +/** \brief Set mode of FFT object + * + * The FFT object can measure in two differnt modes:\n + * CONT(1) : Continious measurement (Acq data, calc, then Acq data ..)\n + * TRIGG(2): Measurements are triggered from plc or over asyn and is only done once (untill next trigger)\n + * \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n + * \param[in] mode Mode CONT(1) or TRIGG(2)\n + * + * \return 0 if success or otherwise an error code.\n + */ +int modeFFT(int fftIndex, FFT_MODE mode); + +/** \brief Trigger FFT object\n + * + * If in triggered mode a new measurment cycle is initiated (fft will be cleared first).\n + * \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n + * + * \return 0 if success or otherwise an error code.\n + */ +int triggFFT(int fftIndex); + +/** \brief Get status of FFT object + * + * The FFT object can be in different states:\n + * NO_STAT(0): Invalid state (something is most likely wrong)\n + * IDLE(1) : Waiting for trigger in triggered mode\n + * ACQ(2) : Acquiring data (filling data buffer)\n + * CALC(3) : Calculating FFT results\n + * \param[in] fftIndex Index of fft (first loaded fft have index 0 then increases)\n + * + * \return Status of fft (if index is out of range NO_STAT will be returned).\n + */ +FFT_STATUS statFFT(int fftIndex); + +/** \brief Link data to _all_ fft objects + * + * This tells the FFT lib to connect to ecmc to find it's data source.\n + * This function should be called just before entering realtime since then all\n + * data sources in ecmc will be definded (plc sources are compiled just before runtime\n + * so are only fist accesible now).\n + * \return 0 if success or otherwise an error code.\n + */ int linkDataToFFTs(); + +/** \brief Deletes all created fft objects\n + * + * Should be called when destructs.\n + */ + void deleteAllFFTs(); # ifdef __cplusplus diff --git a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c index 3c2d5ae..cf6288d 100644 --- a/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c +++ b/ecmcPlugin_FFT-loc/ecmcPlugin_FFTApp/src/ecmcPluginFFT.c @@ -67,6 +67,7 @@ int fftRealtime(int ecmcError) } /** Link to data source here since all sources should be availabe at this stage + * (for example ecmc PLC variables are defined only at enter of realtime) **/ int fftEnterRT(){ return linkDataToFFTs(); @@ -100,6 +101,11 @@ double fft_mode(double index, double mode) { return (double)modeFFT((int)index, (FFT_MODE)((int)mode)); } +// Plc function for enable +double fft_stat(double index) { + return (double)statFFT((int)index); +} + // Register data for plugin so ecmc know what to use struct ecmcPluginData pluginDataDef = { // Allways use ECMC_PLUG_VERSION_MAGIC @@ -218,21 +224,67 @@ struct ecmcPluginData pluginDataDef = { .funcArg9 = NULL, .funcArg10 = NULL, }, - .funcs[4] = {0}, // last element set all to zero.. + .funcs[4] = + { /*----fft_stat----*/ + // Function name (this is the name you use in ecmc plc-code) + .funcName = "fft_stat", + // Function description + .funcDesc = "double fft_stat(index) : Get status of fft (NO_STAT, IDLE, ACQ, CALC) for fft[index].", + /** + * 7 different prototypes allowed (only doubles since reg in plc). + * Only funcArg${argCount} func shall be assigned the rest set to NULL. + **/ + .funcArg0 = NULL, + .funcArg1 = fft_stat, + .funcArg2 = NULL, + .funcArg3 = NULL, + .funcArg4 = NULL, + .funcArg5 = NULL, + .funcArg6 = NULL, + .funcArg7 = NULL, + .funcArg8 = NULL, + .funcArg9 = NULL, + .funcArg10 = NULL, + }, + .funcs[5] = {0}, // last element set all to zero.. // PLC consts /* CONTINIOUS MODE = 1 */ .consts[0] = { .constName = "fft_CONT", - .constDesc = "Continious mode", + .constDesc = "FFT Mode: Continious", .constValue = CONT }, /* TRIGGERED MODE = 2 */ .consts[1] = { .constName = "fft_TRIGG", - .constDesc = "Triggered mode", + .constDesc = "FFT Mode :Triggered", .constValue = TRIGG }, - .consts[2] = {0}, // last element set all to zero.. + /* TRIGGERED MODE = 2 */ + .consts[2] = { + .constName = "fft_NO_STAT", + .constDesc = "FFT Status: Invalid state", + .constValue = NO_STAT, + }, + /* TRIGGERED MODE = 2 */ + .consts[3] = { + .constName = "fft_IDLE", + .constDesc = "FFT Status: Idle state (waiting for trigger)", + .constValue = IDLE + }, + /* TRIGGERED MODE = 2 */ + .consts[4] = { + .constName = "fft_ACQ", + .constDesc = "FFT Status: Acquiring data", + .constValue = ACQ + }, + /* TRIGGERED MODE = 2 */ + .consts[5] = { + .constName = "fft_TRIGG", + .constDesc = "FFT Status: Calculating result", + .constValue = CALC + }, + .consts[6] = {0}, // last element set all to zero.. }; ecmc_plugin_register(pluginDataDef);