无线电

远距离互动感觉就像魔术一样。

如果您是精灵、巫师或独角兽,魔法可能会很有用,但这些东西只存在于故事中。

然而,还有比魔法更好的东西:物理学!

无线交互完全是关于物理学的:无线电波(一种电磁辐射,类似于可见光)具有某种属性(例如它们的幅度、相位或脉冲宽度),由发射器以可以编码信息的方式进行调制因此,广播。当无线电波遇到电导体(即天线)时,它们会产生交流电,从中可以提取电波中的信息并将其转换回其原始形式。

层层叠叠

如果您还记得,网络是分层构建的。

网络最基本的要求是某种连接,允许信号从一个设备传递到另一个设备。在我们的网络教程中,我们使用连接到 I/O 引脚的电线。多亏了无线电模块,我们可以摆脱电线并使用上面总结的物理作为设备之间的无形连接。

网络堆栈中的下一层也与网络教程中的示例不同。在有线示例​​中,我们使用数字开关从引脚发送和读取信号。使用 micro:bit 上的内置收音机,信号的最小有用部分是一个字节。

字节

一个字节是一个信息单位,(通常)由八位组成。位是最小的信息单位,因为它只能处于两种状态:开或关。

字节就像算盘一样工作:字节中的每个位置就像算盘中的一列——它们代表一个相关联的数字。在算盘中,这些通常是千、百、十和单位(用英国的说法)。在一个字节中,它们是 128、64、32、16、8、4、2 和 1。当比特(开/关信号)通过空中发送时,它们被接收者重新组合成字节。

你发现规律了吗?(提示:基数 2。)

通过添加与设置为“on”的字节中的位置相关的数字,我们可以表示 0 到 255 之间的数字。下图显示了如何使用 5 位并从 0 计数到 32:

../_images/binary_count.gif

如果我们可以同意 255 个数字(由一个字节编码)中的每一个代表什么〜例如一个字符〜那么我们可以开始一次发送一个字符一个字符的文本。

有趣的是,人们已经 想到了这一点 ~ 使用字节来编码和解码信息是司空见惯的。这大致对应于有线网络示例中的莫尔斯电码“协议”层。

CS unplugged 网站上可以找到一系列非常棒的儿童(和老师)对“所有字节”的友好解释 。

寻址

无线电的问题在于你不能直接向一个人传输。任何拥有合适天线的人都可以接收您发送的信息。因此,能够区分谁应该接收广播很重要。

micro:bit 内置的收音机解决这个问题的方法很简单:

  • 可以将收音机调谐到不同的频道(编号为 0-83)。这与儿童对讲机收音机的工作方式完全相同:每个人都调到同一个频道,每个人都可以听到其他人通过该频道广播的内容。与对讲机一样,如果您使用相邻频道,则存在轻微干扰的可能性。
  • 无线电模块允许您指定两条信息:地址和组。地址就像邮政地址,而组就像地址的特定收件人。重要的是,收音机会过滤掉它收到的与您的地址和群组不匹配的消息。因此,预先安排您的应用程序将要使用的地址和组非常重要。

当然,micro:bit 还在接收其他地址/组组合的广播消息。重要的是你不需要担心过滤掉那些。尽管如此,如果有人足够聪明,无论目标地址/组应该是什么,他们都可以读取所有无线网络流量。在这种情况下,必须使用加密的通信方式,这样只有所需的收件人才能真正阅读广播的消息。密码学是一个引人入胜的主题,但不幸的是,超出了本教程的范围。

萤火虫

这是萤火虫:

../_images/firefly.gif

这是一种使用生物发光向其朋友发送信号(无需电线)的错误。以下是它们相互发送信号时的样子:

../_images/fireflies.gif

BBC 在网上有一段相当漂亮 的萤火虫视频。

我们将使用无线电模块来创建类似于一群萤火虫相互发送信号的东西。

首先使函数可用于您的 Python 程序。然后调用该函数打开收音机。由于收音机耗电并占用内存,我们已经制作了它,因此您可以决定何时启用它(当然有一个功能)。 import radio radio.on() radio.off()

此时,无线电模块已配置为合理的默认值,使其与可能针对 BBC micro:bit 的其他平台兼容。可以控制上面讨论的许多功能(例如通道和寻址)以及用于广播消息的功率量和传入消息队列将占用的 RAM 量。API 文档包含根据需要配置无线电所需的所有信息。

假设我们对默认值感到满意,发送消息的最简单方法是这样的:

radio.send("a message")

该示例使用该send函数来简单地广播字符串“a message”。接收消息更容易:

new_message = radio.receive()

当接收到消息时,它们被放置在消息队列中。该 receive函数以字符串形式返回队列中最旧的消息,为新传入的消息腾出空间。如果消息队列已满,则忽略新传入的消息。

这就是它的全部内容!(尽管无线电模块也足够强大,您可以发送任意类型的数据,而不仅仅是字符串。有关其工作原理,请参阅 API 文档。)

有了这些知识,就可以像这样制作 micro:bit 萤火虫:

# A micro:bit Firefly.
# By Nicholas H.Tollervey. Released to the public domain.
import radio
import random
from microbit import display, Image, button_a, sleep

# Create the "flash" animation frames. Can you work out how it's done?
flash = [Image().invert()*(i/9) for i in range(9, -1, -1)]

# The radio won't work unless it's switched on.
radio.on()

# Event loop.
while True:
    # Button A sends a "flash" message.
    if button_a.was_pressed():
        radio.send('flash')  # a-ha
    # Read any incoming messages.
    incoming = radio.receive()
    if incoming == 'flash':
        # If there's an incoming "flash" message display
        # the firefly flash animation after a random short
        # pause.
        sleep(random.randint(50, 350))
        display.show(flash, delay=100, wait=False)
        # Randomly re-broadcast the flash message after a
        # slight delay.
        if random.randint(0, 9) == 0:
            sleep(500)
            radio.send('flash')  # a-ha

重要的事情发生在事件循环中。首先,它检查按钮 A 是否被按下,如果按下,则使用无线电发送消息“flash”。然后它从消息队列中读取任何消息radio.receive()。如果有消息,它会休眠一小段随机时间(使显示更有趣)并用于display.show()动画萤火虫闪光。最后,为了让事情变得有点令人兴奋,它选择了一个随机数,这样它就有十分之一的机会向其他人重新广播“闪光”消息(这就是在多个设备之间维持萤火虫显示的可能方式) . 如果它决定重新广播,那么它会等待半秒钟(因此初始 flash 消息的显示有机会消失),然后再次发送“flash”信号。因为此代码包含在一个while True块,它循环回到事件循环的开头并永远重复这个过程。

最终结果(使用一组 micro:bits)应该是这样的:

../_images/mb-firefly.gif