Quantcast
Channel: Counter/Timer topics
Viewing all articles
Browse latest Browse all 1271

Error -50175 (The specified mathematical operation results in an overflow) when writting multiple counter channels samples in a task

$
0
0

I using NI-DAQmx C API to create a task and then create 4 counters in that task. The task is not started at this point. Later, I call DAQmxWriteCtrFreq to write the frequency and duty cycle samples, 1 sample per channel, so each array (frequency and duty cycle) has 4 float64 positions. The write function is returning error -50175 (The specified mathematical operation results in an overflow). Running the same code in a simulated hardware works. If I run the same code, but instead of 4 counters I create just one in the task, it works. 

 

My hw setup is a CCA,CDAQ-9185 ENET CDAQ, 4-SLOT, and a MODULE ASSY, NI 9474

 

This is a simple code to reproduce the error:

#include "pch.h" #include "NIDAQmx.h" static const char* counters[] = { #if !defined _DEBUG "cDAQ9185-23617DBMod3/ctr0", "cDAQ9185-23617DBMod3/ctr1", "cDAQ9185-23617DBMod3/ctr2", "cDAQ9185-23617DBMod3/ctr3", #else "cDAQ1Mod6/ctr0", "cDAQ1Mod6/ctr1", "cDAQ1Mod6/ctr2", "cDAQ1Mod6/ctr3", #endif }; static const float64 frequencies[] = { 2000, 2000, 2000, 1000 }; static const float64 dutyCycles[] = { 99, 99, 99, 1 }; static void showError( int rc ); int main() { int rc; TaskHandle task; std::cout << "Creating task..." << std::endl; if ( !DAQmxFailed( rc= DAQmxCreateTask("", &task) ) ) { std::cout << "Task created, creating channels..." << std::endl; for ( int i = 0; !DAQmxFailed( rc ) && i < ( sizeof( counters ) / sizeof( counters[ 0 ] ) ); i++ ) { if ( !DAQmxFailed( rc = DAQmxCreateCOPulseChanFreq( task, // The task handle counters[ i ], // The name of the physical channel to use for generating the PWM pulse. "", // The name(s) to assign to the created virtual channel(s). ("" = NI-DAQmx uses the physical channel name as the virtual channel name). DAQmx_Val_Hz, // The units in which to specify frequency. DAQmx_Val_Low, // The resting state of the output terminal. 0, // The amount of time in seconds to wait before generating the first pulse. frequencies[ i ], // The frequency at which to generate pulses. dutyCycles[ i ] / 100.0 ) ) ) // The width of the pulse divided by the pulse period. NI-DAQmx uses this ratio, combined with frequency, to determine pulse width and the interval between pulses. { // Specifies that the task generates samples continuously. NI-DAQmx uses the last parameter to determine the buffer size. rc = DAQmxCfgImplicitTiming( task, DAQmx_Val_ContSamps, 1 ); } } if ( !DAQmxFailed( rc ) ) { std::cout << "Retrieving current counter parameters from the task..." << std::endl; uint32_t numberOfChannels = 0; if ( !DAQmxFailed( rc = DAQmxGetTaskNumChans( task, ( uInt32* )&numberOfChannels ) ) ) { std::vector<float64> frequencySamples( numberOfChannels ); std::vector<float64> dutyCycleSamples( numberOfChannels ); for ( uint32_t i = 0; i < numberOfChannels && !DAQmxFailed( rc ); i++ ) { uint32_t index = i + 1; // For DAQmx functions the first channel starts in 1, hence the i + 1. size_t len = DAQmxGetNthTaskChannel( task, index, nullptr, 0 ); if ( len > 0 ) { std::vector<char> ch( len, 0 ); // Allocate the required size (the null terminator is included) if ( !DAQmxFailed( DAQmxGetNthTaskChannel( task, index, &ch[ 0 ], len ) ) ) // The first call was just to get the required string length. This second call will actually return the channel name. { DAQmxGetCOPulseFreq( task, &ch[ 0 ], &frequencySamples[ i ] ); DAQmxGetCOPulseDutyCyc( task, &ch[ 0 ], &dutyCycleSamples[ i ] ); } } } DAQmxResetBufOutputBufSize( task ); if ( !DAQmxFailed( rc ) ) { rc = DAQmxWriteCtrFreq( task, 1, true, DAQmx_Val_WaitInfinitely, DAQmx_Val_GroupByChannel, &frequencySamples[ 0 ],&dutyCycleSamples[ 0 ], nullptr, nullptr ); } } } DAQmxStopTask( task ); DAQmxClearTask( task ); } if ( DAQmxFailed( rc ) ) { showError( rc ); } } static void showError( int rc ) { size_t len = DAQmxGetErrorString( rc, // The NIDAQmx API error code nullptr, // Buffer that will have the converted error message. Passing nullptr will cause the function to return the required buffer size. 0 ); // The size, in bytes, of the buffer passed in the errorString. Passing 0 will cause the function to return the required buffer size. if ( len > 0 ) { std::vector<char> errorDescription( len + 1, 0 ); // Allocate the required size. Make sure we have the string terminator. if ( DAQmxGetErrorString( rc, &errorDescription[ 0 ], errorDescription.size() ) == 0 ) // Retrieve the error message. { std::cout << "DAQmx error: " << rc << " - " << &errorDescription[ 0 ] << std::endl; } } }

Viewing all articles
Browse latest Browse all 1271

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>