Skip to content

Commit d9e5380

Browse files
committed
Add API documentation and tutorial for the radio module.
1 parent 45a4398 commit d9e5380

File tree

10 files changed

+355
-12
lines changed

10 files changed

+355
-12
lines changed

docs/ble.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
Bluetooth
22
*********
33

4-
While the BBC micro:bit has Bluetooth Low Energy (BLE) hardware it only has
5-
16k of RAM. The BLE stack alone takes up 12k RAM which means there's not enough
6-
room to (currently) run MicroPython.
4+
While the BBC micro:bit has hardware capable of allowing the device to work as
5+
a Bluetooth Low Energy (BLE) device, it only has 16k of RAM. The BLE stack
6+
alone takes up 12k RAM which means there's not enough room to run MicroPython.
77

88
Future versions of the device may come with 32k RAM which would be sufficient.
99
However, until such time it's highly unlikely MicroPython will support BLE.
10+
11+
.. note::
12+
MicroPython uses the radio hardware with the ``radio`` module. This allows
13+
users to create simple yet effective wireless networks of micro:bit
14+
devices.
15+
16+
Furthermore, the protocol used in the ``radio`` module is a lot simpler
17+
than BLE, making it far easier to use in an educational context.

docs/index.rst

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Projects related to MicroPython on the BBC micro:bit include:
4848
tutorials/direction
4949
tutorials/storage
5050
tutorials/network
51+
tutorials/radio
5152
tutorials/next
5253

5354
.. toctree::
@@ -56,21 +57,22 @@ Projects related to MicroPython on the BBC micro:bit include:
5657

5758
microbit_micropython_api.rst
5859
microbit.rst
59-
pin.rst
60-
music.rst
61-
image.rst
62-
compass.rst
6360
accelerometer.rst
61+
ble.rst
6462
button.rst
63+
compass.rst
6564
display.rst
66-
i2c.rst
67-
uart.rst
68-
spi.rst
6965
filesystem.rst
66+
i2c.rst
67+
image.rst
68+
music.rst
69+
neopixel.rst
7070
os.rst
71+
pin.rst
72+
radio.rst
7173
random.rst
72-
neopixel.rst
73-
ble.rst
74+
spi.rst
75+
uart.rst
7476

7577
.. toctree::
7678
:maxdepth: 2

