void ANDOR885_Camera::setAcquisitionMode(int aMode) throw(std::exception) { int errorValue; // Kinetic series can only be used with external acquisition modes if (aMode == ACQMODE_KINETIC_SERIES && triggerMode == TRIGGERMODE_INTERNAL) { setTriggerMode(TRIGGERMODE_EXTERNAL_EXPOSURE); } errorValue = SetAcquisitionMode(aMode); throwError(errorValue, "Error setting acquisition mode"); acquisitionMode = aMode; }
/** Downloads all of the current EPICS settings to the electrometer. * Typically used after the electrometer is power-cycled. */ asynStatus drvQuadEM::reset() { epicsInt32 iValue; epicsFloat64 dValue; getIntegerParam(P_Range, &iValue); setRange(iValue); getIntegerParam(P_ValuesPerRead, &iValue); setValuesPerRead(iValue); getDoubleParam(P_AveragingTime, &dValue); setAveragingTime(dValue); getIntegerParam(P_TriggerMode, &iValue); setTriggerMode(iValue); getIntegerParam(P_NumChannels, &iValue); setNumChannels(iValue); getIntegerParam(P_BiasState, &iValue); setBiasState(iValue); getIntegerParam(P_BiasInterlock, &iValue); setBiasInterlock(iValue); getDoubleParam(P_BiasVoltage, &dValue); setBiasVoltage(dValue); getIntegerParam(P_Resolution, &iValue); setResolution(iValue); getIntegerParam(P_ReadFormat, &iValue); setReadFormat(iValue); getDoubleParam(P_IntegrationTime, &dValue); setIntegrationTime(dValue); readStatus(); getIntegerParam(P_Acquire, &iValue); setAcquire(iValue); return asynSuccess; }
/// \brief Connect general signals and device management signals. void OpenHantekMainWindow::connectSignals() { // Connect general signals connect(this, SIGNAL(settingsChanged()), this, SLOT(applySettings())); //connect(this->dsoWidget, SIGNAL(stopped()), this, SLOT(stopped())); connect(this->dsoControl, SIGNAL(statusMessage(QString, int)), this->statusBar(), SLOT(showMessage(QString, int))); connect(this->dsoControl, SIGNAL(samplesAvailable(const std::vector<std::vector<double> > *, double, bool, QMutex *)), this->dataAnalyzer, SLOT(analyze(const std::vector<std::vector<double> > *, double, bool, QMutex *))); // Connect signals to DSO controller and widget connect(this->horizontalDock, SIGNAL(samplerateChanged(double)), this, SLOT(samplerateSelected())); connect(this->horizontalDock, SIGNAL(timebaseChanged(double)), this, SLOT(timebaseSelected())); connect(this->horizontalDock, SIGNAL(frequencybaseChanged(double)), this->dsoWidget, SLOT(updateFrequencybase(double))); connect(this->horizontalDock, SIGNAL(recordLengthChanged(unsigned long)), this, SLOT(recordLengthSelected(unsigned long))); //connect(this->horizontalDock, SIGNAL(formatChanged(HorizontalFormat)), this->dsoWidget, SLOT(horizontalFormatChanged(HorizontalFormat))); connect(this->triggerDock, SIGNAL(modeChanged(Dso::TriggerMode)), this->dsoControl, SLOT(setTriggerMode(Dso::TriggerMode))); connect(this->triggerDock, SIGNAL(modeChanged(Dso::TriggerMode)), this->dsoWidget, SLOT(updateTriggerMode())); connect(this->triggerDock, SIGNAL(modeChanged(Dso::TriggerMode)), this->hardControl, SLOT(updateLEDs())); connect(this->triggerDock, SIGNAL(sourceChanged(bool, unsigned int)), this->dsoControl, SLOT(setTriggerSource(bool, unsigned int))); connect(this->triggerDock, SIGNAL(sourceChanged(bool, unsigned int)), this->dsoWidget, SLOT(updateTriggerSource())); connect(this->triggerDock, SIGNAL(sourceChanged(bool, unsigned int)), this->hardControl, SLOT(updateLEDs())); connect(this->triggerDock, SIGNAL(slopeChanged(Dso::Slope)), this->dsoControl, SLOT(setTriggerSlope(Dso::Slope))); connect(this->triggerDock, SIGNAL(slopeChanged(Dso::Slope)), this->dsoWidget, SLOT(updateTriggerSlope())); connect(this->triggerDock, SIGNAL(slopeChanged(Dso::Slope)), this->hardControl, SLOT(updateLEDs())); connect(this->dsoWidget, SIGNAL(triggerPositionChanged(double)), this->dsoControl, SLOT(setPretriggerPosition(double))); connect(this->dsoWidget, SIGNAL(triggerLevelChanged(unsigned int, double)), this->dsoControl, SLOT(setTriggerLevel(unsigned int, double))); connect(this->voltageDock, SIGNAL(usedChanged(unsigned int, bool)), this, SLOT(updateUsed(unsigned int))); connect(this->voltageDock, SIGNAL(usedChanged(unsigned int, bool)), this->dsoWidget, SLOT(updateVoltageUsed(unsigned int, bool))); connect(this->voltageDock, SIGNAL(usedChanged(unsigned int, bool)), this->hardControl, SLOT(updateLEDs())); connect(this->voltageDock, SIGNAL(couplingChanged(unsigned int, Dso::Coupling)), this->dsoControl, SLOT(setCoupling(unsigned int, Dso::Coupling))); connect(this->voltageDock, SIGNAL(couplingChanged(unsigned int, Dso::Coupling)), this->dsoWidget, SLOT(updateVoltageCoupling(unsigned int))); connect(this->voltageDock, SIGNAL(couplingChanged(unsigned int, Dso::Coupling)), this->hardControl, SLOT(updateLEDs())); connect(this->voltageDock, SIGNAL(modeChanged(Dso::MathMode)), this->dsoWidget, SLOT(updateMathMode())); connect(this->voltageDock, SIGNAL(gainChanged(unsigned int, double)), this, SLOT(updateVoltageGain(unsigned int))); connect(this->voltageDock, SIGNAL(gainChanged(unsigned int, double)), this->dsoWidget, SLOT(updateVoltageGain(unsigned int))); connect(this->dsoWidget, SIGNAL(offsetChanged(unsigned int, double)), this, SLOT(updateOffset(unsigned int))); connect(this->spectrumDock, SIGNAL(usedChanged(unsigned int, bool)), this, SLOT(updateUsed(unsigned int))); connect(this->spectrumDock, SIGNAL(usedChanged(unsigned int, bool)), this->dsoWidget, SLOT(updateSpectrumUsed(unsigned int, bool))); connect(this->spectrumDock, SIGNAL(magnitudeChanged(unsigned int, double)), this->dsoWidget, SLOT(updateSpectrumMagnitude(unsigned int))); // Started/stopped signals from oscilloscope connect(this->dsoControl, SIGNAL(samplingStarted()), this, SLOT(started())); connect(this->dsoControl, SIGNAL(samplingStarted()), this->hardControl, SLOT(started())); connect(this->dsoControl, SIGNAL(samplingStopped()), this, SLOT(stopped())); connect(this->dsoControl, SIGNAL(samplingStopped()), this->hardControl, SLOT(stopped())); //connect(this->dsoControl, SIGNAL(recordLengthChanged(unsigned long)), this, SLOT(recordLengthChanged())); connect(this->dsoControl, SIGNAL(recordTimeChanged(double)), this, SLOT(recordTimeChanged(double))); connect(this->dsoControl, SIGNAL(samplerateChanged(double)), this, SLOT(samplerateChanged(double))); connect(this->dsoControl, SIGNAL(availableRecordLengthsChanged(QList<unsigned int>)), this->horizontalDock, SLOT(availableRecordLengthsChanged(QList<unsigned int>))); connect(this->dsoControl, SIGNAL(samplerateLimitsChanged(double, double)), this->horizontalDock, SLOT(samplerateLimitsChanged(double, double))); // Hard Events connect(this->hardControl, SIGNAL(new_event(int, int)), this, SLOT(hard_event(int, int))); connect(this->hardControl, SIGNAL(new_event(int, int)), this->dsoWidget, SLOT(hard_event(int, int))); connect(this->hardControl, SIGNAL(new_event(int, int)), this->horizontalDock, SLOT(hard_event(int, int))); connect(this->hardControl, SIGNAL(new_event(int, int)), this->triggerDock, SLOT(hard_event(int, int))); connect(this->hardControl, SIGNAL(new_event(int, int)), this->voltageDock, SLOT(hard_event(int, int))); }
/** Called when asyn clients call pasynInt32->write(). * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus drvQuadEM::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; int status = asynSuccess; int channel; const char *paramName; const char* functionName = "writeInt32"; getAddress(pasynUser, &channel); /* Set the parameter in the parameter library. */ status |= setIntegerParam(channel, function, value); /* Fetch the parameter string name for possible use in debugging */ getParamName(function, ¶mName); if (function == P_Acquire) { if (value) { epicsRingBytesFlush(ringBuffer_); ringCount_ = 0; } status |= setAcquire(value); } else if (function == P_AcquireMode) { if (value != QEAcquireModeContinuous) { status |= setAcquire(0); setIntegerParam(P_Acquire, 0); } status |= setAcquireMode(value); status |= readStatus(); } else if (function == P_BiasState) { status |= setBiasState(value); status |= readStatus(); } else if (function == P_BiasInterlock) { status |= setBiasInterlock(value); status |= readStatus(); } else if (function == P_NumChannels) { status |= setNumChannels(value); status |= readStatus(); } else if (function == P_NumAcquire) { status |= setNumAcquire(value); status |= readStatus(); } else if (function == P_PingPong) { status |= setPingPong(value); status |= readStatus(); } else if (function == P_Range) { status |= setRange(value); status |= readStatus(); } else if (function == P_ReadData) { status |= doDataCallbacks(); } else if (function == P_Resolution) { status |= setResolution(value); status |= readStatus(); } else if (function == P_TriggerMode) { status |= setTriggerMode(value); status |= readStatus(); } else if (function == P_ValuesPerRead) { valuesPerRead_ = value; status |= setValuesPerRead(value); status |= readStatus(); } else if (function == P_ReadFormat) { status |= setReadFormat(value); status |= readStatus(); } else if (function == P_ReadStatus) { // We don't do this if we are acquiring, too disruptive if (!acquiring_) { status |= readStatus(); } } else if (function == P_Reset) { status |= reset(); status |= readStatus(); } else { /* All other parameters just get set in parameter list, no need to * act on them here */ } /* Do callbacks so higher layers see any changes */ status |= (asynStatus) callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=%d", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=%d\n", driverName, functionName, function, paramName, value); return (asynStatus)status; }
//////////////////////////////////////////////////////////////////////////////// // class OpenHantekMainWindow /// \brief Initializes the gui elements of the main window. /// \param parent The parent widget. /// \param flags Flags for the window manager. OpenHantekMainWindow::OpenHantekMainWindow(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) { // Set application information QCoreApplication::setOrganizationName("paranoiacs.net"); QCoreApplication::setOrganizationDomain("paranoiacs.net"); QCoreApplication::setApplicationName("OpenHantek"); // Window title this->setWindowIcon(QIcon(":openhantek.png")); this->setWindowTitle(tr("OpenHantek")); // Create the controller for the oscilloscope, provides channel count for settings /* this->dsoControl = new Hantek::Control(); if (!this->dsoControl->deviceFound()) { // no Hantek scope found, try to find Buudai/SainSmart scopes... qDebug() << "No Hantek scope found, looking for Buudai scopes now..."; delete this->dsoControl; this->dsoControl = new Buudai::Control(); } */ this->dsoControl = new Buudai::Control(); // Application settings this->settings = new DsoSettings(); this->settings->setChannelCount(this->dsoControl->getChannelCount()); this->readSettings(); // Create dock windows before the dso widget, they fix messed up settings this->createDockWindows(); // The data analyzer this->dataAnalyzer = new DataAnalyzer(this->settings); // Central oscilloscope widget this->dsoWidget = new DsoWidget(this->settings, this->dataAnalyzer); this->setCentralWidget(this->dsoWidget); // Subroutines for window elements this->createActions(); this->createToolBars(); this->createMenus(); this->createStatusBar(); // Apply the settings after the gui is initialized this->applySettings(); // Update stored window size and position this->settings->options.window.position = this->pos(); this->settings->options.window.size = this->size(); // Connect general signals connect(this, SIGNAL(settingsChanged()), this, SLOT(applySettings())); //connect(this->dsoWidget, SIGNAL(stopped()), this, SLOT(stopped())); connect(this->dsoControl, SIGNAL(statusMessage(QString, int)), this->statusBar(), SLOT(showMessage(QString, int))); connect(this->dsoControl, SIGNAL(samplesAvailable(const QList<double *> *, const QList<unsigned int> *, double, QMutex *)), this->dataAnalyzer, SLOT(analyze(const QList<double *> *, const QList<unsigned int> *, double, QMutex *))); // Connect signals to DSO controller and widget //connect(this->horizontalDock, SIGNAL(formatChanged(HorizontalFormat)), this->dsoWidget, SLOT(horizontalFormatChanged(HorizontalFormat))); connect(this->horizontalDock, SIGNAL(timebaseChanged(double)), this, SLOT(updateTimebase())); connect(this->horizontalDock, SIGNAL(timebaseChanged(double)), this->dsoWidget, SLOT(updateTimebase())); connect(this->horizontalDock, SIGNAL(frequencybaseChanged(double)), this->dsoWidget, SLOT(updateFrequencybase())); connect(this->triggerDock, SIGNAL(modeChanged(Dso::TriggerMode)), this->dsoControl, SLOT(setTriggerMode(Dso::TriggerMode))); connect(this->triggerDock, SIGNAL(modeChanged(Dso::TriggerMode)), this->dsoWidget, SLOT(updateTriggerMode())); connect(this->triggerDock, SIGNAL(sourceChanged(bool, unsigned int)), this->dsoControl, SLOT(setTriggerSource(bool, unsigned int))); connect(this->triggerDock, SIGNAL(sourceChanged(bool, unsigned int)), this->dsoWidget, SLOT(updateTriggerSource())); connect(this->triggerDock, SIGNAL(slopeChanged(Dso::Slope)), this->dsoControl, SLOT(setTriggerSlope(Dso::Slope))); connect(this->triggerDock, SIGNAL(slopeChanged(Dso::Slope)), this->dsoWidget, SLOT(updateTriggerSlope())); connect(this->dsoWidget, SIGNAL(triggerPositionChanged(double)), this->dsoControl, SLOT(setTriggerPosition(double))); connect(this->dsoWidget, SIGNAL(triggerLevelChanged(unsigned int, double)), this->dsoControl, SLOT(setTriggerLevel(unsigned int, double))); connect(this->voltageDock, SIGNAL(usedChanged(unsigned int, bool)), this, SLOT(updateUsed(unsigned int))); connect(this->voltageDock, SIGNAL(usedChanged(unsigned int, bool)), this->dsoWidget, SLOT(updateVoltageUsed(unsigned int, bool))); connect(this->voltageDock, SIGNAL(couplingChanged(unsigned int, Dso::Coupling)), this->dsoControl, SLOT(setCoupling(unsigned int, Dso::Coupling))); connect(this->voltageDock, SIGNAL(couplingChanged(unsigned int, Dso::Coupling)), this->dsoWidget, SLOT(updateVoltageCoupling(unsigned int))); connect(this->voltageDock, SIGNAL(modeChanged(Dso::MathMode)), this->dsoWidget, SLOT(updateMathMode())); connect(this->voltageDock, SIGNAL(gainChanged(unsigned int, double)), this, SLOT(updateVoltageGain(unsigned int))); connect(this->voltageDock, SIGNAL(gainChanged(unsigned int, double)), this->dsoWidget, SLOT(updateVoltageGain(unsigned int))); connect(this->dsoWidget, SIGNAL(offsetChanged(unsigned int, double)), this, SLOT(updateOffset(unsigned int))); connect(this->spectrumDock, SIGNAL(usedChanged(unsigned int, bool)), this, SLOT(updateUsed(unsigned int))); connect(this->spectrumDock, SIGNAL(usedChanged(unsigned int, bool)), this->dsoWidget, SLOT(updateSpectrumUsed(unsigned int, bool))); connect(this->spectrumDock, SIGNAL(magnitudeChanged(unsigned int, double)), this->dsoWidget, SLOT(updateSpectrumMagnitude(unsigned int))); // Started/stopped signals from oscilloscope connect(this->dsoControl, SIGNAL(samplingStarted()), this, SLOT(started())); connect(this->dsoControl, SIGNAL(samplingStopped()), this, SLOT(stopped())); // Set up the oscilloscope this->dsoControl->connectDevice(); for(unsigned int channel = 0; channel < this->settings->scope.physicalChannels; channel++) { this->dsoControl->setCoupling(channel, (Dso::Coupling) this->settings->scope.voltage[channel].misc); this->updateVoltageGain(channel); this->updateOffset(channel); this->dsoControl->setTriggerLevel(channel, this->settings->scope.voltage[channel].trigger); } this->updateUsed(this->settings->scope.physicalChannels); this->dsoControl->setBufferSize(this->settings->scope.horizontal.samples); this->updateTimebase(); this->dsoControl->setTriggerMode(this->settings->scope.trigger.mode); this->dsoControl->setTriggerPosition(this->settings->scope.trigger.position * this->settings->scope.horizontal.timebase * DIVS_TIME); this->dsoControl->setTriggerSlope(this->settings->scope.trigger.slope); this->dsoControl->setTriggerSource(this->settings->scope.trigger.special, this->settings->scope.trigger.source); this->dsoControl->startSampling(); }
ANDOR885_Camera::ANDOR885_Camera() { debugging = false; initialized = false; notDestructed = false; extension = ".tif"; eventMetadata = NULL; pauseCameraMutex = new omni_mutex(); pauseCameraCondition = new omni_condition(pauseCameraMutex); stopEventMutex = new omni_mutex(); stopEventCondition = new omni_condition(stopEventMutex); stopEvent = false; numAcquiredMutex = new omni_mutex(); numAcquiredCondition = new omni_condition(numAcquiredMutex); waitForEndOfAcquisitionMutex = new omni_mutex(); waitForEndOfAcquisitionCondition = new omni_condition(waitForEndOfAcquisitionMutex); waitForCleanupEventMutex = new omni_mutex(); waitForCleanupEventCondition = new omni_condition(waitForCleanupEventMutex); bool cleanupEvent = false; //Initialize necessary parameters readMode_t.name = "Read mode"; //If ever there is more than one read mode, be sure to properly initialize this for playing events! readMode_t.choices[READMODE_IMAGE] = "Image"; shutterMode_t.name = "Shutter mode"; shutterMode_t.choices[SHUTTERMODE_AUTO] = "Auto"; shutterMode_t.choices[SHUTTERMODE_OPEN] = "Open"; shutterMode_t.choices[SHUTTERMODE_CLOSE] = "Closed"; acquisitionMode_t.name = "**Acquisition mode (RTA)"; acquisitionMode_t.choices[ACQMODE_SINGLE_SCAN] = "Single scan"; acquisitionMode_t.choices[ACQMODE_KINETIC_SERIES] = "Kinetic series"; acquisitionMode_t.choices[ACQMODE_RUN_TILL_ABORT] = "Run 'til abort"; triggerMode_t.name = "**Trigger mode (EE)"; triggerMode_t.choices[TRIGGERMODE_EXTERNAL] = "External"; triggerMode_t.choices[TRIGGERMODE_EXTERNAL_EXPOSURE] = "External exposure"; triggerMode_t.choices[TRIGGERMODE_INTERNAL] = "Internal"; preAmpGain_t.name = "*Preamp Gain"; // preAmpGain_t.choices.push_back(""); // preAmpGain_t.choiceFlags.push_back(PREAMP_BLANK); preAmpGain = NOT_AVAILABLE; // preAmpGainPos = PREAMP_BLANK; verticalShiftSpeed_t.name = "*Vertical Shift Speed (us/px)"; verticalClockVoltage_t.name = "*Vertical Clock Voltage"; horizontalShiftSpeed_t.name = "*Horizontal Shift Speed (us)"; // pImageArray = NULL; cameraStat = ANDOR_ON; acquisitionMode = ACQMODE_RUN_TILL_ABORT; readMode = READMODE_IMAGE; exposureTime = (float) 0.05; // in seconds accumulateTime = 0; kineticTime = 0; ttl = TTL_OPEN_HIGH; shutterMode = SHUTTERMODE_OPEN; closeTime = SHUTTER_CLOSE_TIME; openTime = SHUTTER_OPEN_TIME; // triggerMode = TRIGGERMODE_EXTERNAL_EXPOSURE; //will be set by InitializeCamera frameTransfer = ANDOR_OFF; // spoolMode = ANDOR_OFF; coolerSetpt = -90; coolerStat = ANDOR_ON; cameraTemp = 20; EMCCDGain = NOT_AVAILABLE; verticalShiftSpeed = 0; verticalClockVoltage = 0; horizontalShiftSpeed = 0; readMode_t.initial = readMode_t.choices.find(readMode)->second; shutterMode_t.initial = shutterMode_t.choices.find(shutterMode)->second; // triggerMode_t.initial = triggerMode_t.choices.find(triggerMode)->second; acquisitionMode_t.initial = acquisitionMode_t.choices.find(acquisitionMode)->second; //Name of path to which files should be saved filePath = createFilePath(); logPath = "C:\\Documents and Settings\\EP Lab\\Desktop\\"; palPath = "C:\\Documents and Settings\\User\\My Documents\\My Pictures\\Andor_iXon\\GREY.PAL"; initialized = !InitializeCamera(); if (initialized){ notDestructed = true; omni_thread::create(playCameraWrapper, (void*) this, omni_thread::PRIORITY_HIGH); try { setExposureTime(exposureTime); setTriggerMode(triggerMode); } catch (ANDOR885_Exception& e){ std::cerr << e.printMessage() << std::endl; initialized = false; } if (debugging) { try { setAcquisitionMode(acquisitionMode); setReadMode(readMode); } catch (ANDOR885_Exception& e){ std::cerr << e.printMessage() << std::endl; initialized = false; } } } }