Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

CreatePulseChannelFrequency() does not relinquish output pin

I've inherited a medical device product, and it uses the NI 6602 with MS 8.1.1.  It configures pin 53 (Dev1/ctr6) to generate a waveform via NiDAQmxTask.COChannels.CreatePulseChannelFrequency().  This code has been working for a number of years.

 

We would like to create a utility for testing that will toggle the same pin 53 hi/lo, in this case using NiDAQmxTask.DOChannels.CreateChannel() with NiDAQmxDigitalSingleChannelWriter.WriteSingleSampleSingleLine() - call it CaseB, and the prior case CaseA.

 

We find, after PC bootup, we can run CaseB, followed by CaseA no problems.  If however, we try to run CaseB after CaseA, the voltage on pin 53 will only go up to 1.8v when we try to set it to 5v.  We can run CaseA, and the pin acts correctly.

 

It seems like if CaseB runs before CaseA, CaseB gives up the pin correctly.  However, when CaseA gets the pin, it never gives it up, at least to CaseB, even after our app is terminated.  The only way to get it to relinquish the pin is to reboot the PC.

 

The utility will be used for enhanced instrument testing.  The original designers of the code are unavailable for guidance.  Can you tell me how to get the task to give up the pin?

 

Thanks

 

John

0 Kudos
Message 1 of 12
(7,435 Views)

Hi John,

 

Are you explicitly using the DaqSystem.ConnectTerminals to route the counter signal to pin 53?  This shouldn't be necessary since pin 53 is the default counter out (and to route to a non-default lines you should typically use ExportSignals.ExportHardwareSignal).  Using the Connect Terminals would reserve the line even after the task has completed running unless you explicitly call DaqSystem.DisconnectTerminals.


Other than the above suggestion, I'm not sure what might be causing the behavior--does a Device Reset fix the issue?

That is, can you run Case A, Reset the Device (can be done programmatically or through Measurement and Automation Explorer), then run case B?

 

Also, what happens if you try to use the test panels (also accessed through Measurement and Automation Explorer) after running Case A?

Particularly, can you run a digital output using the test panel after running Case A?


Also, which version of DAQmx are you running?  Would it be possible to post a code snippet to show how your tasks are configured?


Best Regards,

John

John Passiak
0 Kudos
Message 2 of 12
(7,431 Views)

John -

 

Thanks for the prompt reply.  Some more pieces to the picture ...

 

1. The code is running on an FDA-approved device.  We are motivated to keep code changes to a minimum because that makes the reappraisal process quicker. 

2. Everything is programmatic - C++ via Visual Studio Measurement Studio v8.1.1.  That is, there is no LabView, no Measurement and Automation Explorer (that I know of) ...

3. I consider it VERY SIGNIFICANT that closing the CaseA app does not release the pin.  It requires a PC reboot to release it.  Obviously there is an NI service that retains control over the pin despite the app terminating.  I have a hard time believing this is intended behavior by NI. 

4. I consider it FAIRLY SIGNIFICANT that when CaseA has the pin first, and then CaseB allocates it, the voltage only goes to 1.85v.  As an EE, the 1.85v is a classic red flag that two TTL outputs are fighting over the same signal line, e.g.. CaseA is driving it low at the same time CaseB is trying to drive it high.  Again, it cannot be intended behavior for a task like CaseB to obtain a handle to a pin that is under control of another task/object.

5.  I consider it significant that I can run CaseB several times before CaseA, and it never appears to hold onto the pin when it terminates.

6. The original programmers used autopointers to hold the NiDAQmxTask objects - nowhere else in the app (200,000+ lines of code) are autopointers used.  I suspect their use is related to this pin retention problem.

 

Here's the code for CaseA (m_taskFLSSource).  The objective is to create a square wave on the pin (53) in question

 

 

m_taskFLSSource = std::auto_ptr<CNiDAQmxTask>(new CNiDAQmxTask());

 

//Creates a CNiDAQmxCOChannel to generate digital pulses defined by frequency and duty cycle

m_taskFLSSource->COChannels.CreatePulseChannelFrequency(

Channel,

"PulseTrain",

DAQmxCOPulseFrequencyUnitsHertz,

m_idleState,

waitstart,

frequency1,

dutyCycle1);

 

// Configures the task to start acquiring or generating samples

// on a rising or falling edge of a digital signal

m_taskFLSSource->Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(

triggerSource, // QLS, FLS and Split Lamp all share the same trigger source

triggerEdge);

 

 

m_taskFLSSource->Timing.ConfigureImplicit(

DAQmxSampleQuantityModeContinuousSamples,

1);

 

 

m_taskFLSSource->Start();

 

 

The routine returns soon after this point.  There is no delete - I suspect the autoptr is supposed to take care of that.

 