docs/radio.rst

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
Radio
2+
*****
3+
4+
.. py:module:: radio
5+
6+
The ``radio`` module allows devices to work together via simple wireless
7+
networks.
8+
9+
The radio module is conceptually very simple:
10+
11+
* Broadcast messages are of a certain configurable length (up to 251 bytes).
12+
* Messages received are read from a queue of configurable size (the larger the queue the more RAM is used). If the queue is full, new messages are ignored.
13+
* Messages are broadcast and received on a preselected channel (numbered 0-100).
14+
* Broadcasts are at a certain level of power - more power means more range.
15+
* Messages are filtered by address (like a house number) and group (like a named recipient at the specified address).
16+
* The rate of throughput can be one of three pre-determined settings.
17+
* Send and receieve bytes to work with arbitrary data.
18+
* As a convenience for children, it's easy to send and receive messages as strings.
19+
* The default configuration is both sensible and compatible with other platforms that target the BBC micro:bit.
20+
21+
To access this module you need to::
22+
23+
import radio
24+
25+
We assume you have done this for the examples below.
26+
27+
Constants
28+
=========
29+
30+
.. py:attribute:: RATE_250KBIT
31+
32+
Constant used to indicate a throughput of 256 Kbit a second.
33+
34+
.. py:attribute:: RATE_1MBIT
35+
36+
Constant used to indicate a throughput of 1 MBit a second.
37+
38+
.. py:attribute:: RATE_2MBIT
39+
40+
Constant used to indicate a throughput of 2 MBit a second.
41+
42+
43+
Functions
44+
=========
45+
46+
.. py:function:: on()
47+
48+
Turns the radio on. This needs to be explicitly called since the radio
49+
draws power and takes up memory that you may otherwise need.
50+
51+
.. py:function:: off()
52+
53+
Turns off the radio, thus saving power and memory.
54+
55+
.. py:function:: config(**kwargs)
56+
57+
Configures various keyword based settings relating to the radio. The
58+
available settings and their sensible default values are listed below.
59+
60+
The ``length`` (default=32) defines the maximum length, in bytes, of a
61+
message sent via the radio. It can be up to 251 bytes long (254 - 3 bytes
62+
for S0, LENGTH and S1 preamble).
63+
64+
The ``queue`` (default=3) specifies the number of messages that can be
65+
stored on the incoming message queue. If there are no spaces left on the
66+
queue for incoming messages, then the incoming message is dropped.
67+
68+
The ``channel`` (default=7) can be an integer value from 0 to 100
69+
(inclusive) that defines an arbitrary "channel" to which the radio is
70+
tuned. Messages will be sent via this channel and only messages received
71+
via this channel will be put onto the incoming message queue. Each step is
72+
1MHz wide, based at 2400MHz.
73+
74+
The ``power`` (default=0) is an integer value from 0 to 7 (inclusive) to
75+
indicate the strength of signal used when broadcasting a message. The
76+
higher the value the stronger the signal, but the more power is consumed
77+
by the device. The numbering translates to positions in the following list
78+
of dBm (decibel milliwatt) values: -30, -20, -16, -12, -8, -4, 0, 4.
79+
80+
The ``address`` (default=0x75626974) is an arbitrary name, expressed as a
81+
32-bit address, that's used to filter incoming packets at the hardware
82+
level, keeping only those that match the address you set. The default used
83+
by other micro:bit related platforms is the default setting used here.
84+
85+
The ``group`` (default=0) is an 8-bit value (0-255) used with the
86+
``address`` when filtering messages. Conceptually, "address" is like a
87+
house/office address and "group" is like the person at that address to
88+
which you want to send your message.
89+
90+
The ``data_rate`` (default=radio.RATE_1MBIT) indicates the speed at which
91+
data throughput takes place. Can be one of the following contants defined
92+
in the ``radio`` module : ``RATE_250KBIT``, ``RATE_1MBIT`` or
93+
``RATE_2MBIT``.
94+
95+
If ``config`` is not called then the defaults described above are assumed.
96+
97+
.. py:function:: reset()
98+
99+
Reset the settings to their default values (as listed in the documentation
100+
for the ``config`` function above).
101+
102+
.. note::
103+
104+
None of the following send or receive methods will work until the radio is
105+
turned on.
106+
107+
.. py:function:: send_bytes(message)
108+
109+
Sends a message containing bytes.
110+
111+
.. py:function:: receive_bytes()
112+
113+
Receive the next incoming message on the message queue. Returns ``None`` if
114+
there are no pending messages. Messages are returned as bytes.
115+
116+
.. py:function:: send(message)
117+
118+
Sends a message string. This is the equivalent of
119+
``send_bytes(bytes(message, 'utf8'))`` but with ``b'\x01\x00\x01'``
120+
prepended to the front (to make it compatible with other platforms that
121+
target the micro:bit).
122+
123+
.. py:function:: receive()
124+
125+
Works in exactly the same way as ``receive_bytes`` but returns
126+
whatever was sent.
127+
128+
Currently, it's equivalent to ``str(receive_bytes(), 'utf8')`` but with a
129+
check that the the first three bytes are ``b'\x01\x00\x01'`` (to make it
130+
compatible with other platforms that may target the micro:bit). It strips
131+
the prepended bytes before converting to a string.
132+
133+
A ``ValueError`` exception is raised if conversion to string fails.
134+
135+
Examples
136+
--------
137+
138+
.. include:: ../examples/radio.py
139+
:code: python

docs/tutorials/binary_count.gif

113 KB
Loading

docs/tutorials/fireflies.gif

715 KB
Loading

docs/tutorials/firefly.gif

