由来

很久以前, 翻到了JO32KF的WebSDR, 我靠好先进啊,

JO32KF的WebSDR截图

我也想做一个, 于是调查了一下, 支持GNURadio的硬件好贵... 然后就发现了超级便宜的RTL-SDR, x宝搞定一个.

淘宝RTL-SDR截图

买回来后, 确实很好玩, 可以听到对讲机, 看到飞机起降, 有意思! 想着自己做个FM解调玩玩吧, 大概调查后发现难度不小. 那么就先从简单的开始做, RTL-SDR有Python的接口, 那么就先在Python上实现一个能实时显示信号的程序吧.

我的路线图:

  1. 随机信号 <- 本文内容
  2. 麦克风频谱图
  3. RTL-SDR频谱图
  4. FM解调

实现

Python上要画图, 当然我先想到的是matplotlib, 如果他可以, 那就不用在那些做GUI的软件包中找了. 它就是, matplotlib.animation. 下面列出一些大侠们的blog post.

此外,还有Matplotlib的官方例子.

在试了一遍后, 我发现大多数的例子都是先准备好数据, 然后再来animation, 如官方的basic_example.py例子.

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def update_line(num, data, line):   #该函数用于每次调用时生成每一帧的plot
    line.set_data(data[...,:num])
    return line,

fig1 = plt.figure()                 #创建一个存放plot的Figure.

data = np.random.rand(2, 25)        #初始化data,两个数一组,共25组.
l, = plt.plot([], [], 'r-')         #先画一个空的plot
plt.xlim(0, 1)                      #限定plot范围
plt.ylim(0, 1)
plt.xlabel('x')
plt.title('test')
line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
    interval=50, blit=True)         #开始动画.
#line_ani.save('lines.mp4')

这个程序生成了25帧的数据, 然后在animation.FuncAnimation中只生产25帧plot, 在调用update_line时, num会从1到25, 这样就画出了变化的图形,而且每25帧重复.

那么也就是说把frames设为1,应当就可以显示不同的数据,且每次都清屏. 而在update_line函数中把要显示的数据return回去就可以了.

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.lines as line

fig = plt.figure()
ax = plt.axes(xlim=(0,10), ylim=(0,1))
linem = line.Line2D([],[])

def init():
    ax.add_line(linem)
    return linem,

def update(i):
    linem.set_xdata(np.arange(0,10,1))
    linem.set_ydata(np.random.rand(10))
    return linem,

fig.show()

ani = animation.FuncAnimation(fig, update,
                              init_func=init,
                              frames=1,
                              interval=1,
                              blit=True)

raw_input("wait")

程序运行截图

嗯~看起来简单, 调了两天哦~ init函数是必须的, 在blit使能时, 如没有init函数, animation会将update的第一帧作为初始话, 你就会看到一个不消失的曲线. 而那个奇怪的return linem,意思是返回一个unpack的tuple,参考stackoverflow 而为什么要返回这个奇怪的东西, 我也是大概理解, animation的API文档.

If blit=True, func and init_func should return an iterable of drawables to clear.

需要注意的是, 这个Animation与Python执行的环境有很大关系, 我在windows的cmd下和在spyder下运行效果有区别. 因此如果你的代码不行, 可以试试换个执行环境.


Comments

comments powered by Disqus