Jump to content
  • 0

AD3 Waveforms Scope vs API, Data Differs


cpitman

Question

Hey folks,

i am trying to automate a test procedure with the AD3, and one part is having the oscilloscope read from an active differential 500x probe that should be reading 240V RMS (ie AC Mains) or 0 (when the device is switched off).

When I configure everything through Waveforms, I see the signal I am looking for. When I try to get the data via the API, (1) the value does not change when the voltage is switched on and off, (2) the value I am reading seems random, each run is different, (3) whatever value is returned, it keeps returning it for many minutes, even though the scope should be in scan mode.

There is a second low-voltage channel that I can read successfully, so the basics of connecting are working.

Attached is an export I get when using WaveForms, with Channel 1 set to have 500x attenuation.

Here is what I am getting when using the API:

ha.get_load_voltage()
Valid samples: 16384, Max: 167.67514243395638, Min: 0.0
1.3227957862802593
ha.get_load_voltage()
Valid samples: 16384, Max: 167.67514243395638, Min: 0.0
1.3227957862802593
ha.get_load_voltage()
Valid samples: 16384, Max: 167.67514243395638, Min: 0.0
1.3227957862802593

 

What might I be doing differently between Waveforms and the API? Is it some configuration that is defaulted in Waveforms but needs to be manually set when using the API? Mishandling of an attenuated signal? Any pointers are appreciated!

 

Here is an excerpt of the code:

# Reset the device
self.handle_error(self.dwf.FDwfDeviceReset(self.handle))

self.handle_error(self.dwf.FDwfDeviceAutoConfigureSet(self.handle, c_int(0)))

# Oscilloscope configuration
# Channel 1 is for measuring the load voltage, via a x500 probe
# Channel 2 is for measuring the signal, via a x1 probe, measuring duty cycle
self.handle_error(self.dwf.FDwfAnalogInChannelEnableSet(self.handle, c_int(0), c_bool(True)))
self.handle_error(self.dwf.FDwfAnalogInChannelEnableSet(self.handle, c_int(1), c_bool(True)))

# Set both channels to scan mode
self.handle_error(self.dwf.FDwfAnalogInAcquisitionModeSet(self.handle, c_int(1)))

# Channel 1's signal is about 60Hz, and Channel 2's signal is about 1kHz
# At a frequency of 1MHz, Channel 1 will have ~16667 samples per cycle, and Channel 2 will have ~1000 samples per cycle
self.handle_error(self.dwf.FDwfAnalogInFrequencySet(self.handle, c_double(1000000)))
self.handle_error(self.dwf.FDwfAnalogInBufferSizeSet(self.handle, c_int(16667)))

# Set the attenuation of the channels
# Channel 1 is 500x, Channel 2 is 1x
self.handle_error(self.dwf.FDwfAnalogInChannelAttenuationSet(self.handle, c_int(0), c_double(500.0)))
self.handle_error(self.dwf.FDwfAnalogInChannelAttenuationSet(self.handle, c_int(1), c_double(1.0)))

# Set the voltage range of the channels
# Channel 1 is -340V to 340V with 500x attenuation, Channel 2 is -12V to 12V with 1x attenuation
self.handle_error(self.dwf.FDwfAnalogInChannelRangeSet(self.handle, c_int(0), c_double(360.0*2)))
self.handle_error(self.dwf.FDwfAnalogInChannelRangeSet(self.handle, c_int(1), c_double(14.0*2)))

# Wait for the oscilloscope to stabilize
time.sleep(2)

self.handle_error(self.dwf.FDwfAnalogInConfigure(self.handle, c_bool(True), c_bool(True)))

...

    def get_load_voltage(self):
        if not self._is_on:
            raise RuntimeError("Hardware is not connected")
        # Read data from Channel 1 (load voltage) of the oscilloscope
        status = c_byte(0)
        self.handle_error(self.dwf.FDwfAnalogInStatus(self.handle, c_int(0), byref(status)))

        valid_samples = c_int(0)
        self.handle_error(self.dwf.FDwfAnalogInStatusSamplesValid(self.handle, byref(valid_samples)))
        if valid_samples.value < 1000:
            raise RuntimeError("Insufficient samples")
        
        self.handle_error(self.dwf.FDwfAnalogInStatusData(self.handle, c_int(0), self.buffer, valid_samples))

        print(f"Valid samples: {valid_samples.value}, Max: {max(self.buffer)}, Min: {min(self.buffer)}")

        # Calculate rms of the data
        sum = 0
        for i in range(valid_samples.value):
            sum += (self.buffer[i]) ** 2
        rms = (sum / valid_samples.value) ** 0.5

        return rms

 

GoodScope.png

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...