Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

AnalogMultiChannelReader for in_stream in python nidaqmx multithreading??

I am trying to create an GUI program using python and tkinder with multithreading. However while trying to pass AnalogMultiChannelReader(task.in_stream) instance to seperate thread so, it can run in the background, gives several errors. Below is the code I used, the code works perfectly, If i pass some random numbers but for AnalogMultiChannelReader instance doesn't work. 

Any suggestions on what I am doing wrong here?

 

 

# -*- coding: utf-8 -*-
"""
import tkinter as tk
from tkinter import *
import threading
import random
import time
from queue import Queue, Empty
import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

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

#%%
root = tk.Tk()
fig = Figure(figsize=(5,5), dpi=100)
graph = fig.add_subplot(111)
canvas = FigureCanvasTkAgg(fig,root)
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

def DAQ(q, Read, out):

    while True:
        
        Read.read_many_sample(data = out,number_of_samples_per_channel = 10000)# read from DAQ
        out = np.around(out, 6) #Round all values to 6 decimals to avoid overflow
        q.put((out))
        time.sleep(1)

def update_data(queue, root):
    try:
        vibrations = queue.get_nowait()
    except Empty:
        pass
    else:
        
        graph.plot(vibrations)
        canvas.draw()
        
    root.after(1, update_data, queue, root)

data_queue = Queue()
with nidaqmx.Task() as task:
    task.ai_channels.add_ai_accel_chan("cDAQ9181-1BB3669Mod1/ai0:2")
    task.timing.cfg_samp_clk_timing(10000, source="", sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=10000)
    reader = AnalogMultiChannelReader(task.in_stream)
    output = np.zeros([3, 10000])
    task.start() 


t = threading.Thread(target=DAQ, args=(data_queue, reader, output,))
t.daemon = True
t.start()
update_data(data_queue, root)
root.mainloop()

if I can successfully run the sample program provided from here

 

The error code I get after running my code is as follow:

 

Exception in thread Thread-7:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "<ipython-input-4-35e645b9e6e9>", line 16, in DAQ
    Read.read_many_sample(data = out,number_of_samples_per_channel = 10000)# read from DAQ
  File "C:\ProgramData\Anaconda3\lib\site-packages\nidaqmx\stream_readers.py", line 330, in read_many_sample
    self._verify_array(data, number_of_samples_per_channel, True, True)
  File "C:\ProgramData\Anaconda3\lib\site-packages\nidaqmx\stream_readers.py", line 78, in _verify_array
    channels_to_read = self._in_stream.channels_to_read
  File "C:\ProgramData\Anaconda3\lib\site-packages\nidaqmx\_task_modules\in_stream.py", line 223, in channels_to_read
    check_for_error(size_or_code)
  File "C:\ProgramData\Anaconda3\lib\site-packages\nidaqmx\errors.py", line 127, in check_for_error
    raise DaqError(error_buffer.value.decode("utf-8"), error_code)
nidaqmx.errors.DaqError: Task specified is invalid or does not exist.
Status Code: -200088

Any suggestion on how to fix it would be really helpful.

 

Thank You.

0 Kudos
Message 1 of 5
(4,709 Views)

Hi

Sorry, I am not familiar with this, but I can provide you with some reference information:

1.https://forums.ni.com/t5/Multifunction-DAQ/daqmx-error-on-dispose-pure-virtual-function-call/td-p/26...

2.https://forums.ni.com/t5/Multifunction-DAQ/AnalogUnscaledReader-gives-somewhat-different-reading-tha...

May I know what kind of data type of the random numbers that you pass in?

 

 

0 Kudos
Message 2 of 5
(4,597 Views)
# -*- coding: utf-8 -*-
"""
import tkinter as tk
from tkinter import *
import threading
import random
import time
from queue import Queue, Empty
import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

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

#%%
root = tk.Tk()
fig = Figure(figsize=(5,5), dpi=100)
graph = fig.add_subplot(111)
canvas = FigureCanvasTkAgg(fig,root)
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

def DAQ(q,):
   with nidaqmx.Task() as task:
    task.ai_channels.add_ai_accel_chan("cDAQ9181-1BB3669Mod1/ai0:2")
    task.timing.cfg_samp_clk_timing(10000, source="", sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=10000)
    reader = AnalogMultiChannelReader(task.in_stream)
    output = np.zeros([3, 10000])
    task.start()

    while True:
        
        reader.read_many_sample(data = out,number_of_samples_per_channel = 10000)# read from DAQ
        out = np.around(out, 6) #Round all values to 6 decimals to avoid overflow
        q.put((out))
        time.sleep(1)

def update_data(queue, root):
    try:
        vibrations = queue.get_nowait()
    except Empty:
        pass
    else:
        
        graph.plot(vibrations)
        canvas.draw()
        
    root.after(1, update_data, queue, root)

data_queue = Queue() 


t = threading.Thread(target=DAQ, args=(data_queue, reader, output,))
t.daemon = True
t.start()
update_data(data_queue, root)
root.mainloop()

I was able to fix this problem by starting the task with the function. I am not sure why this is happening since I didn't investigate the C-API of NI-DAQmx. I think it has something to do with passing the AnalogMultiChannelReader() object through to the different thread. Probably the task needs to be initiated in the same thread as the reader. Python module for NI-DAQmx is not thread safe. Since this question I haven't seen any updates in their library either. All in all together, I gave up on NI products and moved on to good old serial bus and TCP/IP DAQ cards where I have more control over data and multi-threading. 

Thanks for the reply. 

Message 3 of 5
(4,577 Views)

Any good alternatives on DAQs to NI?

0 Kudos
Message 4 of 5
(1,817 Views)

@eduardomp8 wrote:

Any good alternatives on DAQs to NI?


There are several low cost alternatives but the support and performance may not be the same level.

 

MCC DAQ is one such alternative.

 

Santhosh
Soliton Technologies

New to the forum? Please read community guidelines and how to ask smart questions

Only two ways to appreciate someone who spent their free time to reply/answer your question - give them Kudos or mark their reply as the answer/solution.

Finding it hard to source NI hardware? Try NI Trading Post
Message 5 of 5
(1,807 Views)