From c839387396b7e7ee266b61ba141a7d5e3a2f36f9 Mon Sep 17 00:00:00 2001 From: MPIBR-kretschmerf <friedrich.kretschmer@brain.mpg.de> Date: Thu, 2 Mar 2017 10:40:45 +0100 Subject: [PATCH] NIDAQ errors are logged to file and program does not quit anymore on errors --- NIDAQmxInterface.cpp | 111 +++++++++++++++++++++++++++---------------- NIDAQmxInterface.h | 2 +- 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/NIDAQmxInterface.cpp b/NIDAQmxInterface.cpp index 8da8852..0d55911 100644 --- a/NIDAQmxInterface.cpp +++ b/NIDAQmxInterface.cpp @@ -24,28 +24,28 @@ void NIDAQmxInterface::DAQmxInitializeInterface() DAQmxSetDefaultEngine(); /* configure digital read error task */ - DAQmxErrChk(DAQmxCreateTask("DigError", &daq->di_error)); - DAQmxErrChk(DAQmxCreateDIChan(daq->di_error, "Dev1/port2", "", DAQmx_Val_ChanForAllLines)); + errorCheck(DAQmxCreateTask("DigError", &daq->di_error)); + errorCheck(DAQmxCreateDIChan(daq->di_error, "Dev1/port2", "", DAQmx_Val_ChanForAllLines)); DAQmxReadErrorPort(); /* 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(DAQmxRegisterSignalEvent(daq->di_port, DAQmx_Val_ChangeDetectionEvent, 0, inputCallbackWrapper, this)); + errorCheck(DAQmxCreateTask("DigIn", &daq->di_port)); + errorCheck(DAQmxCreateDIChan(daq->di_port, "Dev1/port0", "", DAQmx_Val_ChanForAllLines)); + errorCheck(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)); + //errorCheck(DAQmxCfgChangeDetectionTiming(daq->di_port, "Dev1/port0/line2,Dev1/port0/line6", "Dev1/port0/line2,Dev1/port0/line6", DAQmx_Val_ContSamps, 1)); + errorCheck(DAQmxRegisterSignalEvent(daq->di_port, DAQmx_Val_ChangeDetectionEvent, 0, inputCallbackWrapper, this)); /* configure digital write task */ - DAQmxErrChk(DAQmxCreateTask("DigOut", &daq->do_port)); - DAQmxErrChk(DAQmxCreateDOChan(daq->do_port, "Dev1/port1", "", DAQmx_Val_ChanForAllLines)); + errorCheck(DAQmxCreateTask("DigOut", &daq->do_port)); + errorCheck(DAQmxCreateDOChan(daq->do_port, "Dev1/port1", "", DAQmx_Val_ChanForAllLines)); /* configure digital internal clock task */ - DAQmxErrChk(DAQmxCreateTask("DigClk", &daq->do_clk)); - //DAQmxErrChk(DAQmxCreateCOPulseChanTime(daq->do_clk, "Dev1/ctr0", "", DAQmx_Val_Seconds, DAQmx_Val_Low, 0, 0.05, DO_PULSE_WIDTH)); - DAQmxErrChk(DAQmxCreateCOPulseChanTime(daq->do_clk, "Dev1/ctr0", "", DAQmx_Val_Seconds, DAQmx_Val_Low, 0, 0.05, 0.08)); - DAQmxErrChk(DAQmxCfgImplicitTiming(daq->do_clk, DAQmx_Val_FiniteSamps, 1)); + errorCheck(DAQmxCreateTask("DigClk", &daq->do_clk)); + //errorCheck(DAQmxCreateCOPulseChanTime(daq->do_clk, "Dev1/ctr0", "", DAQmx_Val_Seconds, DAQmx_Val_Low, 0, 0.05, DO_PULSE_WIDTH)); + errorCheck(DAQmxCreateCOPulseChanTime(daq->do_clk, "Dev1/ctr0", "", DAQmx_Val_Seconds, DAQmx_Val_Low, 0, 0.05, 0.08)); + errorCheck(DAQmxCfgImplicitTiming(daq->do_clk, DAQmx_Val_FiniteSamps, 1)); - DAQmxErrChk(DAQmxRegisterDoneEvent(daq->do_clk, 0, pulldownTimerCallbackWrapper, this)); + errorCheck(DAQmxRegisterDoneEvent(daq->do_clk, 0, pulldownTimerCallbackWrapper, this)); /* start custom task */ DAQmxStartCustomTask(daq->di_port); @@ -87,7 +87,7 @@ void NIDAQmxInterface::DAQmxReadErrorPort() /* read port */ if (daq->di_error != 0) - DAQmxErrChk(DAQmxReadDigitalU8(daq->di_error, 1, 10.0, DAQmx_Val_GroupByChannel, &port_bit, 1, &read, NULL)); + errorCheck(DAQmxReadDigitalU8(daq->di_error, 1, 10.0, DAQmx_Val_GroupByChannel, &port_bit, 1, &read, NULL)); /* stop task */ DAQmxStopCustomTask(daq->di_error); @@ -98,19 +98,25 @@ void NIDAQmxInterface::DAQmxReadErrorPort() if ((port_bit & DAQ_PORT_DE_MONITOR) == DAQ_PORT_DE_MONITOR) { fprintf(stderr, "DAQmxError:NIDAQmxInterface/DAQmxReadErrorPort:\n\tMONITOR failed!\n"); - exit(EXIT_FAILURE); + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("ERROR: Monitor read error on NIDAQ", 0, 0, timeString)); + return; } if ((port_bit & DAQ_PORT_DE_AIR) == DAQ_PORT_DE_AIR) { fprintf(stderr, "DAQmxError:NIDAQmxInterface/DAQmxReadErrorPort:\n\tAIR pump failed!\n"); - exit(EXIT_FAILURE); + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("ERROR: Air read error on NIDAQ", 0, 0, timeString)); + return; } if ((port_bit & DAQ_PORT_DE_WATER) == DAQ_PORT_DE_WATER) { fprintf(stderr, "DAQmxError:NIDAQmxInterface/DAQmxReadErrorPort:\n\tWATER pump failed!\n"); - exit(EXIT_FAILURE); + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("ERROR: Water read error on NIDAQ", 0, 0, timeString)); + return; } } @@ -122,7 +128,7 @@ void NIDAQmxInterface::DAQmxReadErrorPort() void NIDAQmxInterface::DAQmxDestroyInterface() { /* check if task is digital output task is done */ - DAQmxErrChk(DAQmxWaitUntilTaskDone(daq->do_clk, -1)); + errorCheck(DAQmxWaitUntilTaskDone(daq->do_clk, -1)); /* stop tasks */ DAQmxStopCustomTask(daq->di_port); @@ -131,13 +137,13 @@ void NIDAQmxInterface::DAQmxDestroyInterface() DAQmxStopCustomTask(daq->di_error); /* clear tasks */ - DAQmxErrChk(DAQmxClearTask(daq->di_port)); + errorCheck(DAQmxClearTask(daq->di_port)); daq->di_port = 0; - DAQmxErrChk(DAQmxClearTask(daq->do_port)); + errorCheck(DAQmxClearTask(daq->do_port)); daq->do_port = 0; - DAQmxErrChk(DAQmxClearTask(daq->do_clk)); + errorCheck(DAQmxClearTask(daq->do_clk)); daq->do_clk = 0; - DAQmxErrChk(DAQmxClearTask(daq->di_error)); + errorCheck(DAQmxClearTask(daq->di_error)); daq->di_error = 0; return; @@ -152,12 +158,12 @@ void NIDAQmxInterface::DAQmxStartCustomTask(TaskHandle taskHandle) if (taskHandle != 0) { /* check if task is already active */ - DAQmxErrChk(DAQmxIsTaskDone(taskHandle, &done)); + errorCheck(DAQmxIsTaskDone(taskHandle, &done)); if (!done) - DAQmxErrChk(DAQmxStopTask(taskHandle)); + errorCheck(DAQmxStopTask(taskHandle)); /* start / re-start task */ - DAQmxErrChk(DAQmxStartTask(taskHandle)); + errorCheck(DAQmxStartTask(taskHandle)); } return; @@ -171,9 +177,9 @@ void NIDAQmxInterface::DAQmxStopCustomTask(TaskHandle taskHandle) if (taskHandle != 0) { /* check if task is active */ - DAQmxErrChk(DAQmxIsTaskDone(taskHandle, &done)); + errorCheck(DAQmxIsTaskDone(taskHandle, &done)); if (!done) - DAQmxErrChk(DAQmxStopTask(taskHandle)); + errorCheck(DAQmxStopTask(taskHandle)); } return; @@ -190,24 +196,26 @@ void NIDAQmxInterface::DAQmxTriggerDO(uInt8 qry_port_bit, bool arm_timer) 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)); + errorCheck(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); + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("ERROR: unable to TriggerDO on NIDAQ", qry_port_bit, (qry_port_bit & daq->do_bit_wrt) == qry_port_bit, timeString)); + return; } /* arm time out if required */ if ((daq->do_clk != 0) & (arm_timer == TRUE)) { - DAQmxErrChk(DAQmxIsTaskDone(daq->do_clk, &done)); + errorCheck(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)); + errorCheck(DAQmxStopTask(daq->do_clk)); + errorCheck(DAQmxStartTask(daq->do_clk)); } /* log trigger */ QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); @@ -231,23 +239,25 @@ void NIDAQmxInterface::DAQmxSetDO(uInt8 qry_port_bit, bool arm_timer, bool isSet }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)); + errorCheck(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); + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("ERROR: unable to SetDO on NIDAQ", qry_port_bit, (qry_port_bit & daq->do_bit_wrt) == qry_port_bit, timeString)); + return; } /* arm time out if required */ if ((daq->do_clk != 0) & (arm_timer == TRUE)) { - DAQmxErrChk(DAQmxIsTaskDone(daq->do_clk, &done)); + errorCheck(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)); + errorCheck(DAQmxStopTask(daq->do_clk)); + errorCheck(DAQmxStartTask(daq->do_clk)); } /* log trigger */ @@ -264,7 +274,7 @@ int32 CVICALLBACK NIDAQmxInterface::FcnCbckDetectDI(TaskHandle taskHandle, int32 if(!isPaused){ int32 read = 0; if (taskHandle != 0) - DAQmxErrChk(DAQmxReadDigitalU8(taskHandle, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->di_bit_now, 1, &read, NULL)); + errorCheck(DAQmxReadDigitalU8(taskHandle, 1, 10.0, DAQmx_Val_GroupByChannel, &daq->di_bit_now, 1, &read, NULL)); if (read) { @@ -317,14 +327,16 @@ int32 CVICALLBACK NIDAQmxInterface::FcnCbckTriggerStopDO(TaskHandle taskHandle, 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)); + errorCheck(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); + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile("ERROR: unable to set timeout for NIDAQ", 0, 0, timeString)); + return -1; } /* log trigger */ @@ -333,3 +345,20 @@ int32 CVICALLBACK NIDAQmxInterface::FcnCbckTriggerStopDO(TaskHandle taskHandle, } return 0; } + +bool NIDAQmxInterface::errorCheck(int32 functionReturnValue) +{ + if((functionReturnValue) < 0){ + char errBuffer[2048]; + DAQmxGetExtendedErrorInfo(errBuffer, 2048); + qDebug() << errBuffer; + QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz"); + emit(writeToLogFile(QString("ERROR: ").append(errBuffer), 0, 0, timeString)); + + //fprintf(stderr, "DAQmxError: %s\n Calling: %s\n", errBuffer, functionReturnValue); + return true; + }else{ + return false; + } + +} diff --git a/NIDAQmxInterface.h b/NIDAQmxInterface.h index dc11cfd..956702e 100644 --- a/NIDAQmxInterface.h +++ b/NIDAQmxInterface.h @@ -98,6 +98,6 @@ class NIDAQmxInterface: public QObject int32 CVICALLBACK FcnCbckTriggerStopDO(TaskHandle, int32); friend int32 CVICALLBACK inputCallbackWrapper(TaskHandle taskHandle, int32 signalID, void *callback_dat); friend int32 CVICALLBACK pulldownTimerCallbackWrapper(TaskHandle taskHandle, int32 signalID, void *callback_dat); - + bool errorCheck(int32 functionReturnValue); #endif /* define (NIDAQmxInterface_h) */ };