gentnerlab / pyoperant

python package for operant conditioning
BSD 3-Clause "New" or "Revised" License
13 stars 15 forks source link

add support for NI-DAQmx #6

Open neuromusic opened 11 years ago

neuromusic commented 11 years ago

via PyDAQmx

neuromusic commented 10 years ago

this should be implemented as an "interface": pyoperant/interfaces/pydaqmx_.py

to start, we should have _boolean_read() & _boolean_write(value=True) methods & use the callback feature to setup _boolean_poll(until_value=True)

neuromusic commented 10 years ago

change detection in nidaqmx: http://www.ni.com/white-paper/4102/en/

neuromusic commented 10 years ago

more references:

on DAQmx events: http://www.ni.com/white-paper/5384/en/

Configure Timing --> Configure Change Detection --> Start Task --> Read --> Clear Task --> Error Check /via http://forums.ni.com/t5/Digital-I-O/Change-Detection-Interrupts-NI-6509/td-p/190597

example c code:

int CVICALLBACK StartCallback(int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
    int32       error=0;
    TaskHandle  taskHandle=0;
    char        chan[256];
    char        risingEdgeChan[256];
    char        fallingEdgeChan[256];
    int32       samplesPerRead;
    int32       numRead;
    uInt8       *data=NULL;
    char        errBuff[2048]={'\0'};
    int         i,j;
    int         numLines;
    int32       bytesPerSamp;

    if( event==EVENT_COMMIT ) {
        GetCtrlVal(panel,PANEL_CHANNEL,chan);
        GetCtrlVal(panel,PANEL_RISING_EDGE_CHANNEL,risingEdgeChan);
        GetCtrlVal(panel,PANEL_FALLING_EDGE_CHANNEL,fallingEdgeChan);
        GetCtrlVal(panel,PANEL_SAMPLES_PER_READ,&samplesPerRead);

        /*********************************************/
        /*/ DAQmx Configure Code
        /*********************************************/
        DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
        DAQmxErrChk (DAQmxCreateDIChan(taskHandle,chan,"",DAQmx_Val_ChanPerLine));
        DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,risingEdgeChan,fallingEdgeChan,DAQmx_Val_ContSamps,samplesPerRead));
        DAQmxErrChk (DAQmxGetTaskAttribute(taskHandle,DAQmx_Task_NumChans,&numLines));

        if( (data=malloc(samplesPerRead*numLines))==NULL ) {
            MessagePopup("Error","Not enough memory");
            goto Error;
        }
        SetCtrlAttribute(panel,PANEL_STRIPCHART,ATTR_NUM_TRACES,numLines);

        /*********************************************/
        /*/ DAQmx Start Code
        /*********************************************/
        DAQmxErrChk (DAQmxStartTask(taskHandle));

        gRunning = 1;
        while( gRunning ) {
            /*********************************************/
            /*/ DAQmx Read Code
            /*********************************************/
            DAQmxReadDigitalLines (taskHandle,samplesPerRead,10.0,DAQmx_Val_GroupByScanNumber,data,samplesPerRead*numLines,&numRead,&bytesPerSamp,NULL);

            /* Separate the traces vertically by adding the line number */
            /* to each individual data point.  In most cases, this is   */
            /* the desired behavior.  To show traces bunched together,  */
            /* remove the for loops below.                              */
            for(i=0;i<numRead;i++)
                for(j=0;j<numLines;j++)
                    data[i*numLines+j] += j * 2;
            if( numRead>0 )
                PlotStripChart(panel,PANEL_STRIPCHART,data,numRead*numLines,0,0,VAL_UNSIGNED_CHAR);
            ProcessSystemEvents();
        }
    }
neuromusic commented 10 years ago

http://www.ni.com/white-paper/5409/en/