quadEM Driver

Mark Rivers, University of Chicago

Contents

Overview

quadEM supports quad electrometers/picoammeters, typically used for photodiode-based x-ray beam position monitors, or split ion chambers. They can also be used for any low-current measurement that requires high speed digital input. There is support for two models:

  1. The AH401B picoammeter designed and sold by Synchrotron Trieste (elettra). It is also sold by CAENels. This device communicates using TCP/IP over 100 Mbit/s Ethernet or high-speed serial. It provides 4-channel current measurements at up to 1000 Hz.
  2. The Quad Electrometer built by Steve Ross from the APS (called APS_EM in this document). This device consists of a 4-channel digital electrometer unit and 2 VME boards. The device provides 2 readings per diode at up to 813 Hz.

Both of these units are based on the same principle of an op-amp run as a current amplifier with a large feedback capacitor, and a high resolution ADC.

The quadEM software includes asyn drivers and an SNL program that provide support for the following:

Detailed information on the APS electrometer can be found in the Electrometer Users Guide.

Detailed information on the AH401B electrometer can be found in the AH401B Users Manual.

The support is based on asynPortDriver. It consists of a base class (drvQuadEM.cpp) which is device-independent. There are device-dependent classes for the AH401B (drvAH401B.cpp) and the APS electrometer (drvAPS_EM.cpp). There is an EPICS State Notation Language (SNL) program (quadEM_SNL.st) is used to synchronize acquisition of time-series data, and to compute FFT power-spectra of the time-series data.

Databases

quadEM.template

The quadEM.template database provides control of the electrometer and analog input records using the standard asyn device support. This provides digitally averaged readings of the current, sum, difference and position at speeds up to 10 Hz with standard EPICS scan times. For the data values the analog input records use asynInt32Average device support, which averages all callback readings between record processing. The driver also does callbacks for these same values on the asynFloat64 interface, which is required by the fast feedback device support for the EPID record. It also does asynInt32Array callbacks with an array for each of the 11 values (Current1 to Position34), which is required by the drvFastSweep driver for time-series data.

Records in quadEM.template
drvInfo string EPICS record name EPICS record type asyn interface Access Description
QE_ACQUIRE $(P)$(R)Acquire bo asyInt32 r/w Acquire command. This command turns acquisition on (1) and off (0).
QE_RANGE $(P)$(R)Range mbbo asyInt32 r/w Range command. This selects the feedback capacitor, which controls the gain of the device. There are 8 capacitor choices. For the AH401B the choices are in units of saturation charge:
  • 1800 pC
  • 350 pC
  • 300 pC
  • 250 pC
  • 200 pC
  • 150 pC
  • 100 pC
  • 50 pC
For the APS_EM the choices are in units of capacitance:
  • External
  • 17.6 pf
  • 8.80 pF
  • 5.87 pF
  • 4.40 pF
  • 3.52 pF
  • 2.93 pF
  • 2.51 pF
