Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Detecting changes using PCI-6527 with NI-DAQmx

Just installed .NET languages support for NI-DAQmx 7.1 and I was unable to locate examples and reference files. It looks like they weren't installed at all, regardless the fact that I have chosen that option.
0 Kudos
Message 11 of 27
(2,475 Views)
The .NET examples are installed to Program Files\National Instruments\MeasurementStudio70\DotNET\Examples\DAQmx. There are both C# and VB.NET examples. There are no managed C++ examples. The easiest thing for you to do will be to translate the C# examples to managed C++. The function reference for the DAQmx .NET class library is integrated into the MSDN help collection and is also available through the Start menu - Start>>Programs>>National Instruments>>Measurement Studio 7.0>>Measurement Studio Documentation.

This information, along with other useful information to help you get started, is in the DAQ Quick Start Guide. You can open the DAQ Quick Start Guide from Start>>Progra
ms>>National Instruments>>NI-DAQ>>DAQ Quick Start Guide.
0 Kudos
Message 12 of 27
(2,475 Views)
It took me some time, but I magaed to tanslate an example WriteDigChan form C# code to C++ Managed code.
I encoutnered some problems.
1. This is the code of C# example:
'private void WriteButton_Click(object sender, System.EventArgs e)
{
try
{
using (Task digitalWriteTask = new Task("DigitalWriteTask"))
{
digitalWriteTask.DOChannels.CreateChannel(channelParametersTextBox.Text,"",
ChannelLineGrouping.OneChannelForAllLines);
bool[] dataArray = new bool[8];
dataArray[0] = bit0CheckBox.Checked? true: false;
dataArray[1] = bit1CheckBox.Checked? true:false;
dataArray[2] = bit2CheckBox.Checked? true:false;
dataArray[3] = bit3CheckBox.Checked? true:false;
dataArray[4] = bit4CheckBox.Checked? true:false;
dataArray[5] = bit5CheckBox.Checked? true:false;
dataArray[6] = bit6CheckBox.Checked? true:false;
dataArray[7] = bit7CheckBox.Checked? true:false;
DigitalSingleChannelWriter writer = new DigitalSingleChannelWriter(digitalWriteTask.Stream);
writer.WriteSingleSampleMultiLine(true, dataArray);
}
}
catch(DaqException ex)
{
MessageBox.Show(ex.Message);
}
}'

I translated the code into this:
'
#using
#using "NationalInstruments.DAQmx.dll"
using namespace NationalInstruments::DAQmx;
.
.
.
void CDiomxHandler::WriteToDIO (void)
{
int i = 0;
Task *DIOWTask = new Task ("DigitalWriteTask");
bool* dataArray = new bool [8];

DIOWTask->DOChannels->CreateChannel ("Dev1/Port3/Line0:7", "Port0", ChannelLineGrouping::OneChannelForAllLines);

for (i=0; i<8; i++)
{
if ((i%2) == 0)
dataArray [i] = true;
else
dataArray [i] = false;
}

DigitalSingleChannelWriter *writer = new DigitalSingleChannelWriter (DIOWTask->Stream);
writer->WriteSingleSampleMultiLine (true, dataArray);
}'

Select compile project and go this:
d:\Vlado Stuff\Work\Pivovarna\ProductionCode\DIOmx\DiomxHandler.cpp(33): error C2664: 'NationalInstruments::DAQmx::DigitalSingleChannelWriter::WriteSingleSampleMultiLine' : cannot convert parameter 2 from 'bool *' to 'bool __gc[]'

It seems that WriteSingleSampleMultiLine method needs second argument to be of type __gc bool[]. I tried everything that I know, including modified sample for __gc array in MSDN. And it doesn't work. Anybody know a solution.

2. Then I played a bit with the code and finished with this:
'#using
#using "NationalInstruments.DAQmx.dll"
using namespace NationalInstruments::DAQmx;
.
.
.
void CDiomxHandler::WriteToDIO (void)
{
Task *DIOWTask = new Task ("DigitalWriteTask");

DIOWTask->DOChannels->CreateChannel ("Dev1/Port3/Line0", "Line0", ChannelLineGrouping::OneChannelForAllLines);

DigitalSingleChannelWriter *writer = new DigitalSingleChannelWriter (DIOWTask->Stream);
writer->WriteSingleSampleSingleLine (true, true);
}'

Compiled this and it passed with honours. Then I tried my application on PCI-6527 and the stuff I written does not work! There is some sort of error. Doesn't say what, though. Any ideas on this one too?
0 Kudos
Message 13 of 27
(2,475 Views)
You need to define a gc array in order to use it with the managed code. Try this

int i = 0;
Task *DIOWTask = new Task ("DigitalWriteTask");
bool dataArray __gc[] = new bool __gc[8];

for (i=0; i<8; i++)
{
if ((i%2) == 0)
dataArray [i] = true;
else
dataArray [i] = false;
}

DIOWTask->DOChannels->CreateChannel ("Dev1/Port0/Line0:7",
"Port0", ChannelLineGrouping::OneChannelForAllLines);

