Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Access analog input online in a loop using Python

Hi there, 

I'm running a behavioural experiment and need to read the input from my NI USB-6229 BNC online inside a for loop. The code below works fine to save all input recorded during the loop, but my attempts to access the data online using ReadAnalogF64 seemed to have cleared the buffer, so when I call the ReadAnalogF64 again after the end of the for loop all input shows data collected after the loop (e.g. data collected during the loop is not available anymore). Any ideas on how to access the data inside the loop without clearing the buffer so that all data can be stored immediately after the for loop ends? I'm using Win7 and Canopy Python. Any help would be much appreciated.

 

Cheers

 

 

import numpy as np
from PyDAQmx import *
from nidaqmx.stream_readers import (AnalogMultiChannelReader)
import time

analog_input = Task()
taskHandle = TaskHandle(0)
fs = 1000.0# Acquisition frequency
Numb_channels = 8# Number of channels to collect
N_samples = 2600# Time in miliseconds we will collect data for.
databuffer = np.zeros((N_samples*Numb_channels,), dtype=np.float64)
nCycles = N_samples/(fs/120)# Number of frames given the monitor runs at 120Hz
read = int32()
data = np.zeros((N_samples*Numb_channels,), dtype=np.float64)

analog_input.CreateAIVoltageChan("Dev2/ai0:7", None, DAQmx_Val_Diff, -10.0, 10.0, DAQmx_Val_Volts, None)
analog_input.CfgSampClkTiming("", fs, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, N_samples)
analog_input.SetReadRelativeTo(DAQmx_Val_FirstSample)

for TrialsN in range(1):# Number of trials during experiment
    analog_input.StartTask()
    time.sleep(0.05)

    for frameN in range(int(round(nCycles))):
        if frameN<60:
            x = (0, 0)
        else:
            x += (dataPoint1, dataPoint2)#I would like to have access to the latest data points in the buffer during this loop

        flip.window()

    analog_input.ReadAnalogF64(int(N_samples), 5, DAQmx_Val_GroupByScanNumber, databuffer, len(databuffer), byref(read), None)
# The line above works like a charm but only without accessing data in the loop

 

 

 

 

 

 

0 Kudos
Message 1 of 3
(2,664 Views)

Hey,

 

I am not fully knowledgeable in Python, but are you not able to send that data into an array that can accessed later on? Also, which part is reading the data inside the For Loop? You have two For Loops so I want to be sure we are looking at the same thing.

 

Thanks,

-Brian J.

0 Kudos
Message 2 of 3
(2,628 Views)

Hi Brian,

thanks for your message. The problem is that I only need to access a few data points from a couple of channels inside the second For loop (e.g. 2 data points from 2 out of 8 channels). I can do that using ReadAnalogF64 inside the second For loop (not shown in the code I provided earlier, red text now), but that gives me only a fraction of what should have been saved within each iteration (each iteration lasts for the duration of a monitor refresh rate or 8.33 ms), and if I want to read all samples it stops the animation on screen. If I only save what I need online, then I would lose a fair bit of data that is important when measuring short lived physiological events. This is easily done in Labview (not an option at the moment because I need control over the monitor screen using python) and in previous Matlab versions using a now defunct function called PEEKDATA. As the name describes, peekdata would allow me to look at a defined number of samples from the buffer without interfering with the background data collection. I was hoping for an analogous to peekadata, but am open for suggestions. Let me know in case something isn't clear.

 

Many thanks,

W

 

import numpy as np
from PyDAQmx import *
from nidaqmx.stream_readers import (AnalogMultiChannelReader)
import time

analog_input = Task()
taskHandle = TaskHandle(0)
fs = 1000.0# Acquisition frequency
Numb_channels = 8# Number of channels to collect
N_samples = 2600# Time in miliseconds we will collect data for.
N_samples2 = 2
databuffer = np.zeros((N_samples*Numb_channels,), dtype=np.float64)
databuffer2 = np.zeros((N_samples2*Numb_channels,), dtype=np.float64)
nCycles = N_samples/(fs/120)# Number of frames given the monitor runs at 120Hz
read = int32()
data = np.zeros((N_samples*Numb_channels,), dtype=np.float64)
read2 = int32()
data2 = np.zeros((N_samples2*Numb_channels,), dtype=np.float64)

analog_input.CreateAIVoltageChan("Dev2/ai0:7", None, DAQmx_Val_Diff, -10.0, 10.0, DAQmx_Val_Volts, None)
analog_input.CfgSampClkTiming("", fs, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, N_samples)
analog_input.SetReadRelativeTo(DAQmx_Val_FirstSample)

for TrialsN in range(1):# Number of trials during experiment
    analog_input.StartTask()
    time.sleep(0.05)

    for frameN in range(int(round(nCycles))):
        analog_input.ReadAnalogF64(int(N_samples2), 5, DAQmx_Val_GroupByScanNumber, databuffer2, len(databuffer2), byref(read), None)
        if frameN<60:
            x = (0, 0)
        else:
            x += (dataPoint1, dataPoint2)#I would like to have access to the latest data points in the buffer during this loop

        flip.window()

    analog_input.ReadAnalogF64(int(N_samples), 5, DAQmx_Val_GroupByScanNumber, databuffer, len(databuffer), byref(read), None)
    # The line above works like a charm but only without accessing data in the loop

 

0 Kudos
Message 3 of 3
(2,622 Views)