LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

niDMM_Fetch appears to return previously measured value

Hi,

I have a strange problem when using a PCI-4060 (DMM) with WinXP, CVI 7.1 and niDMM 2.5.

I'm trying to measure two resistances using the 4-wire mode of the 4060. The resistors
are chosen by an external relay that is switched by a digital output pin from a PCI-6221.
The measurement is performed using a software trigger.

Here are the sequence of operations I perform:

1. Setup the DMM
2. Choose first resistor using relay
3. Measure resistance
4. Wait 1 second
5. Choose second resistor using relay
6. Measure resistance
7. Wait 1 second.
8. Measure resistance again.

The problem I see is that step 6 returns the value of the first resistor. However,
step 8 returns the correct value of the second resistor and any subsequent
measurements return the correct value. The code I'm using is below:


static ViSession dmmVi = VI_NULL;
static char *dmmResource = "DAQ::3::INSTR";

//------------------------------------------------------------------------------
// Setup
static int
InitDMM(void)
{
    ViStatus    error = VI_SUCCESS;

    checkErr(niDMM_init(dmmResource,    // resource name
            VI_TRUE,    // idQuery
            VI_TRUE,    // reset
            &dmmVi));

    checkErr(niDMM_ConfigurePowerLineFrequency(dmmVi, NIDMM_VAL_60_HERTZ));

    checkErr(niDMM_ConfigureMeasurement(dmmVi, NIDMM_VAL_4_WIRE_RES,
                    20000.0,    // 20 kOhm range
                    0.1));    // resolution

    checkErr(niDMM_ConfigureTrigger(dmmVi, NIDMM_VAL_IMMEDIATE,
                    NIDMM_VAL_AUTO_DELAY));

    // had to call this function even though I need only single point
    // acquisition
    checkErr(niDMM_ConfigureMultiPoint(dmmVi, 1, 0, NIDMM_VAL_SOFTWARE_TRIG,
                           0.0));

    checkErr(niDMM_Initiate(dmmVi));

 Error:
    if (error < VI_SUCCESS) {
    if (dmmVi != VI_NULL) {
        DMMErrorHandler(dmmVi);
        niDMM_close(dmmVi);
        dmmVi = VI_NULL;
    }
    }

    return error;
}

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Resistance measurement

static double
MeasureResistance(void)
{
    ViReal64    resistance;
    ViStatus    error = VI_SUCCESS;
    ViInt32    nMeasurements = 0;
    ViInt16    acqDone = 0;

    if (iniNoDMM)    // for testing only
    return 3500.0;

    if (dmmVi == VI_NULL)
    return BAD_RESISTANCE;

    checkErr(niDMM_SendSoftwareTrigger(dmmVi));

    checkErr(niDMM_ReadStatus(dmmVi, &nMeasurements, &acqDone));
    printf("DMM: %d %d\n", nMeasurements, (int)acqDone);

    checkErr(niDMM_Fetch(dmmVi, NIDMM_VAL_TIME_LIMIT_AUTO, &resistance));

 Error:
    if (error < VI_SUCCESS) {
    resistance = BAD_RESISTANCE;
    DMMErrorHandler(dmmVi);
    }

    return resistance;
}

//------------------------------------------------------------------------------

The code is based on the example in C:\Program Files\National Instruments\CVI71\samples\niDMM\Triggered\Cont Acq - SW Sample Trig
(which shows the same problem, by the way). I've tried using  single point acquisition and experimented with  the triggerSource and
triggerDelay parameters of the ConfigureTrigger() call. I've also tried playing with the sampleInterval parameter of ConfigureMultiPoint()
but haven't had anly luck. Any value other than the parameters I've used would cause ReadStatus() to return 0 for the number of
acquired points.

Are there any known problems with the 4060 and niDMM 2.5 that may explain this behavior? I couldn't find any in the KnowledgeBase.
If someone has run into this problem and has a solution or workaround, I would appreciate hearing from them very much.

Thanks,
Chandan
0 Kudos
Message 1 of 6
(3,251 Views)

I would have thought that you need to swap steps 3&4, and 6&7. That is, wait a short time immediately after changing the relay state, to allow sufficient time for it to physically move its contacts, before making a measurement. Otherwise the software is likely to be quicker than a mechanical relay, and you will end up measuring with the relay in the wrong state.

JR

0 Kudos
Message 2 of 6
(3,237 Views)
Yes, I do have a short wait between steps 2 and 3 and 5 and 6. I just didn't want to clutter up the pseudo-code.
As a matter of fact, I can use MAX to switch the relay and use one of the nidmm examples to measure the
resistance, meaning that the times are all human times (plenty of time for things to settle). I still see the problem
that the first measurement returns one value and the second returns another.

Chandan
0 Kudos
Message 3 of 6
(3,224 Views)

Hi,

Dont you have to do a Initiate and then a Fetch to acquire a new reading. All fetch does is returns the data from the instruments output buffer.

Regards

Ray Farmer

Regards
Ray Farmer
0 Kudos
Message 4 of 6
(3,215 Views)
Actually, I call Initiate() when I set up the DMM in my InitDMM() included above. For each measurement,
I SendSoftwareTrigger() and then Fetch(). This seems to be the recommended sequence, at least from
what I can tell from the nidmm examples, especially the one in
National Instruments\CVI71\samples\niDMM\Triggered\Cont Acq - SW Sample Trig

Thanks,
Chandan
0 Kudos
Message 5 of 6
(3,208 Views)

Hi,

If you are doing a single measurement then I believe the triger count and the sample count should both be equal to one

checkErr(niDMM_ConfigureMultiPoint(dmmVi, 1, 1, NIDMM_VAL_SOFTWARE_TRIG, 0.0));

(not sure this has both as I dont have CVI version to hand)

Hope this helps

Regards

Ray Farmer



   

Regards
Ray Farmer
0 Kudos
Message 6 of 6
(3,201 Views)