我创建了以下代码,以捕获和显示NI-DAQmx(USB 6215)的信号。我需要同时捕获和显示来自16个通道的实时信号。我想同时拥有2个窗口。一个带有16个实时图形的图形,一个带有通过单击16个图形(第一个窗口)选择的图形的图形,默认情况下将显示第16个图形的第一个图形。我使用了here和here
中找到的代码我一直在研究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()