Захват от National Instruments NI-DAQmx (USB 6215) 16 каналов и дисплей - PullRequest
0 голосов
/ 20 ноября 2018

Я создал код ниже для захвата и отображения сигнала от NI-DAQmx (USB 6215).Мне нужно захватывать и отображать живые сигналы с 16 каналов одновременно.Я хочу иметь 2 окна одновременно.Один с 16 живыми графиками и один с графиком, который вы выбираете, нажимая на 16 графиков (первое окно), по умолчанию будет отображаться первый график из 16-го.Я использовал код, найденный в здесь и здесь

Я изучал документацию NI, но на самом деле я не знаю, что мне нужно делать дальше.

#import PyDAQmx as nidaqmx
import nidaqmx    # Uncomment this if live

import numpy as np


from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.animation as animation
import matplotlib.pyplot as plt


class MyNidaQMX:
    '''
    This class Captures live signal from NI D/A Q and make a widget
    '''
    live = True         # If you want a Sin as a sample make it False 
    signal = list()
    time = list()
    pause = False
    simulate = False    
    info_text = ''
    line = None
    fig = None
    ax = None
    plot_rows = 1
    plot_cols = 1
    plots = 1
    anime = None
    autostart = True

    title = ''
    titleSize = 20    
    xlabels = list()
    ylabels = list()         
    xlims = {'min':  0, 'max' : 100}
    ylims = {'min': -1, 'max' : 1}
    lims_ratio = 1
    params = list()    
    rate = 10     # Refresh rate in msec, 1000msec = 1sec
    style = 'fivethirtyeight'
    channel = 'Dev1/ai0:1'
    samplesPerChannel = 1
    calibration = 1000

    current_angle = 1
    maxVals = {current_angle : 0}    #  angle : max
    minVals = {current_angle : 0}    #  angle : min


    def __init__(self, parent=None, *args, **kwargs):
        '''
        Constructor
        '''

        # Create the figure window
        self.fig = plt.figure()

        # Get Parameters
        if('plots' in kwargs):
            temp = kwargs.pop('plots')
            (self.plot_rows, self.plot_cols) = map(int,temp.split('x')) 
#            print ' %s %s' %(self.plot_rows, self.plot_rows)        
        self.plots = self.plot_rows * self.plot_cols


        if('style' in kwargs):
            style = kwargs.pop('style')
            self.setStyle(style)    # style of the window

        if('channel' in kwargs):
            self.channel = kwargs.pop('channel')

        if('title' in kwargs):
            self.title = kwargs.pop('title')        
        if('titleSize' in kwargs):
            self.titleSize = kwargs.pop('titleSize')
        self.fig.suptitle(self.title, fontsize=self.titleSize)

        if('xlabels' in kwargs):
            self.xlabels = kwargs.pop('xlabels')
        if('ylabels' in kwargs):
            self.ylabels = kwargs.pop('ylabels')

        if('autostart' in kwargs):
            temp = kwargs.pop('autostart')
            if(temp==True or temp == 1):
                self.autostart = True
            else:
                self.autostart = False

        # create widget or subplot window 
        for i in range(0, self.plots):
            self.ax = self.fig.add_subplot(self.plot_rows, self.plot_cols, (i+1))

            if(i < len(self.xlabels)):            
                self.ax.set_xlabel(self.xlabels[i])
            if(i < len(self.ylabels)):
                self.ax.set_ylabel(self.ylabels[i])

        # Create Canvas
        if __name__ != '__main__':
            self.canvas = FigureCanvas(self.fig)

        # Create the widget as object
        self.line, = self.ax.plot([], [], '-', color='blue', ms=self.rate)

        # Set axes limit
        self.updateLims()

        # The text that will shows the values in graph
        info_posx = 0.05
        info_posy = 0.9
        self.info_text = self.ax.text(info_posx, info_posy, '', transform=self.ax.transAxes)

        # animate
        self.anime = animation.FuncAnimation(self.fig,
                                             self.signalPoints,
                                             self.signalCapture,
                                             interval=self.rate,
                                             #blit=False,
                                             repeat=True)
        if(self.autostart):
            self.startAnimation()

        # Connect close event
#        self.fig.canvas.mpl_connect('button_press_event', self.pauseAnimation)
        self.fig.canvas.mpl_connect('close_event', self.handle_close)

        # Turn the interactive mode on.
#        plt.ion()    

    def signalCapture(self):
        t_max = 100.0
        dt = 0.05
        data = 0.0
        t = 0.0
        task = None


#        if True:    #if live Comment this    
        with nidaqmx.Task() as task:    #if live Uncomment this
            task.ai_channels.add_ai_current_chan(self.channel)    #if live Uncomment this

            while t < t_max:

                if (self.simulate and not self.pause):
                    if self.live:
                    # Data from signal
                        data=task.read(number_of_samples_per_channel=self.samplesPerChannel)
                        data = (data[0][0])*self.calibration    # Signal Calibration
                    else:
                    # Data sample
                        data = np.sin(np.pi*t) * self.current_angle

                    # Time factor
                    t = t + dt

                    # Dynamically scale axes
                    self.scaleAxes(data)

                elif(not self.simulate):
                    data = 0.0
                    t = 0.0

                yield data, t

            # reset the graph
            self.clearSignal()

    def signalPoints(self, data):

        x, t = data[0], data[1]

        self.signal.append(x)
        self.time.append(t)
        self.info_text.set_text('Time = %.1f s \nValue = %.1f'%(data[1], data[0]))    
        self.line.set_data(self.time, self.signal)

        return self.line, self.info_text

    def scaleAxes(self, val):
        flag = False
        ratio = val - self.lims_ratio
        if(ratio <= self.ylims['min']):
            self.ylims['min'] = ratio
            flag = True

        ratio = val + self.lims_ratio
        if(ratio >= self.ylims['max']):
            self.ylims['max'] = ratio
            flag = True

        if(flag):
            self.updateLims()        

    def updateLims(self):
        self.ax.set_xlim(self.xlims['min'], self.xlims['max'])
        self.ax.set_ylim(self.ylims['min'], self.ylims['max'])

    def handle_close(self, evt):        
        self.stopAnimation(evt)
        title = self.fig._suptitle.get_text()   # self.fig._label
        print 'Closed Figure %s!!'% (self.fig.number)

    def startAnimation(self, event=None):
        self.simulate = True
        if(self.pause):
            self.pauseAnimation()

    def pauseAnimation(self, event=None):
        self.pause ^= True

    def stopAnimation(self, event=None):

        self.simulate = False
        self.clearSignal()

    def clearSignal(self):        
#        self.ax.clear()
#        print 'Signal:\n'+str(self.signal)+'Time'+str(self.time) 
        self.signal = list()
        self.time = list()

    def storeSignal(self):
        self.stored_signals[self.current_angle] = self.signal
        self.stored_times[self.current_angle] = self.time

    def showGraph(self):

#        self.fig.show()
        plt.show()

    def draw(self):
        self.canvas.draw()


#========================
#    Usage Example
#========================

if __name__ == '__main__':

    draw16 = MyNidaQMX(plots='4x4')
    draw16.showGraph()

#    print plt.style.available
    xlbs = ["X Labels"]
    ylbs = ["Y Labels"]
    draw = MyNidaQMX(title= "Title",
                     titleSize=20,
                     channel= "Dev1/ai1:0",
                     xlabels= xlbs,
                     ylabels= ylbs)
    draw.showGraph()
...