2011年06月03日 星期五 11:44
版主在这篇文章中提到http://www.zeuux.org/group/scipython/bbs/content/6193/
“最近用Python写了一个从串口和一个模拟信号输入设备读入数据的程序,对Python的便利又加深了一层体会。串口读入数据用的是pyserial, 模拟信号输入设备则使用ctypes直接调用其DLL驱动。所有读入的数据都很容易转换成NumPy的数组,然后实现绘图显示、数据处理以及保存数据等功 能。整个程序一个文件,500多行而已。界面用的是TraitsUI、绘图用的是Chaco。
最初考虑用C#编写,结果发现C#在将字符串转换成数组,或者将数组快速保存成文件等方面都比较费事。而且界面也不灵活,绘图库ZedGraph用起来也不如Chaco方便。
我想用MATLAB去实现这样的功能可能会更麻烦。”
我很想学习一下您提到的这个通过这样一个输入 获得实时显示例子,不知道版主可不可以写在书中 或者在此处共享一下呢?
2011年06月03日 星期五 14:19
这是我最开始学习的时候写的例子,基本功能代码都是资料上的,功能很简单,有些代码也很初级。
实现的功能很简单,串口个仪器发指令,一起会返回数据,然后画图。
根据你的要求,还加了一句通过控制并口 LED亮下灯
# -*- coding:utf-8 -*-
from enthought.traits.api import HasTraits, Button, Bool, Str, on_trait_change, Int, Instance
from enthought.traits.ui.api import View, Item, Handler
import serial,threading
import enthought.chaco.shell as cs
import numpy as np
import matplotlib.pyplot as plt
from time import sleep
from enthought.chaco.api import Plot, ArrayPlotData
from enthought.enable.component_editor import ComponentEditor
from ctypes import windll
TERM = '\r\n'
class aa(HasTraits):
send = Button
draw = Button
draw_mat = Button
ok = Button
draw_line = Button
restart =Button
plot = Instance(Plot)
idx = Int(0)
command = Str
response = Str
config = Bool(False)
ser = serial.Serial()
view =View(
Item('command',label = u'输入命令'),
Item('send',label= u'发送'),
Item('response',label = u'返回信息', style="custom"),
Item('idx',label = u'检测点序号'),
Item('ok',label = u'确定一个点'),
Item('draw',label = u'画曲线'),
Item('draw_mat',label = u'画曲线'),
Item('draw_line',label = u'画直线'),
Item('restart',label = u'重新开始测量'),
Item('plot',editor=ComponentEditor(), show_label=False),
resizable = True,
width = 600,
height = 800,
title = u'Lake Shore Model 421 Gaussmeter 数据采集'
)
def __init__(self):
self.data = []
self.greturn = ''
self.flag = True
self.flag_text = False
self.ser.port = 2
self.ser.baudrate = 9600
self.ser.bytesize = serial.SEVENBITS
self.ser.parity = serial.PARITY_ODD
self.ser.stopbits = serial.STOPBITS_ONE
if self.ser.isOpen:
self.ser.close()
else:
pass
self.ser.open()
self.t = threading.Thread(target = self.readDate)
self.t.start()
#亮个灯
self.p = windll.inpout32
self.p.Out32(0x378, 16)
sleep(0.06)
self.p.Out32(0x378, 0)
sleep(0.1)
#亮个灯
def readDate(self):
text = ''
while self.flag:
text += self.ser.read(1)
if text.endswith("\r\n"):
print text
if self.flag_text:
self.greturn = text
self.idx = self.idx + 1
self.data.append([self.idx,np.float(self.greturn)])
self.response = self.response + str(self.idx) + ' ' + text
self.config = not self.config
else:self.response = u"发送命令为" + self.command + TERM + text
text = ''
else:
pass
def _restart_fired(self):
self.idx = 0
np.savetxt("Gaussmeter-Temp.csv",self.data)
self.data = []
self.config = not self.config
self.response = ''
def _send_fired(self):
print 'ok'
self.command = self.command.upper()
strCommand = self.command
self.ser.write(strCommand + TERM)
def _draw_fired(self):
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.sin(x)
cs.plot(x, y, "r-")
cs.title(u"First plot")
cs.ytitle(u"sin(x)")
cs.show()
def _draw_mat_fired(self):
x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)
plt.figure(figsize=(8,4))
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
plt.show()
def _ok_fired(self):
self.ser.write('FIELD?' + TERM)
self.flag_text = True
def _draw_line_fired(self):
np.savetxt("Gaussmeter.csv",self.data)
sleep(0.01)
self.data = np.loadtxt("Gaussmeter.csv")
x,y = self.data.T
plt.plot(x,y)
plt.xlabel("X")
plt.ylabel("Y-Gaussmeter")
plt.title("Lake Shore Gaussmeter")
plt.show()
def _config_changed(self):
x = []
y = []
for i in xrange(self.idx):
x.append(i)
y.append(self.data[i][1])
plotdata = ArrayPlotData(x=x, y=y)
plot = Plot(plotdata)
plot.plot(("x", "y"), type="line", color="red")
plot.plot(("x", "y"), type="scatter", color="red", marker = "circle", make_size = 2)
self.plot = plot
self.plotdata = plotdata
class closeHandler(Handler):
def close(self, info, is_ok):
if info.object.ser.isOpen:info.object.ser.close()
if info.object.flag:
info.object.flag = False
if info.object.t.isAlive():
info.object.t.join()
return True
super(closeHandler, self).close(info, is_ok)
if __name__ == "__main__":
a = aa()
a.configure_traits(handler=closeHandler())
2011年06月03日 星期五 14:40
恩恩 神速 学习了~
2011年06月03日 星期五 18:31
完整的例子的话,程序会比较长,你可以先看看如何用Chaco制作波形动画:
http://hyry.dip.jp:8000/scipybook/default/file/08-chaco/chaco_simple_line_anim.py
在那个时钟处理程序中添加从pyserial读入数据的代码就可以了。
等我有时间再写一个比较完整的例子。
2011年06月03日 星期五 21:37
先发一个通过串口控制的界面截图:
Zeuux © 2024
京ICP备05028076号