提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
Moku:Go是Liquid Instruments公司为新理工科人才培养提供的完善工程实验教学解决方案,满足从强化基础教学到自主创新人才培养的课程体系。 Moku:Go集成8个仪器功能并提供选配可编程电源,取代笨重、繁琐的传统台式测量设备。学生可以将全套实验室装入书包,无论身在何处随时随地都可以学习。 Moku:Go可以通过自带Wi-Fi热点连接操控,集成了可靠,具有电气保护的信号接口,USB-C用作电源接口以及高速数据传输,以及6种可选颜色。Windows和Mac端的操作软件提供易用且直观的图形用户界面,还可以通过API与课程集成。 Moku:Go硬件以软件设计充分考虑了用户需求,确保学生获得完整、连贯的四年学习及课外实践体验。
本篇文章将从Moku:Go M1的基础使用入手,见识见识未来电子信息专业学生是如何进行实验的。
一、Moku:Go初上手
LI官网网址:http://www.li.market/,在“获取平台详情”选项中可以找到各类文档、Moku软件和各类API的使用方式。
将Moku:Go磁吸式电源插上电后,经过短暂的等待,黄灯变为绿灯,即代表它已经正式开启。然后就可以通过配套的数据线、或是用WIFI直接连接(硬件背后有该Moku:Go的编号和WIFI密码)的方式第一次连接Moku:Go。在设置界面可以修改设备名、修改密码,连接外界WIFI并手动分配IP地址等等,此后就可以通过寝室WIFI去访问它了,并且也有了远程控制(不需要去连设备本身的WIFI)的可能性。
时至今日,Moku:Go M1已经能够提供诸如示波器、频谱分析仪等11种仪器、功能以及自身具有的两通道可编程电源。不得不说的是它的界面相比于传统设备确实新颖了很多。
上图是PID控制器界面,支持两通道输入输出,对应Moku:Go M1的两通道模拟输入和输出。可同时进行两路PID调控,但由于仅支持两路输入,所以两路PID调控在这里的作用更多的是进行对比。(一般两路输入分别是当前量和目的量,通过PID控制让当前量趋于目的量,或是两者之差趋于零)
Moku:Go的界面简单易懂,并且输入输出口都是和常规的实验设备一样的,还是很好上手的。
二、Python API的使用
先来网址:https://apis.liquidinstruments.com/starting-python.html
大致就是说要求python3.5以上,pip install moku然后moku download就好了。
在当前你可能会下载版本2.4的API,而Moku:Go硬件可能只到2.2,所以某些函数可能会出现库里有,用不了。库里已经删了,你也用不了的情况出现。笔者当前没有试过去下旧版本的库,大部分还是能用的,小部分对照着官网文档和函数描述改一改就可以了。
大致使用方式:
$: python
>>> from moku.instruments import Oscilloscope
>>> osc = Oscilloscope('192.168.123.45')
>>> data = osc.get_data()
>>> print(data['ch1'], data['ch2'], data['time'])
通过get_data函数就获得了近时间内Moku:Go采集到的数据了,是包含两通道输出数值、对应时间的python字典形式。
调用get_data函数本身需要消耗不少时间,大概为0.3S左右。这与它数据读取的机制有关,当前不能确定的说法是:Python API读取Moku:Go数据是通过访问其开启的http服务实现的(因为某次不经意的报错告知http出现问题)。Moku:Go并没有建立更快速、持续的连接,所以目前不能通过Python API完成远程数据的实时读取。
通过这样的现象,笔者也猜测:Python API、Matlab API等方式,都只是对某一种方式的套壳,就比如是http的方式。只不过是调换了编程方式,本质过程没有改变,这也比较符合“接口”这一词。
对于设备的初始化函数:
osc = Oscilloscope('192.168.10.200',force_connect=False)
默认参数force_connect=False会让你在大部分情况下是连不上Moku:Go的(报错,当前API正有用户在使用),因为之前的用户没有接触占用(特别是使用Python API时),根据官方文档来说,要使用下面这句话,但大多时候似乎也是没用的。
osc.relinquish_ownership()
这里也就得提一嘴,Multi-Instruments功能还没有上线,说人话就是现在你还不能一边使用示波器、一边使用频谱分析仪。当你电脑软件在线时,你也不能通过Python API直接使用(不强制连接),否则会将电脑端踢下线。所以既要使用Python API,又要查看波形就得用Python相关的库去绘制。这里给出一个使用pyqtgraph绘图的小demo。
import pyqtgraph as pg
from moku.instruments import PIDController
import time
name = "Input2"
pid = PIDController('192.168.10.200', force_connect=True)
# 获取pid数据的定时回调函数
def get_pid_data():
time1 = time.time()
info = pid.get_data()
time2 = time.time()
print("耗时:", time2 - time1)
x = info['time']
y = info['ch1']
# print(x[int(len(x) / 2)])
# print(y[int(len(x) / 2)])
plot.setData(x, y, pen='g')
if __name__ == '__main__':
pid.set_monitor(1, name)
pid.set_control_matrix(1, input_gain1=1, input_gain2=-1)
pid.set_control_matrix(1, input_gain1=0, input_gain2=1)
# pyqt's初始化
# 创建窗口
app = pg.mkQApp() # 建立app
win = pg.GraphicsWindow() # 建立窗口
win.setWindowTitle(u'pyqtgraph 实时波形显示工具')
win.resize(800, 500) # 小窗口大小
# 创建图表
historyLength = 100 # 横坐标长度
p = win.addPlot() # 把图p加入到窗口中
p.showGrid(x=True, y=True) # 把X和Y的表格打开
p.setRange(yRange=[-5, 5], padding=0)
p.setLabel(axis='left', text='电压') # 靠左
p.setLabel(axis='bottom', text='时间')
p.setTitle('PID') # 表格的名字
plot = p.plot()
timer = pg.QtCore.QTimer()
timer.timeout.connect(get_pid_data) # 定时刷新数据显示
timer.start(50) # 多少ms调用一次
app.exec_()
或者使用python中matlab绘图库。下述代码是从官方PID控制器例程中改过来的,保留了部分注释。(笔者自己写是不会有注释的哈哈)
# moku example: PID Controller Plotting Example
#
# This script demonstrates how to configure both PID Controllers
# in the PID Controller instrument. Configuration on the Channel 1
# PID is done by specifying frequency response characteristics,
# while Channel 2 specifies the gain characteristics.
#
# The output response of each PID Controller channel is plotted
# in real-time.
#
# (c) 2021 Liquid Instruments Pty. Ltd.
#
import matplotlib.pyplot as plt
from moku.instruments import PIDController
# Connect to your Moku by its ip address using PIDController('192.168.###.###')
# or by its serial number using PIDController(serial=123)
i = PIDController('192.168.10.200', force_connect=False)
try:
# Configures the control matrix:
# Channel 1: input 1 gain = 1 dB, input 2 gain = 0 dB
# Channel 2: input 2 gain = 0 dB, input 2 gain = 1 dB
i.set_control_matrix(channel=1, input_gain1=1, input_gain2=0)
i.set_control_matrix(channel=2, input_gain1=0, input_gain2=1)
# Configure the Channel 1 PID Controller using frequency response
# characteristics
# P = -10dB
# I Crossover = 100Hz
# D Crossover = 10kHz
# I Saturation = 10dB
# D Saturation = 10dB
# Double-I = OFF
# Note that gains must be converted from dB first
i.set_by_frequency(channel=1, prop_gain=-10, int_crossover=1e2,
diff_crossover=1e4, int_saturation=10,
diff_saturation=10)
# Configure the Channel 2 PID Controller using gain characteristics
# Overall Gain = 6dB
# I Gain = 20dB
i.set_by_gain(channel=2, overall_gain=6.0, prop_gain=20)
# Set the probes to monitor Output 1 and Output 2
i.set_monitor(1, 'Output1')
i.set_monitor(2, 'Output2')
# Set the timebase
i.set_timebase(-1e-3, 1e-3) # +- 1msec
#i.set_trigger(type='Edge', source='Input1', level=0)
# Enable the output channels of the PID controller
i.enable_output(1, True, True)
i.enable_output(2, True, True)
# Get initial data frame to set up plotting parameters. This can be done
# once if we know that the axes aren't going to change (otherwise we'd do
# this in the loop)
data = i.get_data()
# Set up the plotting parameters
plt.ion()
plt.show()
plt.grid(b=True)
plt.ylim([-1, 1])
plt.xlim([data['time'][0], data['time'][-1]])
line1, = plt.plot([])
line2, = plt.plot([])
# Configure labels for axes
ax = plt.gca()
# This loops continuously updates the plot with new data
while True:
# Get new data
data = i.get_data()
# Update the plot
line1.set_ydata(data['ch1'])
line2.set_ydata(data['ch2'])
line1.set_xdata(data['time'])
line2.set_xdata(data['time'])
plt.pause(0.001)
except Exception as e:
print(f'Exception occurred: {e}')
finally:
# Close the connection to the Moku device
# This ensures network resources and released correctly
i.relinquish_ownership()
记得把IP地址改成你自己手动或是DHCP分配的就好了。在设置界面就能看到Moku:Go当前的IP。
总结
虽然Moku:Go当前不是非常的全面,特别是不能多仪器并行是非常大的一个槽点,但“片上仪器”这种思想还是非常值得肯定的。对于学生来讲,使用灵活好用的界面、编程控制仪器等等都是很不错的体验,就看未来它会如何继续发展了。