Python和科学计算认证群组  - 讨论区

标题:请教一个例子

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哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号