From d76ddadf55b29e1a95fdddec0f34ba38aae96c52 Mon Sep 17 00:00:00 2001 From: MPIBR-kretschmerf Date: Fri, 17 Feb 2017 10:18:02 +0100 Subject: [PATCH] Disabled NIDAQ input/output on pause and enabled recording of camera exposure trigger --- NIDAQmxInterface.cpp | 215 +++++++++++++++++++------------------ NIDAQmxInterface.h | 2 + StateMachineController.cpp | 27 +++-- StateMachineController.h | 1 + 4 files changed, 131 insertions(+), 114 deletions(-) diff --git a/NIDAQmxInterface.cpp b/NIDAQmxInterface.cpp index d44a7cc..8da8852 100644 --- a/NIDAQmxInterface.cpp +++ b/NIDAQmxInterface.cpp @@ -31,8 +31,8 @@ void NIDAQmxInterface::DAQmxInitializeInterface() /* configure digital read task */ DAQmxErrChk(DAQmxCreateTask("DigIn", &daq->di_port)); DAQmxErrChk(DAQmxCreateDIChan(daq->di_port, "Dev1/port0", "", DAQmx_Val_ChanForAllLines)); - //DAQmxErrChk(DAQmxCfgChangeDetectionTiming(daq->di_port, "Dev1/port0/line2,Dev1/port0/line3,Dev1/port0/line6", "Dev1/port0/line2,Dev1/port0/line3,Dev1/port0/line6", DAQmx_Val_ContSamps, 1)); - DAQmxErrChk(DAQmxCfgChangeDetectionTiming(daq->di_port, "Dev1/port0/line2,Dev1/port0/line6", "Dev1/port0/line2,Dev1/port0/line6", DAQmx_Val_ContSamps, 1)); + DAQmxErrChk(DAQmxCfgChangeDetectionTiming(daq->di_port, "Dev1/port0/line2,Dev1/port0/line3,Dev1/port0/line6", "Dev1/port0/line2,Dev1/port0/line3,Dev1/port0/line6", DAQmx_Val_ContSamps, 1)); + //DAQmxErrChk(DAQmxCfgChangeDetectionTiming(daq->di_port, "Dev1/port0/line2,Dev1/port0/line6", "Dev1/port0/line2,Dev1/port0/line6", DAQmx_Val_ContSamps, 1)); DAQmxErrChk(DAQmxRegisterSignalEvent(daq->di_port, DAQmx_Val_ChangeDetectionEvent, 0, inputCallbackWrapper, this)); /* configure digital write task */ @@ -182,74 +182,78 @@ void NIDAQmxInterface::DAQmxStopCustomTask(TaskHandle taskHandle) /* Trigger digital output */ void NIDAQmxInterface::DAQmxTriggerDO(uInt8 qry_port_bit, bool arm_timer) { - int32 written = 0; - bool32 done = TRUE; + if(!isPaused){ + int32 written = 0; + bool32 done = TRUE; - /* flip query bit to switch on qry bit */ - if (daq->do_port != 0) - { - daq->do_bit_wrt ^= qry_port_bit; - DAQmxErrChk(DAQmxWriteDigitalU8(daq->do_port, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->do_bit_wrt, &written, NULL)); - } + /* flip query bit to switch on qry bit */ + if (daq->do_port != 0) + { + daq->do_bit_wrt ^= qry_port_bit; + DAQmxErrChk(DAQmxWriteDigitalU8(daq->do_port, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->do_bit_wrt, &written, NULL)); + } - /* check for error */ - if (written == 0) - { - fprintf(stderr, "Error::NIDAQmxInterface/DAQmxTriggerDO:\n\tfailed to write to DO port!\n"); - exit(EXIT_FAILURE); - } + /* check for error */ + if (written == 0) + { + fprintf(stderr, "Error::NIDAQmxInterface/DAQmxTriggerDO:\n\tfailed to write to DO port!\n"); + exit(EXIT_FAILURE); + } - /* arm time out if required */ - if ((daq->do_clk != 0) & (arm_timer == TRUE)) - { + /* arm time out if required */ + if ((daq->do_clk != 0) & (arm_timer == TRUE)) + { - DAQmxErrChk(DAQmxIsTaskDone(daq->do_clk, &done)); - daq->do_bit_qry = (done) ? qry_port_bit : (daq->do_bit_qry | qry_port_bit); - DAQmxErrChk(DAQmxStopTask(daq->do_clk)); - DAQmxErrChk(DAQmxStartTask(daq->do_clk)); + DAQmxErrChk(DAQmxIsTaskDone(daq->do_clk, &done)); + daq->do_bit_qry = (done) ? qry_port_bit : (daq->do_bit_qry | qry_port_bit); + DAQmxErrChk(DAQmxStopTask(daq->do_clk)); + DAQmxErrChk(DAQmxStartTask(daq->do_clk)); + } + /* log trigger */ + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("TRIGGER", qry_port_bit, (qry_port_bit & daq->do_bit_wrt) == qry_port_bit, timeString)); } - /* log trigger */ - QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); - emit(writeToLogFile("TRIGGER", qry_port_bit, (qry_port_bit & daq->do_bit_wrt) == qry_port_bit, timeString)); return; } void NIDAQmxInterface::DAQmxSetDO(uInt8 qry_port_bit, bool arm_timer, bool isSet) { - int32 written = 0; - bool32 done = TRUE; + if(!isPaused){ + int32 written = 0; + bool32 done = TRUE; - /* flip query bit to switch on qry bit */ - if (daq->do_port != 0) - { - if(isSet){ - daq->do_bit_wrt |= (1 << (qry_port_bit-1)); - }else{ - daq->do_bit_wrt &= ~(1 << (qry_port_bit-1)); + /* flip query bit to switch on qry bit */ + if (daq->do_port != 0) + { + if(isSet){ + daq->do_bit_wrt |= (1 << (qry_port_bit-1)); + }else{ + daq->do_bit_wrt &= ~(1 << (qry_port_bit-1)); + } + DAQmxErrChk(DAQmxWriteDigitalU8(daq->do_port, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->do_bit_wrt, &written, NULL)); } - DAQmxErrChk(DAQmxWriteDigitalU8(daq->do_port, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->do_bit_wrt, &written, NULL)); - } - /* check for error */ - if (written == 0) - { - fprintf(stderr, "Error::NIDAQmxInterface/DAQmxTriggerDO:\n\tfailed to write to DO port!\n"); - exit(EXIT_FAILURE); - } + /* check for error */ + if (written == 0) + { + fprintf(stderr, "Error::NIDAQmxInterface/DAQmxTriggerDO:\n\tfailed to write to DO port!\n"); + exit(EXIT_FAILURE); + } - /* arm time out if required */ - if ((daq->do_clk != 0) & (arm_timer == TRUE)) - { - DAQmxErrChk(DAQmxIsTaskDone(daq->do_clk, &done)); - daq->do_bit_qry = (done) ? qry_port_bit : (daq->do_bit_qry | qry_port_bit); - DAQmxErrChk(DAQmxStopTask(daq->do_clk)); - DAQmxErrChk(DAQmxStartTask(daq->do_clk)); - } + /* arm time out if required */ + if ((daq->do_clk != 0) & (arm_timer == TRUE)) + { + DAQmxErrChk(DAQmxIsTaskDone(daq->do_clk, &done)); + daq->do_bit_qry = (done) ? qry_port_bit : (daq->do_bit_qry | qry_port_bit); + DAQmxErrChk(DAQmxStopTask(daq->do_clk)); + DAQmxErrChk(DAQmxStartTask(daq->do_clk)); + } - /* log trigger */ - QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); - emit(writeToLogFile("TRIGGER", qry_port_bit, (qry_port_bit & daq->do_bit_wrt) == qry_port_bit, timeString)); + /* log trigger */ + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("TRIGGER", qry_port_bit, (qry_port_bit & daq->do_bit_wrt) == qry_port_bit, timeString)); + } return; } @@ -257,48 +261,48 @@ void NIDAQmxInterface::DAQmxSetDO(uInt8 qry_port_bit, bool arm_timer, bool isSet /* Detect Input Callback */ int32 CVICALLBACK NIDAQmxInterface::FcnCbckDetectDI(TaskHandle taskHandle, int32 signalID) { - //DAQmxEngine *daq = (DAQmxEngine *)callbackData; + if(!isPaused){ + int32 read = 0; + if (taskHandle != 0) + DAQmxErrChk(DAQmxReadDigitalU8(taskHandle, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->di_bit_now, 1, &read, NULL)); - int32 read = 0; - if (taskHandle != 0) - DAQmxErrChk(DAQmxReadDigitalU8(taskHandle, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->di_bit_now, 1, &read, NULL)); + if (read) + { - if (read) - { + /* FRAME condition, line 2 changes from 1 to 0 */ + if (((daq->di_bit_prev & DAQ_PORT_DI_FRAME) == DAQ_PORT_DI_FRAME) & ((daq->di_bit_now & DAQ_PORT_DI_FRAME) == DAQ_PORT_NULL)) + { + daq->di_cntr_frame++; + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("FRAME", daq->di_cntr_imaq, daq->di_cntr_frame, timeString)); + } - /* FRAME condition, line 2 changes from 1 to 0 */ - if (((daq->di_bit_prev & DAQ_PORT_DI_FRAME) == DAQ_PORT_DI_FRAME) & ((daq->di_bit_now & DAQ_PORT_DI_FRAME) == DAQ_PORT_NULL)) - { - daq->di_cntr_frame++; - QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); - emit(writeToLogFile("FRAME", daq->di_cntr_imaq, daq->di_cntr_frame, timeString)); - } + /* LICK condition, line 6 changes from 0 to 1 */ + if (((daq->di_bit_prev & DAQ_PORT_DI_LICK) == DAQ_PORT_NULL) & ((daq->di_bit_now & DAQ_PORT_DI_LICK) == DAQ_PORT_DI_LICK)) + { + daq->di_cntr_lick++; + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("LICK", DAQ_PORT_DI_LICK, daq->di_cntr_lick, timeString)); + + /* every N licks give a reward */ + if ((daq->di_cntr_lick % licksToReward) == 0){ + DAQmxTriggerDO(DAQ_PORT_DO_WATER, TRUE); + qDebug()<<"Water reward!"; + } - /* LICK condition, line 6 changes from 0 to 1 */ - if (((daq->di_bit_prev & DAQ_PORT_DI_LICK) == DAQ_PORT_NULL) & ((daq->di_bit_now & DAQ_PORT_DI_LICK) == DAQ_PORT_DI_LICK)) - { - daq->di_cntr_lick++; - QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); - emit(writeToLogFile("LICK", DAQ_PORT_DI_LICK, daq->di_cntr_lick, timeString)); - - /* every N licks give a reward */ - if ((daq->di_cntr_lick % licksToReward) == 0){ - DAQmxTriggerDO(DAQ_PORT_DO_WATER, TRUE); - qDebug()<<"Water reward!"; } - } + /* CAMERATRIGGER condition, line 3 changes from 1 to 0 */ + if (((daq->di_bit_prev & DAQ_PORT_DI_CAMERATRIGGER) == DAQ_PORT_DI_CAMERATRIGGER) & ((daq->di_bit_now & DAQ_PORT_DI_CAMERATRIGGER) == DAQ_PORT_NULL)) + { + daq->di_cntr_cameraTrigger++; + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("CAMERATRIGGER", DAQ_PORT_DI_CAMERATRIGGER, daq->di_cntr_cameraTrigger, timeString)); + } - /* CAMERATRIGGER condition, line 7 changes from 1 to 0 */ - if (((daq->di_bit_prev & DAQ_PORT_DI_CAMERATRIGGER) == DAQ_PORT_DI_CAMERATRIGGER) & ((daq->di_bit_now & DAQ_PORT_DI_CAMERATRIGGER) == DAQ_PORT_NULL)) - { - daq->di_cntr_cameraTrigger++; - QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); - emit(writeToLogFile("CAMERATRIGGER", DAQ_PORT_DI_CAMERATRIGGER, daq->di_cntr_cameraTrigger, timeString)); + /* update bit history */ + daq->di_bit_prev = daq->di_bit_now; } - - /* update bit history */ - daq->di_bit_prev = daq->di_bit_now; } return 0; @@ -307,26 +311,25 @@ int32 CVICALLBACK NIDAQmxInterface::FcnCbckDetectDI(TaskHandle taskHandle, int32 /* Timer Digital Out is Done */ int32 CVICALLBACK NIDAQmxInterface::FcnCbckTriggerStopDO(TaskHandle taskHandle, int32 signalID) { - //DAQmxEngine *daq = (DAQmxEngine *)callbackData; + if(!isPaused){ + int32 written = 0; + /* flip query bit, to switch off pulse */ + if (daq->do_port != 0) + { + daq->do_bit_wrt ^= daq->do_bit_qry; + DAQmxErrChk(DAQmxWriteDigitalU8(daq->do_port, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->do_bit_wrt, &written, NULL)); + } - int32 written = 0; - /* flip query bit, to switch off pulse */ - if (daq->do_port != 0) - { - daq->do_bit_wrt ^= daq->do_bit_qry; - DAQmxErrChk(DAQmxWriteDigitalU8(daq->do_port, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->do_bit_wrt, &written, NULL)); - } + /* check for error */ + if (written == 0) + { + fprintf(stderr, "Error::NIDAQmxInterface/FcnCbckTriggerStopDO: failed to write to DO port!\n"); + exit(EXIT_FAILURE); + } - /* check for error */ - if (written == 0) - { - fprintf(stderr, "Error::NIDAQmxInterface/FcnCbckTriggerStopDO: failed to write to DO port!\n"); - exit(EXIT_FAILURE); + /* log trigger */ + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("TRIGGER", daq->do_bit_qry, (daq->do_bit_qry & daq->do_bit_wrt) == daq->do_bit_qry, timeString)); } - - /* log trigger */ - QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); - emit(writeToLogFile("TRIGGER", daq->do_bit_qry, (daq->do_bit_qry & daq->do_bit_wrt) == daq->do_bit_qry, timeString)); - return 0; } diff --git a/NIDAQmxInterface.h b/NIDAQmxInterface.h index e5eb867..dc11cfd 100644 --- a/NIDAQmxInterface.h +++ b/NIDAQmxInterface.h @@ -74,6 +74,8 @@ class NIDAQmxInterface: public QObject const double DO_PULSE_WIDTH = 0.08;// in seconds int licksToReward = 16; + bool isPaused = false; //ignore input/output when true + explicit NIDAQmxInterface(QObject *parent = 0); /* function prototypes */ void DAQmxInitializeInterface(); diff --git a/StateMachineController.cpp b/StateMachineController.cpp index e064f52..02170be 100644 --- a/StateMachineController.cpp +++ b/StateMachineController.cpp @@ -59,7 +59,11 @@ StateMachineController::StateMachineController(QObject *parent): connect(state_acquisitionBaseline, SIGNAL(entered()), this, SLOT(onStateAcquisitionBaselineEntered())); // state sound connect(state_sound, SIGNAL(entered()), this, SLOT(onStateSoundEntered())); + + + /*Connect pause signals*/ connect(pausedState, SIGNAL(entered()), this, SLOT(onStatePauseEntered())); + connect(pausedState, SIGNAL(exited()), this, SLOT(onStatePauseExited())); nidaq = new NIDAQmxInterface(); @@ -91,7 +95,7 @@ StateMachineController::StateMachineController(QObject *parent): logFileThread->start(); }else{ QMessageBox messageBox; - messageBox.critical(0,"Error","Unable to initialize TDT audio interface!"); + messageBox.critical(0,"Error","Unable to initialize TDT audio interface!\nYou will not be able to use this device."); } @@ -178,7 +182,7 @@ void StateMachineController::onStateUserReactionEntered() timerDialog->show(); timerDialog->startTimer(); - qDebug()<< "Starting user reaction"; + qDebug() << "Starting user reaction"; emit(statusMessage("Starting user reaction")); mainTimer->setInterval(settings.userReaction * 1000); @@ -187,13 +191,13 @@ void StateMachineController::onStateUserReactionEntered() void StateMachineController::onStateUserReactionExited() { - qDebug()<<"Triggering microscope"; + qDebug() << "Triggering microscope"; nidaq->DAQmxTriggerDO(NIDAQmxInterface::DAQ_PORT_DO_IMGAQ, true); } void StateMachineController::onStateAcquisitionBaselineEntered() { - qDebug()<< "Starting baseline"; + qDebug() << "Starting baseline"; emit(statusMessage("Starting baseline")); mainTimer->setInterval(settings.preImaq * 1000); mainTimer->start(); @@ -201,7 +205,7 @@ void StateMachineController::onStateAcquisitionBaselineEntered() void StateMachineController::onStateSoundEntered() { - qDebug()<< "Loading sound"; + qDebug() << "Loading sound"; int soundType = settings.trialSequence.first(); settings.trialSequence.pop_front(); @@ -219,11 +223,11 @@ void StateMachineController::onStateSoundEntered() break; } - qDebug()<< "Starting sound"; + qDebug() << "Starting sound"; emit(statusMessage("Starting sound")); mainTimer->start(); nidaq->DAQmxTriggerDO(NIDAQmxInterface::DAQ_PORT_DO_SOUND, true); - qDebug()<< "Finished sound"; + qDebug() << "Finished sound"; emit(statusMessage("Finished sound")); // go to next trial if(trialsCurrent < trialsTotal) { @@ -245,7 +249,14 @@ void StateMachineController::onStateSoundEntered() void StateMachineController::onStatePauseEntered() { - qDebug()<<"Pause state entered"; + qDebug() << "Pause state entered"; mainTimer->stop(); + nidaq->isPaused = true; timerDialog->removeTimer(); } + +void StateMachineController::onStatePauseExited() +{ + nidaq->isPaused = false; + qDebug() << "Pause state exited"; +} diff --git a/StateMachineController.h b/StateMachineController.h index 03ef2ff..743e43f 100644 --- a/StateMachineController.h +++ b/StateMachineController.h @@ -62,6 +62,7 @@ private slots: void onStateAcquisitionBaselineEntered(); void onStateSoundEntered(); void onStatePauseEntered(); + void onStatePauseExited(); signals: