美文网首页
Python与LabVIEW初探:进程间通信

Python与LabVIEW初探:进程间通信

作者: azpo2009_198e | 来源:发表于2018-09-27 22:13 被阅读0次

    2018年5月30日


    上文提到了Python在进行数据处理方面的便利,与LabVIEW在仪器通信方面的广泛应用。结合两者的优势,可以方便实现高灵活性的功能,此时,实现两者进程间的通信就显得格外重要。实现Python与LabVIEW间的数据传输有许多种不同方法,这里将采用简单的UDP通信来交换数据,Python与LabVIEW分别作为客户端与服务端工作,下面以一个测量激光器实际功率的简单程序来说明Python与LabVIEW结合的强大。

    实验背景

    进行实验分析时需要得知激光器在不同设定电流下的光功率,需要对激光器设定一系列电流值,然后记录功率计测量得到的光功率。

    功能分析

    主要功能分为两部分,一部分为设定电流值与记录光功率,另一部分为UDP通信。
    设定电流值可以简单粗暴的使用pywinauto库与keyboard库来实现,步骤为1、pywinauto选择窗口并最大化,2、keyboard输入电流值。纪录光功率需要连接功率计,此处通过LabVIEW的VISA资源与功率计通信,然后调用测量光功率的子VI得到功率值。这两块的功能通过调用Python和LabVIEW各自的库函数可以实现,出于页面简洁的理由这部分代码就省略了,仅仅展示UDP通信部分。
    UDP通信部分仅需要实现简单的数据通信功能,Python部分使用sendto()recvfrom();LabVIEW部分首先打开选定端口号的UDP服务,然后调用读取UDP与写入UDP的子VI。
    总体的工作流程图如下:

    测量激光器光功率工作流程图

    需求实现

    本例中,Python和LabVIEW两部分的功能都十分简单,所以在各自UDP通信的示例上稍作修改就可以满足要求,首先是Python部分的代码:

    import signal
    import threading
    import sys
    
    import socket
    
    
    # 创建Socket,SOCK_DGRAM指定了这个Socket的类型是UDP
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
    # 绑定端口:
    s.bind(('127.0.0.1', 61557))
    # 设置接收超时,此时间应大于服务端完成一次采样的时间
    s.settimeout(1)    
    print('Bind UDP on 61557...')
    
    # 定义按下Ctrl+C时退出的处理
    def client_exit(num, frame):
        print("退出数据收集")
        s.close()    # 关闭Socket
        sys.exit(0)
    
    signal.signal(signal.SIGINT, client_exit)    # 对于KeyboardInterrupt的handlder处理
    exit = threading.Event()    # 创建一个event
    
    while not exit.is_set():    # 当exit事件没有set时,循环运行
        s.sendto(b'Client ready.',('127.0.0.1', 61556))    # 向服务端发送数据
        try:
            data, addr = s.recvfrom(1024)    # 接收服务端发送的数据
            print('Received from %.4e:%s.' % (float(data),addr))
        except socket.timeout:
            pass
    

    代码相对直观,while循环前都是一些对象的初始化过程,while循环中包括了客户端发送准备信号和接收服务端数据的socket函数,在接收到服务端发送的data数据之后就可以进行相应处理了。像本例中就是通过while循环遍历包含不同设定电流的列表,然后在单次循环中从LabVIEW服务端接收得到电流对应的光功率,存储在对应的光功率列表中,最后就实现了扫描记录光功率的功能。
    另外是LabVIEW部分的代码,基本上也是在LabVIEW自带的UDP通信示例上稍作修改得到的。LabVIEW服务端运行在循环中,当接收到Python客户端发送的数据时开始采集数据,这里调用的VI是光功率计单次测量功率的VI(PM100D Measure Power.vi),也可以改成别的VI例如产生随机数,采集完成后将得到的浮点数转化为字符串,通过UDP发送回Python客户端。

    LabVIEW示例-更新数据

    当客户端没有发送数据时,忽略超时错误,继续循环。

    LabVIEW示例-忽略超时

    此时先开始运行LabVIEW服务端,然后运行Python客户端,就可以实现两者间的进程通信,在LabVIEW端和Python端可以看到相互发送的字符串。

    参考:
    1、UDP编程-廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432004977916a212e2168e21449981ad65cd16e71201000
    2、LabVIEW示例:SimpleUDP

    全文完


    相关文章

      网友评论

          本文标题:Python与LabVIEW初探:进程间通信

          本文链接:https://www.haomeiwen.com/subject/zsoidftx.html