Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

NI USB6210 DAQ acquisition nothing like actual signal

Solved!
Go to solution

I have a +/-5V (almost) square wave at 50Hz going onto a NI USB 6210 analog differential input, ai0-ai8 (where ai8 is connected to GND). Below is the scope reading taken across ai0-ai8

 

Scope_reading.jpg

 

When I take a differential acquisition on ai0 I get nothing like that,

NIDAQ_capture.png

The frequency is right but nothing else, whats going on here?

Code snippet used to set up channel,

acquisition.ai_channels.add_ai_voltage_chan("Dev1/ai0",
                                                terminal_config = constants.TerminalConfiguration.DIFFERENTIAL,
                                                min_val         = -5.0,
                                                max_val         = 5.0) 
    acquisition.timing.cfg_samp_clk_timing(rate           = sampling_freq_in, 
                                           sample_mode    = constants.AcquisitionType.CONTINUOUS,
                                           samps_per_chan = buffer_in_size_cfg)

 

Full code listing,

"""
Analog data acquisition from NI USB-6210
"""

# Imports
import matplotlib.pyplot as plt
import numpy as np

import nidaqmx
from nidaqmx.stream_readers import AnalogMultiChannelReader
from nidaqmx import constants

import threading
import pickle
from datetime import datetime
import scipy.io


### NI USB-6210 set up ###
# Parameters
sampling_freq_in   = 10000                      # in Hz
buffer_in_size     = 1000
bufsize_callback   = buffer_in_size
buffer_in_size_cfg = round(buffer_in_size * 1)  # clock configuration
chans_in           = 1                          # set to number of active OPMs (x2 if By and Bz are used, but that is not recommended)
refresh_rate_plot  = 100                        # in Hz
crop               = 10                         # number of seconds to drop at acquisition start before saving
my_filename        = 'test_3_opms'              # with full path if target folder different from current folder (do not leave trailing /)



# Initialize data placeholders
buffer_in = np.zeros((chans_in, buffer_in_size))
data      = np.zeros((chans_in, 1))  # will contain a first column with zeros but that's fine


# Definitions of basic functions
def ask_user():
    
    global running
    input("Press ENTER/RETURN to stop acquisition.")
    running = False


def cfg_read_task(acquisition): 
                                                               # uses above parameters
    acquisition.ai_channels.add_ai_voltage_chan("Dev1/ai0",
                                                terminal_config = constants.TerminalConfiguration.DIFFERENTIAL,
                                                min_val         = -5.0,
                                                max_val         = 5.0) 
    acquisition.timing.cfg_samp_clk_timing(rate           = sampling_freq_in, 
                                           sample_mode    = constants.AcquisitionType.CONTINUOUS,
                                           samps_per_chan = buffer_in_size_cfg)


def reading_task_callback(task_idx, event_type, num_samples, callback_data):  # bufsize_callback is passed to num_samples

    global data
    global buffer_in

    if running:
        
        buffer_in = np.zeros((chans_in, num_samples))   
        stream_in.read_many_sample(buffer_in, num_samples, timeout=constants.WAIT_INFINITELY)
        data      = np.append(data, buffer_in, axis=1)  # appends buffered data to total variable data

    return 0  


# Configure and setup the tasks
task_in   = nidaqmx.Task()
cfg_read_task(task_in)
stream_in = AnalogMultiChannelReader(task_in.in_stream)
task_in.register_every_n_samples_acquired_into_buffer_event(bufsize_callback, reading_task_callback)


# Start threading to prompt user to stop
thread_user = threading.Thread(target=ask_user)
thread_user.start()


# Main loop
running    = True
time_start = datetime.now()
task_in.start()


# Plot a visual feedback for the user's mental health
f, ax1 = plt.subplots(1, 1, sharex='all', sharey='none')
while running:  # make this adapt to number of channels automatically
    ax1.clear()
    ax1.plot(data[0, -sampling_freq_in * 5:].T)  # 5 seconds rolling window
    ax1.set_ylabel('voltage [V]')
    xticks = np.arange(0, data[0, -sampling_freq_in * 5:].size, sampling_freq_in)
    xticklabels = np.arange(0, xticks.size, 1)
    ax1.set_xticks(xticks)
    ax1.set_xticklabels(xticklabels)

    plt.pause(1/refresh_rate_plot)  # required for dynamic plot to work (if too low, nulling performance bad)


# Close task to clear connection once done
task_in.close()
duration = datetime.now() - time_start
print("Closing & saving data")


# Final save data and metadata ... first in python reloadable format:
filename = my_filename
with open(filename, 'wb') as f:
    pickle.dump(data, f)
'''
Load this variable back with:
with open(name, 'rb') as f:
    data_reloaded = pickle.load(f)
'''
# Human-readable text file:
extension = '.txt'
np.set_printoptions(threshold=np.inf, linewidth=np.inf)  # turn off summarization, line-wrapping
with open(filename + extension, 'w') as f:
    f.write(np.array2string(data.T, separator=', '))  # improve precision here!
# Now in matlab:
extension = '.mat'
scipy.io.savemat(filename + extension, {'data':data})


# Some messages at the end
num_samples_acquired = data[0,:].size
print("\n")
print("US-6210 acquisition ended.\n")
print("Acquisition duration: {}.".format(duration))
print("Acquired samples: {}.".format(num_samples_acquired - 1))


# Final plot of whole time course the acquisition
plt.close('all')
f_tot, ax1 = plt.subplots(1, 1, sharex='all', sharey='none')
ax1.plot(data[0, 10:].T)  # note the exclusion of the first 10 iterations (automatically zoomed in plot)
ax1.set_ylabel('voltage [V]')
xticks = np.arange(0, data[0, :].size, sampling_freq_in)
xticklabels = np.arange(0, xticks.size, 1)
ax1.set_xticks(xticks)
ax1.set_xticklabels(xticklabels)
plt.show()

 

0 Kudos
Message 1 of 5
(287 Views)
Solution
Accepted by topic author Dr_Nic

If the signal is not differential, you can connect the signal to just ai0 and connect gnd of signal to agnd.

 

Now ensure that the instrument is functioning properly, connect the signal to ai0-agnd, open DAQmx test panel from NI MAX, configure appropriate settings and observe the waveform.

 

If the waveform shows up correctly, then the instrument is good, your implementation of code may be incorrect.

-Santhosh
Semiconductor Validation & Production Test
Soliton Technologies
NI CLD, CTD
LabVIEW + TestStand + TestStand Semiconductor Module (2013 - 2020)
NI STS for Mixed signal and RF
0 Kudos
Message 2 of 5
(259 Views)

Hi,

 

The DAQmx test panel from NI MAX gave an equally odd waveform, even stranger than the one obtained via the Python script,

NI_Test_panel.png

Can I conclude that this is a hardware fault?

0 Kudos
Message 3 of 5
(232 Views)

I would not consider this as a hardware fault yet.

 

Could you please share the connections you have made? what is the signal source? some pictures maybe?

-Santhosh
Semiconductor Validation & Production Test
Soliton Technologies
NI CLD, CTD
LabVIEW + TestStand + TestStand Semiconductor Module (2013 - 2020)
NI STS for Mixed signal and RF
Message 4 of 5
(228 Views)

I had the terminal labels, connections & settings wrong, a full-house of wrong!

 

Label should have been a1, the agnd ref should have been to pin 28 and the terminal configuration should have been NRSE.

 

Thanks for your help, I should have paid better attention to your initial response & realized I wasn't dealing with a differential input!

0 Kudos
Message 5 of 5
(219 Views)