On the APS_EM all gains except the first External gain use capacitors that are built in to the Burr Brown chip. These are quite small capacitors and only cover a narrow range, so the gains are quite high, and only rather low currents can be measured with them, even at the shortest integration times. The external capacitors can be replaced to select the first gain, and boards are normally built with 220 pF external capacitors. At APS 13-ID we have used much larger values, 1000 to 5000 pF, because the currents from our undulator beam position monitor are large. There are actually 8 external capacitors: 4 of them control the gain for each input for the "ping" channel, and the other 4 control the gain for the "pong" channel. By using one capacitor value for the 4 diodes on the ping channel and a different capacitor value for the 4 diodes on the pong channel, then two user-selectable gains are available. One must then select the appropriate channel in the PingPong record, and not use the average.
QE_PING_PONG $(P)$(R)PingPong mbbo asyInt32 r/w Both the AH401B and the APS_EM have 2 input channels, which we call Ping and Pong here. This doubles the speed of the unit, because one channel is being digitized while the other is integrating. This record selects how the two channels are treated.
On the AH401B the choices are "Off" (0) and "On" (1). "Off" only returns the data from the Ping channel. This reduces noise because only a single integration capacitor is used, but it reduces the data rate by a factor of two, because data are only returned on every other integration time. "On" returns the data from both channels, which doubles the data rate at some expense in noise.
On the APS_EM both values are always transmitted from the device, and the choices are #1 (Ping), #2 (Pong), and Avg. which averages the values from the Ping and Pong channels. Note that if Range=External and the two external capacitors are different, then one should not use Avg. because that will mix data from two different gains.
QE_INTEGRATION_TIME $(P)$(R)IntegrationTime ao asynFloat64 r/w Selects the integration time of the amplifier. As the integration time is increased the sensitivity increases, but the number of readings/sec sent from the device is decreased.
For the AH401B values range from 0.001s to 1.000s. The data are sent after one integration time if PingPong="On" or after 2 integration times if PingPong="Off".
For the APS_EM the values range from .000615s to 0.1311s. The data are sent to the VME card from the amplifier after 2 integration times, one value in the Ping channel and one value in the Pong channel. The data period is thus 0.00123 to 0.02622 s, or a frequency range of about 813 Hz to 38.1 Hz.
QE_SAMPLE_TIME $(P)$(R)SampleTime_RBV ai asynFloat64 r/w Contains the actual time between sample readings from the device. This is controlled by the value of IntegrationTime, and for the AH401B also by the value of PingPong.
QE_TRIGGER $(P)$(R)Trigger bo asynInt32 r/w Controls whether acquistion is free-running ("No") or triggered by an external pulse ("Yes"). This is only supported on the AH401B, the APS_EM does not support external triggering.
QE_RESET $(P)$(R)Reset bo asyInt32 r/w Reset command. Processing this record will reset the electrometer. On the APS_EM this operation takes about 1 second, and may be required to establish communication if the amplifier unit is power-cycled or disconnected and reconnected. On the AH401B this operation downloads all of the EPICS settings to the electrometer, and must be done if the electrometer is power-cycled without rebooting the EPICS IOC.
QE_CURRENT_OFFSET $(P)$(R)CurrentOffset[1-4] ao asynInt32 (addr=0-3) r/w Offset that will be subtracted from each reading before calculating the Current[1-4].
QE_POSITION_OFFSET $(P)$(R)PositionOffset[12,34] ao asynInt32 (addr=0-1) r/w Offset that will be subtracted from the computed position.
QE_POSITION_SCALE $(P)$(R)PositionScale[12,34] ao asynInt32 (addr=0-1) r/w Scale factor used when computing the position.
QE_DATA $(P)$(R)Current[1-4] ai asynInt32 (addr=0-3) r/o The value of the current. This is calculated as measuredValue-CurrentOffset. These records use asynInt32Average device support so they average the readings from the device since the time the record was last processed. For example with the AH401B if PingPong="On" and the integration time is 0.002s (500 Hz), if the Read record .SCAN field is 1 second then 500 readings will be averaged.
QE_DATA $(P)$(R)Sum[12,34,1234] ai asynInt32 (addr=4-6) r/o The sum of diodes 1+2, 3+4, and 1+2+3+4. These records use asynInt32Average device support so they average the readings from the device since the time the record was last processed.
QE_DATA $(P)$(R)Diff[12,34] ai asynInt32 (addr=7-8) r/o The difference of the diode pair 2-1 and 4-3. These records use asynInt32Average device support so they average the readings from the device since the time the record was last processed.
QE_DATA $(P)$(R)Position[12,34] ai asynInt32 (addr=9-10) r/o The position of the diode pair. This is calculated as ((Diff/Sum)*PositionScale - PositionOffset). These records use asynInt32Average device support so they average the readings from the device since the time the record was last processed.
QE_DOUBLE_DATA N.A. N.A. asynFloat64 (addr=0-10) r/o The QE_DOUBLE_DATA drvInfo string is used to read the same information as QE_DATA, but using the asynFloat64 interface rather than the asynInt32 interface. This is provided to support the fast feedback device support for the EPID record, which is provided in the synApps "std" module. That device support expects callbacks on the asynFloat64 interface for its input data.
N.A. $(P)$(R)Read ai N.A. r/w Processing this record reads all of the Position, Sum, Diff, and Position records using forward links.

This is the medm screen to control the quadEM with the records in quadEM.template.

quadEM.adl

quadEM.png

quadEM_TimeSeries.template