What I'm hoping is that there is some kind of Release() function that I can call on m_taskFLSSource.

 

Here's the code for CaseB

 

 

CNiDAQmxTask myTask;

physicalLine = line;

 

// Create the digital output channel

myTask.DOChannels.CreateChannel(physicalLine, "",DAQmxOneChannelForEachLine);

CNiDAQmxDigitalSingleChannelWriter writer(myTask.Stream);

writer.WriteSingleSampleSingleLine(true, value);

 

And the routine returns after this point.

 

Thanks for looking into this.

 

--John

 

0 Kudos
Message 3 of 12
(7,420 Views)

Hi John,

 

What version of DAQmx are you running?  I actually did some digging and found there was a bug that would explain the behavior you are seeing (CAR ID 102342).  The bug should be fixed as of DAQmx 8.8 but was not reported in the readme.

 

The 1.8V is indeed indicitive of double-driving the line:  the 6602 and 6608 use two TIO ASICs, I would expect the problem is unique to these two boards.

 

 

I'm not sure how involved the reappraisal process is going to be for a driver update, so the other option to work around the problem is to reset the device after running the counter task (Device.Reset).

 

MAX is typically installed with our drivers (you can find it under Start >> Programs >> National Instruments >> Measurement and Automation Explorer).

 

 

Best Regards,

John

John Passiak
0 Kudos
Message 4 of 12
(7,407 Views)

 

John -

 

Thanks for the guidance.  When I use MAX to look at the Ni-DAQmx device driver, it displays version 8.5.0f5.  I'll try a new download to see if that works.

 

If not, or if we aren't allowed to change drivers, what function performs a Device Reset?  Do you have any code examples? 

 

Thanks,

 

--John

0 Kudos
Message 5 of 12
(7,402 Views)

Hi John,

 

The device reset can be performed with the following function:

 

 

2009-12-07_083159.png

 

 

I can't think of any examples offhand but the Device Reset is going to be just the single line of code--if you run into any issues implementing it be sure to let me know.  Were you able to successfully reset the device to corret the problem through Measurement and Automation Explorer (shown below)?

 

 

2009-12-07_083440.png

 

 

 

Best Regards,

 

John

John Passiak
0 Kudos
Message 6 of 12
(7,377 Views)

 

John -

 

Thanks for the reply.

 

Thanks for the advice to call Devices::Reset().  Unfortunately, the only objects in the code snippet that I included are tasks.  Which object is a Device, or is there a way to call Devices::Reset() without an object?

 

Also - downloaded the Ni-DAQmx 9.0.2 hardware driver from ni.com to get the upgrade you suggested.  Now I'm getting a "Failed to create empty document" error from my app, even though it was compiled into an EXE over a year ago.  I'm getting it from at least three versions of the EXE, all compiled at least 2 months before I downloaded the Ni-DAQmx driver.  Nothing else was changed except what the download did.  Is there any way to get a listing of all DLLs the Ni-DAQmx download would have impacted?

 

Thanks

 

--John

0 Kudos
Message 7 of 12
(7,367 Views)

Hi John,

 

Good point--the code should look something like this to get the device reference:

myDevice = NationalInstruments.DAQmx.DaqSystem.Local.LoadDevice("Dev1")

myDevice.Reset()

 

As far as the upgrade issue is concerned, you may need to recompile the code (although I understand that might not be possible for you guys).  Does the error message provide any additional details?  If so, could you post a screenshot so I can see what the exact message is?

 

 

-John

John Passiak
0 Kudos
Message 8 of 12
(7,351 Views)

John -

I'll assume "Dev1" is the same string I submitted as the first argument in m_taskFLSSource->COChannels.CreatePulseChannelFrequency(), correct?

I've recompiled the code, unloaded the NiDAQmx 9.0.2 via Control Panel, loaded the original NiDAQmx 8.5 from the original CDs, etc. .. recompiled, etc.

BUT - as mentioned prior - this problem shows up when I run an EXE compiled in 2008 - how does recompiling affect that? I can't explain it other than an overwritten DLL. Thats why I would like a list of DLLs downloaded via the NiDAQmx 9.0.2 driver update found on the www.ni.com page, particularly DLLs that are NOT removed via Control Panel Uninstallation of NiDAQmx 9.0.2.

attached is a screenshot of the error msg.

 

             
  

0 Kudos
Message 9 of 12
(7,337 Views)

JBravo686,

 

There shouldn't be any dlls installed by NI Software that are not removed by the uninstaller.  The only thing I have ever heard of not being removed completely was registry keys.  Nothing is intentionally not removed if that is what you are referring to except maybe a component that another (still installed) program needs or a basic Windows dll or program that comes with windows.

Sincerely,
Jason Daming
Applications Engineer
National Instruments
http://www.ni.com/support
0 Kudos
Message 10 of 12
(7,326 Views)