This is an EPICS areaDetector driver for a simulated ADC driver. This driver generates times-series data for 8 signals as a 2-D array [8, NumTimePoints]. The signals are common waveforms (sine, cosine, square wave, sawtooth, random noise, etc.) The driver was written in part to test the new NDPluginTimeSeries plugin in ADCore R2-5. But it can also serve as a starting point for writing drivers that are used to collect time-series data like ADCs, waveform digitizers, etc.
Each signal in the driver describes a waveform. The equations governing these signals are similar. The equation for the sine wave is the following:
Signal[t] = Offset + Noise * random() + Amplitude * sin((time * Frequency + Phase/360.) * 2. * PI);
This driver inherits from asynNDArrayDriver. It also implements a number parameters that are specific to the ADC simulation detector. The ADCSimDetector class documentation describes this class in detail.
The simulation driver-specific parameters are the following:
Parameters for the driver as a whole Parameter Definitions in ADCSimDetector.cpp and EPICS Record Definitions in ADCSimDetector.template |
||||||
Parameter index variable | asyn interface | Access | Description | drvInfo string | EPICS record name | EPICS record type |
---|---|---|---|---|---|---|
P_Acquire | asynInt32 | r/w |
Start/stop acquisition. Values are: 0: "Done": Stops acquisition 1: "Acquire": Starts acquisition |
SIM_ACQUIRE |
$(P)$(R)Acquire $(P)$(R)Acquire_RBV |
busy bi |
P_TimeStep | asynFloat64 | r/w | Time per data point | SIM_TIME_STEP |
$(P)$(R)TimeStep $(P)$(R)TimeStep_RBV |
ao ai |
NumTimePoints | asynInt32 | r/w | Number of time points to accumulate before calling registered plugins | SIM_NUM_TIME_POINTS |
$(P)$(R)NumTimePoints $(P)$(R)NumTimePoints_RBV |
longout longin |
P_AcquireTime | asynFloat64 | r/w | Total elapsed time before automatically stopping acquisition. If 0 then acquistion continues until manually stopped. Note that this is "simulated time", i.e. the number of time points since acquisition was started * TimeStep. This may differ from actual time because of the processor speeds, granularity of epicsThreadSleep(), etc. | SIM_ACQUIRE_TIME |
$(P)$(R)AcquireTime $(P)$(R)AcquireTime_RBV |
ao ai |
P_ElapsedTime | asynFloat64 | r/w | Total elapsed time since acquisition was started. | SIM_ELAPSED_TIME | $(P)$(R)ElapsedTime | ai |
Parameters for each signal N.
Parameter Definitions in NDPluginTimeSeries.h and EPICS Record Definitions in ADCSimDetectorN.template |
||||||
P_Amplitude | asynFloat64 | r/w | The amplitude of this signal. | SIM_AMPLITUDE | $(P)$(R)Amplitude | ao |
P_Offset | asynFloat64 | r/w | The offset of this signal. | SIM_OFFSET | $(P)$(R)Offset | ao |
P_Phase | asynFloat64 | r/w | The phase of the signal in degrees. | SIM_PHASE | $(P)$(R)Phase | ao |
P_Noise | asynFloat64 | r/w | The noise of this signal. This value is multipled by a random number between -1 and 1 for each time point. | SIM_NOISE | $(P)$(R)Noise | ao |
P_Period | asynFloat64 | r/w | The period of this signal. The frequency is calculated from the period. | SIM_PERIOD | $(P)$(R)Period | ao |
P_Frequency | asynFloat64 | r/o | The frequency of this signal, calculated from the period. | SIM_FREQUENCY | $(P)$(R)Frequency | ai |
The ADCimDetector driver is created with the ADCimDetectorConfig command, either from C/C++ or from the EPICS IOC shell.
int ADCSimDetectorConfig(const char *portName, int numTimePoints, int dataType, int maxBuffers, size_t maxMemory, int priority, int stackSize)
The simDetector-specific fields in this command are:
numTimePoints
Initial number of time points.dataType
Initial data type of the detector data. These are the enum
values for NDDataType_t, i.e.
For details on the meaning of the other parameters to this function refer to the detailed documentation on the simDetectorConfig function in the ADCSimDetector.cpp documentation and in the documentation for the constructor for the ADCSimDetector class.
There an example IOC boot directory and startup script (iocBoot/iocADCSimDetector/st.cmd) provided with ADExample.
The following is the MEDM screen simDetector.adl for the simulation detector.
The NDPluginTimeSeries is used to collect the time series data from the ADCSimDetector, perform optional averaging. In this case it is being used in circular buffer mode. The NDArrays it produces are being used by the NDPluginFFT plugin to compute Fast Fourier Transforms.
This is a plot for the sin(x)*cos(x) output. This screen contains some of the controls for the time series plugin.
This is a combined plot for the square wave output. It contains the time-series data, as well as the real, imaginary, and absolute value of the FFT. Note that the square wave FFT contains the fundamental frequency of 5 Hz, and all of the odd harmonics.