Add some docs plc funcs and constants.

This commit is contained in:
Anders Sandström
2020-04-07 11:42:03 +02:00
parent ad8c8778b6
commit 221c39b703
6 changed files with 180 additions and 14 deletions

View File

@@ -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_;
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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=<data 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

View File

@@ -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);