Note that there are some explanatory texts on larger screens.

plurals
  1. POmake a CVICALLBACK a member function in QT creator
    primarykey
    data
    text
    <p>I found an NI example on how to use some of the DAQmx functions. It's a simple C-file that contains some of the following:</p> <pre><code>... // This is a declaration/definition I think int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData); ... // Later in the script there is actual function int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData) { ... return 0; } </code></pre> <p>When I tend to use some of the variables or functions that are defined in .h file, the ChangeDetectionCallback function does not recognize them. I tried to define this callback function as a member function in .h file, hoping that now all functions will be accessible. Here's my .h content:</p> <pre><code>#ifndef MAINWINDOW_H #define MAINWINDOW_H #include &lt;QMainWindow&gt; #include "NIDAQmx.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData); private: Ui::MainWindow *ui; void mainLoop(); }; #endif // MAINWINDOW_H </code></pre> <p>and here's my .c content:</p> <pre><code>#include "mainwindow.h" #include "ui_mainwindow.h" #include "NIDAQmx.h" #include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;time.h&gt; #define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui-&gt;setupUi(this); mainLoop(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::mainLoop() { ... DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL)); ... } int32 MainWindow::ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData) { ... return 0; } </code></pre> <p>So, again, I tried many wrong ways to define my callback function in the header file unsuccessfully. Please, help me to get this straight. And here's the error message that I do not clearly understand:</p> <pre><code>D:\Projects\sapm3\mainwindow.cpp:37: error: cannot convert 'MainWindow::ChangeDetectionCallback' from type 'int32 (MainWindow::)(TaskHandle, int32, void*) {aka long int (MainWindow::)(void*, long int, void*)}' to type 'DAQmxSignalEventCallbackPtr {aka long int (__attribute__((__cdecl__)) *)(void*, long int, void*)}' DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL)); </code></pre> <p>Here's the original code. It triggers callback function to get a measurement sample and outputs the data to console. I wish to write the sampled data to my member variable and emit a signal that is defined in the .h file of the object.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;time.h&gt; #include &lt;NIDAQmx.h&gt; #define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else static TaskHandle taskHandle; static uInt32 numLines; static uInt8 cachedData[200]; int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData); void Cleanup (void); int main(void) { int32 error=0; char errBuff[2048]={'\0'}; /*********************************************/ // DAQmx Configure Code /*********************************************/ DAQmxErrChk (DAQmxCreateTask("",&amp;taskHandle)); DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"Dev1/port0/line0:7","",DAQmx_Val_ChanPerLine)); DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,"Dev1/port0/line0:7","Dev1/port0/line0:7",DAQmx_Val_ContSamps,1)); DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL)); DAQmxErrChk (DAQmxGetTaskNumChans(taskHandle,&amp;numLines)); /*********************************************/ // DAQmx Start Code /*********************************************/ DAQmxErrChk (DAQmxStartTask(taskHandle)); puts("Continuously reading. Press Enter key to interrupt\n"); puts("Timestamp Data read Changed Lines"); getchar(); Error: if( DAQmxFailed(error) ) { DAQmxGetExtendedErrorInfo(errBuff,2048); Cleanup(); printf("DAQmx Error: %s\n",errBuff); } printf("End of program, press Enter key to quit\n"); getchar(); return 0; } int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData) { int32 error=0; uInt8 data[200]={0}; int32 numRead; uInt32 i=0; char buff[512], *buffPtr; char errBuff[2048]={'\0'}; char *timeStr; time_t currTime; if( taskHandle ) { time (&amp;currTime); timeStr = ctime(&amp;currTime); timeStr[strlen(timeStr)-1]='\0'; // Remove trailing newline. /*********************************************/ // DAQmx Read Code /*********************************************/ DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByScanNumber,data,8,&amp;numRead,NULL,NULL)); if( numRead ) { buffPtr = buff; strcpy(buff, timeStr); strcat(buff," "); buffPtr = buff + strlen(buff); for(;i&lt;numLines;++i) { sprintf(buffPtr,"%d",data[i]); buffPtr++; } strcat(buff," "); buffPtr = buff + strlen(buff); for(i=0;i&lt;numLines;++i) { sprintf(buffPtr,"%c",data[i]==cachedData[i]?'-':'X'); buffPtr++; cachedData[i] = data[i]; } puts(buff); fflush(stdout); } } return 0; Error: if( DAQmxFailed(error) ) { DAQmxGetExtendedErrorInfo(errBuff,2048); Cleanup(); printf("DAQmx Error: %s\n",errBuff); } return 0; } void Cleanup (void) { if( taskHandle!=0 ) { /*********************************************/ // DAQmx Stop Code /*********************************************/ DAQmxStopTask(taskHandle); DAQmxClearTask(taskHandle); taskHandle = 0; } } </code></pre> <p>I found the way to go around my problem. I declare an array variable at the top of the file. This way my callback function recognizes it. Then, I copy data from this array to my member array. Similarly, I created a counter variable and increment it each time the callback runs. At the same time I loopcheck this variable in my member function until it reaches desirable value and then emit a signal. Such approach really sucks and I wish to find a more intelligent way to writ it. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload