LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble monitoring a digital line with DAQmxCfgChangeDetectionTiming

Hi everyone,

I'm using LabWindows/CVI 9.0 with a NI PCI-6220 MIO and have to test a voltage converter. Due to high output voltage we keep it locked in a drawer. If the drawer is unlocked a switch goes off.

Before I start my test I explicitly check the switch with the following function which works reliably:

int is_drawer_open()
{
// prepare DAQmx error handling
int32 error = 0;
char errBuff[2048]={'\0'};

int32 read = -1;
uInt8 data = 2; // anything positive from 0 or 1

// read Dev3 port 0 and check line 0
DAQmxErrChk (DAQmxCreateTask("RailLatchCheck",&RailLatchCheck));
DAQmxErrChk (DAQmxCreateDIChan(RailLatchCheck,"Dev3/port0/line0","",DAQmx_Val_ChanPerLine));
DAQmxErrChk (DAQmxStartTask(RailLatchCheck));
DAQmxErrChk (DAQmxReadDigitalU8(RailLatchCheck,1,10.0,DAQmx_Val_GroupByChannel,&data,1,&read,NULL));
DAQmxStopTask(RailLatchCheck);
DAQmxClearTask(RailLatchCheck);
RailLatchCheck = 0;

if(data == 1){
return -1;
}else{
return 0;
}

Error:
if( DAQmxFailed(error) ){
DAQmxGetExtendedErrorInfo(errBuff,2048);
MessagePopup("DAQmx Error",errBuff);
}

return 0;

}


To efficiently monitor the switch I checked out the "Read Dig Chan-Change Detection Event"-Example. However I get static and my ChangeDetectionCallback goes off several times and if I check the actual bit, checking data says the drawer was opened while it's actually still closed:

int CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
{
int32 error=0;
uInt8 data=2;
int32 numRead;
int32 bytesPerSamp;
int i=0;
char errBuff[2048]={'\0'};
Delay(1);

if( gTaskHandle ) {
DAQmxErrChk (DAQmxReadDigitalU8(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,&data,1,&numRead,NULL));
}

if(data == 1)
{
DRAWER_OPEN = -1;
setUBatt0V();
write_port(SETTING28);
}

Error:
if( DAQmxFailed(error) ){
DAQmxGetExtendedErrorInfo(errBuff,2048);
MessagePopup("DAQmx Error",errBuff);
}

return 0;
}



I suppose that the sample is dirty due to the static and would like to know if there is a way to delay the measurement of what DAQmxReadDigitalU8 actually reads into data? I had also sporadically gotten an error -200284. Explicit checks with is_drawer_open() work reliable, however not as instantly as I would expect the ChangeDetectionCallback to work. Or is there maybe a way to monitor a digital line that is more appropriate than DAQmxCfgChangeDetectionTiming? Triggering examples always read their data in the same function block where the whole task is registered, instead of in a separate callback, like in the example I mentioned above.


Appreciate your help!


Best regards
Markus
0 Kudos
Message 1 of 6
(4,142 Views)

whitenoiz wrote:
... my ChangeDetectionCallback goes off several times ...

Does it go off while the drawer is stationary or while it is being pulled out/pushed in?
If the latter is true, it may be so due to switch debounce.
But anyway, it should give a correct value after the drawer switch is completely opened/closed. 
Do you get the sporadic -200284 error from your code, from the sample or both?
Use DAQmxGetErrorString to see the explanation. Did you take that message into account?
There is no trigger/timing related calls in your DAQmx code. Maybe you should add?
Did you try using NI-MAX's sample panels? How do they behave?
Message Edited by ebalci on 09-23-2009 01:16 PM
S. Eren BALCI
IMESTEK
0 Kudos
Message 2 of 6
(4,138 Views)

 

>Does it go off while the drawer is stationary or while it is being pulled out/pushed in?

 

The ChangeDetectionCallback() is called due to interference caused by measurements running in parallel on our external board, not by drawer movement. Verified that with a scope.

 