The quadEM_TimeSeries.template database provides a time-history (like a digital scope) of the current, sum, difference and position at speeds up to 1000Hz (AH401B) or 813 Hz (APS_EM). The time per point can be greater than the sampling time, in which case it does averaging. It also optionally uses FFTs to compute the frequency power-spectrum of each signal. The time-series support requires the drvFastSweep driver from the synApps mca module, and also the quadEM_SNL SNL program in this quadEM module. The time-series and frequency spectra are contained in standard EPICS waveform records.

Records in quadEM_TimeSeries.template
EPICS record name EPICS record type Description
$(P)$(R)SNL_Connected bi Indicates whether the SNL program has successfully connected to all required records in quadEM_TimeSeries.template.
$(P)$(R)EraseAll bo Erases all time-series waveform records.
$(P)$(R)EraseStart bo Erases and starts time series data acquisition.
$(P)$(R)StartAll bo Starts all the MCA records without erasing them first.
$(P)$(R)StopAll bo Stops time-series data acquisition.
$(P)$(R)Acquiring bo Stops time-series data acquisition.
$(P)$(R)MaxChannels longin The maximum number of time-series points that can be acquired. Controlled by the value specified when the quadEM_TimeSeries.template file and quadEM_SNL SNL program were loaded.
$(P)$(R)NuseAll longout Controls the number of time-series points to acquire before acquisition stops automatically.
$(P)$(R)CurrentChannel longin The current time-series data point being acquired.
$(P)$(R)ReadAll bo Forces all the time-series waveform records to process and read the current time-series data. This record can be periodically processed to read the time=series data as it is being acquired. Even if this record is Passive the time-series data will be read once when time-series data acquisition is complete.
$(P)$(R)Dwell ao The dwell time per point. This time is constrained to be an integer multiple of the sampling time, which is in the range 0.001s to 1.0s for the AH401B and 0.00123s to 0.002622s for the APS_EM, depending on the IntegrationTime record. The readback value of $(P)$(R)Dwell_RBV gives the actual dwell time per point.
$(P)$(R)Dwell_RBV ai The actual dwell time per point, which may differ from Dwell, because the time per point is constrained to be a multiple of the sampling time.
$(P)$(R)ElapsedReal ao The elapsed real time since time-series data acquisition started.
$(P)$(R)PresetReal dfanout The preset real time. Time-series acquisition will stop if this value is reached. If this value is 0 then there is no preset real time.
$(P)$(R)AutoRestartTS bo Controls whether time-series data acquisition is automatically restarted as soon as it completes. Choices are "No" and "Yes". This can be useful for producing a continuously updating display of frequency power-spectra, for example.
$(P)$(R)Current[1-4]TS waveform The time-series values for the diode currents.
$(P)$(R)Sum[12,34,1234]TS waveform The time-series values for the diode sums.
$(P)$(R)Diff[12,34]TS waveform The time-series values for the diode sums.
$(P)$(R)Position[12,34]TS waveform The time-series values for the diode positions.
$(P)$(R)TimeAxis waveform An array of the times for the x-axis of time series plots.
$(P)$(R)ComputeFFT bo Controls whether FFTs power-spectra are computed when time-series data acquisition completes. Choices are "No" and "Yes". The FFT calculations are done in the SNL program using the Numerical Recipes "four1" function.
$(P)$(R)Current[1-4]FFT waveform The frequency power-spectra for the diode currents.
$(P)$(R)Sum[12,34,1234]FFT waveform The frequency power-spectra for the diode sums.
$(P)$(R)Diff[12,34]FFT waveform The frequency power-spectra for the diode sums.
$(P)$(R)Position[12,34]FFT waveform The frequency power-spectra for the diode positions.
$(P)$(R)FreqAxis waveform An array of the frequencies for the x-axis of frequency power-spectrum plots.
$(P)$(R)EnableClientWait bo A flag to control whether time-series data acquisition waits for a client to reset the ClientWait record.
$(P)$(R)ClientWait busy A busy record which a client must set back to 0 to enable time-series data acquisition to continue if EnableClientWait is "Enable".

This is the medm screen to control the records in quadEM_TimeSeries.template.

quadEM_TimeSeries.adl

quadEM_TimeSeries.png

This is the medm screen for the first 2 channels. It contains the currents, sum and position as a function of time. The dwell time was 0.002s, and there are 2048 channels (time points), so the total time is 4.096 seconds.

quadEM_PlotAll.adl

quadEM_TimeSeriesPlot.png

This is an medm screen that displays the FFTs of the Current, Sum, and Position for the time-series data above.