DigitalSingleChannelWriter *writer = new Dig
italSingleChannelWriter (DIOWTask->Stream);
writer->WriteSingleSampleMultiLine (true, dataArray);

This worked for me.

For the second part, try changing the channelgrouping to OneChannelForEachLine so that you're specifying a single line

Make sure to handle any DAQExceptions with a try/catch blocks also.

Bilal
Bilal Durrani
NI
0 Kudos
Message 14 of 27
(2,475 Views)
"(2) Create a CNiDAQmxTask object. It has a "Timing" property that returns a class that has a "ConfigureChangeDetection" method that should set up the task to do what you want as well as a "ChangeDetectionOverflowed" property to alert you if changes occur too rapidly for the system to keep up."

OK. Through Managed extensions, I am capable of configuring Change Detection. Now I have another question. When using Traditional DAQ, I was able to specify the way, my application will handle change detection (message or callback function).
Is there any way I can configure, let's say, Callback function, which will be run when change occures or do I have to use polling with DAQmx?
Message 15 of 27
(2,475 Views)
There is an example on this under ..\DotNET\Examples\DAQmx\Digital\Read Values\ReadDigChan_ChangeNotification.
It starts a cont. digital read operation that uses callbacks.
Basically, to setup a continuous read operation, you would be using the BeginReadXXX and EndReadXXX ( depending on how you want to read the data type) methods associated with the digital reader objects.

Bilal
Bilal Durrani
NI
0 Kudos
Message 16 of 27
(2,475 Views)
In DAQmx, all data is retrieved by calling a read method. There are synchronous read methods and asynchronous read methods. Either way, if you want notification in your application of each change detected, you should (1) configure the input buffer to 2 points (myTask.Stream.ConfigureInputBuffer), then (2) read, synchronously or asynchronously (with a callback) one point at a time. See the example Bilal mentioned for an example of setting up and calling the asynchronous read methods.

If you do not need notification of each change in your software, but only need to get all of the change detection data that occurred over an interval, your system will perform better and handle faster changes if you leave the buffer size at its default and
read a larger number of changes at one time.

Tony H.
Measurement Studio
0 Kudos
Message 17 of 27
(2,475 Views)
Thanx. I found the example and tried to convert it into C++. However there are some problems.
Lower you will see a translated code. Below each troublesome line, there will be an error, returned by compiler.

'
void CDiomxHandler::ReadDioInput (void)
{
Task *DIORTask = new Task ("DigitalReadTask");

DIORTask->DIChannels->CreateChannel ("Dev1/Port0/Line0:7", "In1", ChannelLineGrouping::OneChannelForAllLines);
Timing *timing = DIORTask->Timing;
timing->ConfigureChangeDetection ("Dev1/Port0/Line0:7", "Dev1/Port0/Line0:7", SampleQuantityMode::ContinuousSamples);

DigitalSingleChannelReader *reader = new DigitalSingleChannelReader (DIORTask->Stream);

reader->SynchronizingObject = this;
// error C2664: 'NationalInstrumen
ts::DAQmx::DigitalSingleChannelReader::set_SynchronizingObject' : cannot convert parameter 1 from 'CDiomxHandler *const ' to 'System::ComponentModel::ISynchronizeInvoke __gc *'


reader->BeginReadSingleSampleMultiLine (System::AsyncCallback (OnDataReady), NULL);
// error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'System::AsyncCallback'
}'

'OnDataReady' is declared in .h file like this:
'private:
void OnDataReady(System::IAsyncResult *result);'

Any suggestions?
0 Kudos
Message 18 of 27
(2,475 Views)
Thank you. This is an invaluable tip. I will most certanly use this later on.
0 Kudos
Message 19 of 27
(2,475 Views)
Perhaps you missed one of my posts. I am still having troubles. The quotation below should explain everything.

"Thanx. I found the example and tried to convert it into C++. However there are some problems.
Lower you will see a translated code. Below each troublesome line, there will be an error, returned by compiler.

'
void CDiomxHandler::ReadDioInput (void)
{
Task *DIORTask = new Task ("DigitalReadTask");

DIORTask->DIChannels->CreateChannel ("Dev1/Port0/Line0:7", "In1", ChannelLineGrouping::OneChannelForAllLines);
Timing *timing = DIORTask->Timing;
timing->ConfigureChangeDetection ("Dev1/Port0/Line0:7", "Dev1/Port0/Line0:7", SampleQuantityMode::ContinuousSamples);

DigitalSingleChannelReader *reader = new Digi
talSingleChannelReader (DIORTask->Stream);

reader->SynchronizingObject = this;
// error C2664: 'NationalInstruments::DAQmx::DigitalSingleChannelReader::set_SynchronizingObject' : cannot convert parameter 1 from 'CDiomxHandler *const ' to 'System::ComponentModel::ISynchronizeInvoke __gc *'

reader->BeginReadSingleSampleMultiLine (System::AsyncCallback (OnDataReady), NULL);
// error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'System::AsyncCallback'
}'

'OnDataReady' is declared in .h file like this:
'private:
void OnDataReady(System::IAsyncResult *result);'

Any suggestions?"
0 Kudos
Message 20 of 27
(2,475 Views)