>But anyway, it should give a correct value after the drawer switch is completely opened/closed.

 

You are right, that's what I would expect, too and that's actually my problem here. The value detected in ChangeDetectionCallback() does not correspond to the drawer position, while the DAQmxReadDigitalU8 is identical to the DAQmxReadDigitalU8 in is_drawer_open(), which works reliably.

 

>Do you get the sporadic -200284 error from your code, from the sample or both?

Mostly from the sample in ChangeDetectionCallback(), however now I haven't seen it for a while.

 

>There is no trigger/timing related calls in your DAQmx code. Maybe you should add?

 

That's the actual code I use to register the ChangeDetection:

DAQmxCreateTask("BackgroundSwitchMonitor",&gTaskHandle));
DAQmxCreateDIChan(gTaskHandle,latchChan,"",DAQmx_Val_ChanPerLine));

DAQmxCfgChangeDetectionTiming(gTaskHandle,latchChan,NULL,DAQmx_Val_ContSamps,1)); 

DAQmxRegisterSignalEvent(gTaskHandle,DAQmx_Val_SampleCompleteEvent,0,ChangeDetectionCallback,NULL));

 

I tried something like

DAQmxCfgDigEdgeStartTrig(gTaskHandle,"/Dev3/PFI0",DAQmx_Val_Rising));
DAQmxCfgSampClkTiming(gTaskHandle,"",10,DAQmx_Val_Rising,DAQmx_Val_HWTimedSinglePoint,1));


was not successful however. What would be a valid trigger/timing in my case? Can I trigger on port0/line0 which I'm also trying to measure afterwards? The NI example sure did let me do ChangeDetection and measurement on the same line without any errors. I'm lacking a bit of experience here.

 

> Did you try using NI-MAX's sample panels? How do they behave?

 

Just like NI's "single-shot" examples they behave well. However my overall program "architecture" registers the above ChangeDetectionCallback() at the start of a callback routine that reacts to a "Run" button and applies various voltages/states to the Voltage Converter followed by analog measurements. So ChangeDetectionCallback() goes off in parallel to analog data acquisition which runs in a separate (long running) callback. Not to mention Multithreading issues that may arise here...

 

 Thanks for your input so far.

 

0 Kudos
Message 3 of 6
(4,127 Views)

Of course, you must use port0/line0 both for triggering and reading.

 

What's the point in triggering from another -PFI0- line?

Is it connected to the switch also? If it is a floating pin, it sure will fluctuate.

S. Eren BALCI
IMESTEK
0 Kudos
Message 4 of 6
(4,125 Views)

>What's the point in triggering from another -PFI0- line?

 

/port0/line0 never showed up in code completion so I gave PFI0 a shot. No matter which one I use, I get error 200452  saying this property cannot be set with this task or my 6220 board. This is how I currently try to set it up:

 

DAQmxCfgDigEdgeStartTrig(gTaskHandle,"/Dev3/port0/line0",DAQmx_Val_Rising));
DAQmxCreateTask("BackgroundSwitchMonitor",&gTaskHandle));
DAQmxCreateDIChan(gTaskHandle,latchChan,"",DAQmx_Val_ChanPerLine));

DAQmxRegisterSignalEvent(gTaskHandle,DAQmx_Val_SampleCompleteEvent,0,ChangeDetectionCallback,NULL));

 

Still it would be far more appealing to read the line properly in the ChangeDetectionCallback...

 

Thank you. 

0 Kudos
Message 5 of 6
(4,121 Views)

Is this the true order function calls in your code? 

If yes, then your task handle is invalid.

You should use DAQmxCfgDigEdgeStartTrig after you create the task.

 

If you are using PFI for triggering you have to connect it to the switch output also along with port0/line0.

On top of all your hardware has to support the trigger-on-change capability. 

S. Eren BALCI
IMESTEK
0 Kudos
Message 6 of 6
(4,102 Views)