quadEM_plotAll.adl

quadEM_FFTPlot.png

fast_pid_control.db

The quadEM can be used to do fast feedback with the EPID record from the synApps "std" module. The EPID record will process at up to 1000 Hz (AH401B) or 813 Hz (APS_EM). The DT field of the EPID record controls the time between feedback calculations, and this is constrained to be an integer multiple N of the quadEM sampling time. If N>1 then N samples are averaged for each feedback operation.

This is the medm screen that controls the fast feedback of the pitch of the monochromator on APS beamline 13-ID. The readback and control PVs cannot be changed after iocInit. The update rate (SCAN rate of EPID record) only controls the rate at which the EPID record displays "snapshots" of the values of the input, output, and error. It does not affect the rate at which the feedback is actually being done, which is controlled by the DT field in the EPID record, can be much faster than the SCAN value.

pid_control.adl

quadEM_pid_control.png

This is the medm screen that controls the PID parameters. These include the feedback coefficients KP, KI, and KD. The DT (delta time) field controls the rate at which the feedback is actually been run. In this case DT=68.0 ms, which is 55 times longer than the sampling time (1.23 ms), so 55 position readings are being averaged each time the feedback is run.

pid_parameters.adl

quadEM_pid_parameters.png

This is an medm screen that displays the setpoint of the pitch of the monochromator (in red), and the actual readback from the quadEM (in blue). Note that the readback here is only the snapshot values from the EPID record. For full-speed readings of the readback the waveform records from the quadEM_TimeSeries.template database would be used.

pid_plot_readback.adl

quadEM_plot_readback.png

This is pid_fast.template, an example substitutions file. This example uses a quadEM asyn port driver named "APS_EM". ICHAN is set to read from addr=9 and 10, which are the two position values of the quadEM driver. The INPUT_DATA and INPUT_INTERVAL strings are the drvInfo strings for these parameters in the driver. The output is sent to an asyn port driver named DAC1, which is a dac128V 12-bit A/D converter in this data. OCHAN is set to write to addr=1 and 2, which are the second and third DAC channels on that card. The OUTPUT_DATA string is the drvInfo string for the double precision data in the dac128V.

file "$(STD)/stdApp/Db/fast_pid_control.db"
{
pattern
{P,                 PID,  INPUT,     INPUT_DATA,   INPUT_INTERVAL, ICHAN, OUTPUT, OCHAN,  OUTPUT_DATA,    LOPR,     HOPR,  DRVL,  DRVH,  PREC,   KP,    KI,  KD,   DT,        SCAN}
{quadEMTest:, MonoPitch, APS_EM, QE_DOUBLE_DATA,   QE_SAMPLE_TIME,     9,   DAC1,     1,  DOUBLE_DATA,  -32767,    32767,     0,  4095,     3,  .02,  100.,  0., .001, ".1 second"}
{quadEMTest:,  MonoRoll, APS_EM, QE_DOUBLE_DATA,   QE_SAMPLE_TIME,    10,   DAC1,     2,  DOUBLE_DATA,  -32767,    32767,     0,  4095,     3,  .02,  100.,  0., .001, ".1 second"}
}

AH401B Setup

The AH401B communicates via TCP/IP, so it must be configured with an IP address reachable from the host IOC machine.

An example startup script for Linux (or Windows) is provided in quadEM/iocBoot/iocTest.st.cmd.linux. This will need to be edited to set the correct IP address of the AH401B to be used.

APS Electrometer Setup

The APS_EM VME card cannot generate interrupts, but it can output a TTL pulse each time new data is available, at up to 815 Hz. If this pulse is input to an Ip-Unidig (or other asyn digital I/O device with interrupt and callback capabilities), then the ipUnidig interrupt routine will call the APS_EM driver each time new data is available. The Ip-Unidig channel where the APS_EM pulse is connected is specified in the unidigChan argument to drvAPS_EMConfigure command in the startup script. If an Ip-Unidig or other interrupt source is not being used then the APS_EM driver will poll for new data at the system clock rate, typically 60Hz.

An example startup script for vxWorks with the APS_EM is provided in quadEM/iocBoot/iocTest.st.cmd.vxWorks. This example startup script actually starts both an AH401B ($(R)=QE1:) and an APS_EM ($(R)=QE2:) driver. One or the other can be commented out for testing if both devices are not available.