453 KB
Loading

docs/tutorials/introduction.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Introduction
1616
direction
1717
storage
1818
network
19+
radio
1920
next
2021

2122
Python is one of the `world's most popular <http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html>`_ programming languages. Every day, without

docs/tutorials/mb-firefly.gif

1.09 MB
Loading

docs/tutorials/radio.rst

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
Radio
2+
-----
3+
4+
Interaction at a distance feels like magic.
5+
6+
Magic might be useful if you're an elf, wizard or unicorn, but such things only
7+
exist in stories.
8+
9+
However, there's something much better than magic: physics!
10+
11+
Wireless interaction is all about physics: radio waves (a type of
12+
electromagnetic radiation, similar to visible light) have some sort of property
13+
(such as their amplitude, phase or pulse width) modulated by a transmitter in
14+
such a way that information can be encoded and, thus, broadcast. When radio
15+
waves encounter an electrical conductor (i.e. an aerial), they cause an
16+
alternating current from which the information in the waves can be extracted
17+
and transformed back into its original form.
18+
19+
Layers upon Layers
20+
++++++++++++++++++
21+
22+
If you remember, networks are built in layers.
23+
24+
The most fundamental requirement for a network is some sort of connection that
25+
allows a signal to get from one device to the other. In our networking
26+
tutorial we used wires connected to the I/O pins. Thanks to the radio module we
27+
can do away with wires and use the physics summarised above as the invisible
28+
connection between devices.
29+
30+
The next layer up in the network stack is also different from the example in
31+
the networking tutorial. With the wired example we used digital on and off to
32+
send and read a signal from the pins. With the built-in radio on the
33+
micro:bit the smallest useful part of the signal is a byte.
34+
35+
Bytes
36+
+++++
37+
38+
A byte is a unit of information that (usually) consists of eight bits. A bit is
39+
the smallest possible unit of information since it can only be in two states:
40+
on or off.
41+
42+
Bytes work like a sort of abacus: each position in the byte is like a
43+
column in an abacus - they represent an associated number. In an abacus these
44+
are usually thousands, hundreds, tens and units (in UK parlance). In a byte
45+
they are 128, 64, 32, 16, 8, 4, 2 and 1. As bits (on/off
46+
signals) are sent over the air, they are re-combined into bytes by the
47+
recipient.
48+
49+
Have you spotted the pattern? (Hint: base 2.)
50+
51+
By adding the numbers associated with the positions in a byte that are set to
52+
"on" we can represent numbers between 0 and 255. The image below shows how this
53+
works with five bits and counting from zero to 32:
54+
55+
.. image:: binary_count.gif
56+
57+
If we can agree what each one of the 255 numbers (encoded by a byte) represents ~ such as a character ~ then we can start to send text one character per byte
58+
at a time.
59+
60+
Funnily enough, people have already
61+
`thought of this <https://en.wikipedia.org/wiki/ASCII>`_ ~ using bytes to
62+
encode and decode information is commonplace. This approximately corresponds to
63+
the Morse-code "protocol" layer in the wired networking example.
64+
65+
A really great series of child (and teacher) friendly explanations of "all
66+
things bytes" can be found at the
67+
`CS unplugged <http://csunplugged.org/binary-numbers/>`_ website.
68+
69+
Addressing
70+
++++++++++
71+
72+
The problem with radio is that you can't transmit directly to one person.
73+
Anyone with an appropriate aerial can receive the messages you transmit. As a
74+
result it's important to be able to differentiate who should be receiving
75+
broadcasts.
76+
77+
The way the radio built into the micro:bit solves this problem is quite simple:
78+
79+
* It's possible to tune the radio to different channels (numbered 0-100). This works in exactly the same way as kids' walkie-talkie radios: everyone tunes into the same channel and everyone hears what everyone else broadcasts via that channel. As with walkie-talkies, if you use adjacent channels there is a slight possibility of interference.
80+
81+
* The radio module allows you to specify two pieces of information: an address and a group. The address is like a postal address whereas a group is like a specific recipient at the address. The important thing is the radio will filter out messages that it receives that do not match *your* address and group. As a result, it's important to pre-arrange the address and group your application is going to use.
82+
83+
Of course, the micro:bit is still receiving broadcast messages for other
84+
address/group combinations. The important thing is you don't need to worry
85+
about filtering those out. Nevertheless, if someone were clever enough, they
86+
could just read *all the wireless network traffic* no matter what the target
87+
address/group was supposed to be. In this case, it's *essential* to use
88+
encrypted means of communication so only the desired recipient can actually
89+
read the message that was broadcast. Cryptography is a fascinating subject but,
90+
unfortunately, beyond the scope of this tutorial.
91+
92+
Fireflies
93+
+++++++++
94+
95+
This is a firefly:
96+
97+
.. image:: firefly.gif
98+
99+
It's a sort of bug that uses bioluminescence to signal (without wires) to its
100+
friends. Here's what they look like when they signal to each other:
101+
102+
.. image:: fireflies.gif
103+
104+
The BBC have `rather a beautiful video <http://www.bbc.com/earth/story/20160224-worlds-largest-gathering-of-synchronised-fireflies>`_ of fireflies available online.
105+
106+
We're going to use the radio module to create something akin to a swarm of
107+
fireflies signalling to each other.
108+
109+
First ``import radio`` to make the functions available to your Python program.
110+
Then call the ``radio.on()`` function to turn the radio on. Since
111+
the radio draws power and takes up memory we've made it so *you* decide
112+
when it is enabled (there is, of course a ``radio.off()`` function).
113+
114+
At this point the radio module is configured to sensible defaults that make
115+
it compatible with other platforms that may target the BBC micro:bit. It is
116+
possible to control many of the features discussed above (such as channel and
117+
addressing) as well as the amount of power used to broadcast messages and the
118+
amount of RAM the incoming message queue will take up. The API documentation
119+
contains all the information you need to configure the radio to your needs.
120+
121+
Assuming we're happy with the defaults, the simplest way to send a message is
122+
like this::
123+
124+
radio.send("a message")
125+
126+
The example uses the ``send`` function to simply broadcast the string
127+
"a message". To receive a message is even easier::
128+
129+
new_message = radio.receive()
130+
131+
As messages are received they are put on a message queue. The ``receive``
132+
function returns the oldest message from the queue as a string, making space
133+
for a new incoming message. If the message queue fills up, then new incoming
134+
messages are ignored.
135+
136+
That's really all there is to it! (Although the radio module is also powerful
137+
enough that you can send any arbitrary type of data, not just strings. See the
138+
API documentation for how this works.)
139+
140+
Armed with this knowledge, it's simple to make micro:bit fireflies like this:
141+
142+
.. include:: ../../examples/radio.py
143+
:code: python
144+
145+
The import stuff happens in the event loop. First, it checks if button A was
146+
pressed and, if it was, uses the radio to send the message "flash". Then it
147+
reads any messages from the message queue with ``radio.receive()``. If there is
148+
a message it sleeps a short, random period of time (to make the display more
149+
interesting) and uses ``display.show()`` to animate a firefly flash. Finally,
150+
to make things a bit exciting, it chooses a random number so that it has a 1 in
151+
10 chance of re-broadcasting the "flash" message to anyone else (this is how
152+
it's possible to sustain the firefly display among several devices). If it
153+
decides to re-broadcast then it waits for half a second (so the display from
154+
the initial flash message has chance to die down) before sending
155+
the "flash" signal again. Because this code is enclosed within a ``while True``
156+
block, it loops back to the beginning of the event loop and repeats this
157+
process forever.
158+
159+
The end result (using a group of micro:bits) should look something like this:
160+
161+
.. image:: mb-firefly.gif
162+
163+
.. footer:: The image of binary counting is released under the licensing details listed here: https://en.wikipedia.org/wiki/File:Binary_counter.gif

0 commit comments

Comments
 (0)