Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

USB-6211 stops after 100 hours of continuous output

Hi All

 

I am writing an application that has to do months of testing of a hardware system continuously.  I am using a USB-6211 D/A converter and a PC to generate a contant stream of analogue waveform data.

 

The PC is a fast modern computer running Window7.  The output sample rate is 50kHz and I am only using one D/A channel. 

 

When I run the program, the systems works as expected for about 100 hours.  Then I get the following error on the screen:

 

"DAQmx Error:  Task could not be started, because the driver could not write enough data to the device.  This was due to system and/or bus-bandwidth limitations.

 

Status Code: -200946"

 

Once it has failed, re-running the program will bring the same error up after seconds.  The only way to clear the error is to unplug the USB-6211 and plug it back in.  It will then run for another 100 hours.  This is not a solution as the system must run continuously for 3000 hours.

 

It looks as though the error is in the NI driver but I do not know how to debug this.  My code only makes 1 memory alloc at the start of the program and continuously generates samples into this memory buffer.  I can provide the relavent code sections if required.

 

Many Thanks

 

John

 

 

 

0 Kudos
Message 1 of 4
(5,812 Views)

Hi John,

 

If you could provide the code so I can look into the problem for you, that would be great. also if you could let me know what software versions you are using that would also be useful.

 

Kind regards,

Matt H
Applications Engineer
National Instruments UK
0 Kudos
Message 2 of 4
(5,796 Views)

Hi Matt

 

Here are the 2 main routines.  InitialiseOutputSystem is called once at the start of the program and OnEveryNSamplesEventCallback is called whenever the USB buffer has been emptied. 

 

I should also add that I set up the NI drivers (all 2GB of them) 1 week ago from the NI web site so they should be the latest.

 

Thanks for any help you can provide.

 

Cheers

 

John

 

 

 

#define PI                3.14159265359
#define    OUTPUT_FREQ        100.0                                    // output frequency of waveform in Hz
#define    NUM_SAMPLES        10000L                                    // number of samples in output waveform
#define    SAMPLE_RATE        50000L

 

void InitialiseOutputSystem ()
{

    int32        error=0;
    float64        tmpOutput;

        // ***** OUTPUT INITIALISATION *****

    // create task for analogue output
    DAQmxErrChk ( DAQmxCreateTask("",&outputTaskHandle) );
    DAQmxErrChk ( DAQmxCreateAOVoltageChan(outputTaskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL) );

    // set initial voltage to zero volts (no drive)
    tmpOutput = 0.0;
    DAQmxErrChk ( DAQmxWriteAnalogF64(outputTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &tmpOutput, NULL, NULL) );

    // wait for task to complete then stop it again
    DAQmxErrChk ( DAQmxWaitUntilTaskDone(outputTaskHandle,10.0) );
    DAQmxErrChk ( DAQmxStopTask(outputTaskHandle) );


    // get start trigger handle
    //DAQmxErrChk ( GetTerminalNameWithDevPrefix(outputTaskHandle,"ao/StartTrigger",trigName) );

    // configure sample timing
    DAQmxErrChk ( DAQmxCfgSampClkTiming(outputTaskHandle, "", SAMPLE_RATE, DAQmx_Val_Rising, DAQmx_Val_ContSamps, NUM_SAMPLES) );

    // register N samples callback event
    DAQmxErrChk ( DAQmxRegisterEveryNSamplesEvent(outputTaskHandle, DAQmx_Val_Transferred_From_Buffer, NUM_SAMPLES, 0, OnEveryNSamplesEventCallback, NULL) );

    // configure system to not regenerate the waveform automatically
    DAQmxErrChk ( DAQmxSetWriteAttribute(outputTaskHandle, DAQmx_Write_RegenMode, DAQmx_Val_DoNotAllowRegen) );

    // reconfigure output buffer size
    DAQmxErrChk ( DAQmxCfgOutputBuffer(outputTaskHandle, 2*NUM_SAMPLES) );

    // write waveform into driver
    DAQmxErrChk ( DAQmxWriteAnalogF64(outputTaskHandle, NUM_SAMPLES, 0, 10.0, DAQmx_Val_GroupByChannel, ptrOutputWaveform, NULL, NULL) );


    Error:
    if( DAQmxFailed(error) )
    {
        
        CloseNISystem ();    
    
    }

    return;
}

 

 

int32 CVICALLBACK OnEveryNSamplesEventCallback(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, void *callbackData)
{
    int32        error=0;

    char        errBuff[2048]={'\0'};

    //Record the time we last serviced the callback;
    LastCallBack = time (&LastCallBack);
    if ( fFinish )
    {
        //We have finished - make sure the outputted waveform is a continuous zero volts
        for ( int i = 0; i < NUM_SAMPLES; i++ )
            ptrOutputWaveform[i] = 0.0;
    }
    else
    {
        nWaveformCyclesCompleted++;
    }

    // write next waveform into buffer
    DAQmxErrChk ( DAQmxWriteAnalogF64(outputTaskHandle, NUM_SAMPLES, 1, 10.0, DAQmx_Val_GroupByChannel, ptrOutputWaveform, NULL, NULL) );

    if (!fFinish)     
    {
        if (CalCycleRequired == true)//Generate audio into the buffer with the cal cycle frequency.  Reset the phasor so that it starts from 0
        {
            if (CreateFrequency( ptrOutputWaveform, OpParams.CalFreq, 0, 10, 0, true, NUM_SAMPLES ) == true)
            {
                CalCycleRequired = false;
            }
        }
        else //Standard frequency generation - make the next 10000 points
        {
            CreateFrequency( ptrOutputWaveform, OpParams.NoiseFreq, OpParams.DriftFreq, OpParams.NoiseAmp, OpParams.DriftAmp, false, NUM_SAMPLES );
        }

    }

Error:
    if( DAQmxFailed(error) )
    {
        if( DAQmxFailed(error) ) printf("DAQmx Error: %s\n",errBuff);
        DAQmxGetExtendedErrorInfo(errBuff,2048);
        CloseNISystem ();

    }



    return (0);
}

0 Kudos
Message 3 of 4
(5,791 Views)

Hi John,

 

As the error states, it sounds like an error with the bandwidth capabilities of the communication bus. You are probably filling the bus faster than the bus can send the data, which then gives the resulting error you described. By unplugging the device and plugging it in again, you are simply clearing the bus, which means you start from the beginning and fill the bus to the same point again. 

 

If the data is repeating, you can turn on regeneration, which means the pc only needs to write to the bus once, and the data will be repeated. You can acheive this by changing your DAQmxSetWriteAttribute function line to allow regeneration with the following code 

 

DAQmxErrChk (DAQmxSetWriteAttribute (outputTaskHandle, DAQmx_Write_RegenMode, DAQmx_Val_AllowRegen)); 

 

If the data is non-repeating then you will need to either sample at a slower rate to not lose data, or use hardware that is designed for faster sampling. 

 

One other possible thing you could try is to take more samples at a lower rate if this is viable, as this is a more efficient in terms of the buffer not being filled so quickly. 

 

Kind regards,

 

Matt H
Applications Engineer
National Instruments UK
0 Kudos
Message 4 of 4
(5,778 Views)