Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Branch with the V2 documentation #746

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1be9e87
docs: Update the docs to include the V2 API (#692)
microbit-mark Dec 3, 2020
71d5eef
Docs: update for V2 neopixel module (#694)
microbit-mark Dec 18, 2020
353e6e1
Docs: Speaker update and play() pin arguments (#695)
microbit-mark Dec 18, 2020
5357b8e
V2 docs: Remove is_on() from speaker. (#696)
microbit-carlos Dec 21, 2020
f9a37b4
V2 docs: Add pin set_touch_mode() (#701)
microbit-mark Jan 8, 2021
070e590
docs: Update Memory layout, Partial Flashing, Building for V2, BLE (#…
microbit-sam Feb 3, 2021
5774623
docs: Include V2 features in tutorials (#709)
microbit-mark Feb 24, 2021
c967053
docs: dev guide updates (#711)
microbit-mark Mar 16, 2021
eab72dd
docs: Indicate pin_speaker is only for PWM (#715)
microbit-mark Apr 7, 2021
79aced6
docs: Fix typo in neopixel, mumber -> number (#727)
microbit-matt-hillsdon Sep 23, 2021
8bc1fe8
docs: Add V2 microbit.set_volume() info. (#742)
microbit-carlos Apr 25, 2022
a870ff4
docs: Add note about possible 250kbit/sec radio rate in V2. (#744)
microbit-carlos Apr 29, 2022
8007c9e
docs: Add data logging API (#720)
microbit-mark Sep 5, 2022
8c107e9
docs: Add Power Management documentation. (#754)
microbit-carlos Sep 5, 2022
1e4265a
docs: Add Sound Effects documentation. (#753)
microbit-carlos Sep 6, 2022
44c2c1a
docs: Add missing `days` parameter to `microbit.run_every`. (#767)
microbit-carlos Sep 12, 2022
0d6f5b7
docs: Rename wave->waveform from SoundEffect. (#765)
microbit-carlos Sep 21, 2022
a538cb8
docs: Update Power Mgm to change run_every behaviour. (#769)
microbit-carlos Oct 24, 2022
202fab2
docs: Overwrite configued version always be '2' for v2-docs.
microbit-carlos Nov 15, 2022
8c42897
docs: Update URL to download arm-none-eabi-gcc. (#787)
microbit-carlos Dec 6, 2022
905577a
docs: Improve microphone description, add more info for `set_threshol…
microbit-carlos Apr 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 203 additions & 26 deletions docs/audio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,220 @@ Audio

.. py:module:: audio

This module allows you play sounds from a speaker attached to the micro:bit.
This module allows you play sounds with the micro:bit.

By default sound output will be via the edge connector on pin 0 and the
:doc:`built-in speaker <speaker>` (**V2**). You can connect wired headphones or
a speaker to pin 0 and GND on the edge connector to hear the sounds.

The ``audio`` module can be imported as ``import audio`` or accessed via
the ``microbit`` module as ``microbit.audio``.

In order to use the audio module you will need to provide a sound source.
There are three different kinds of audio sources that can be played using the
:py:meth:`audio.play` function:

1. `Built in sounds <#built-in-sounds-v2>`_ (**V2**),
e.g. ``audio.play(Sound.HAPPY)``
2. `Sound Effects <#sound-effects-v2>`_ (**V2**), a way to create custom sounds
by configuring its parameters::

my_effect = audio.SoundEffect(freq_start=400, freq_end=2500, duration=500)
audio.play(my_effect)

3. `Audio Frames <#audioframe>`_, an iterable (like a list or a generator)
of Audio Frames, which are lists of 32 samples with values from 0 to 255::

square_wave = audio.AudioFrame()
for i in range(16):
square_wave[i] = 0
square_wave[i + 16] = 255
audio.play([square_wave] * 64)

A sound source is an iterable (sequence, like list or tuple, or a generator) of
frames, each of 32 samples.
The ``audio`` modules plays samples at the rate of 7812.5 samples per second,
which means that it can reproduce frequencies up to 3.9kHz.

Functions
=========

.. py:function:: play(source, wait=True, pin=pin0, return_pin=None)

Play the source to completion.
Play the audio source to completion.

:param source: There are three types of data that can be used as a source:

- ``Sound``: The ``microbit`` module contains a list of
built-in sounds, e.g. ``audio.play(Sound.TWINKLE)``. A full list can
be found in the `Built in sounds <#built-in-sounds-v2>`_ section.
- ``SoundEffect``: A sound effect, or an iterable of sound effects,
created via the :py:meth:`audio.SoundEffect` class
- ``AudioFrame``: An iterable of ``AudioFrame`` instances as described
in the `AudioFrame Technical Details <#id2>`_ section

:param source: An iterable sound source, each element of which must be
an ``AudioFrame``.
:param wait: If ``wait`` is ``True``, this function will block until the
source is exhausted.
:param pin: Specifies which pin the speaker is connected to.
:param return_pin: Specifies a differential pin to connect to the speaker
instead of ground.

Classes
=======
:param pin: An optional argument to specify the output pin can be used to
override the default of ``pin0``. If we do not want any sound to play
we can use ``pin=None``.

:param return_pin: specifies a differential edge connector pin to connect
to an external speaker instead of ground. This is ignored for the **V2**
revision.

.. py:function:: is_playing()

:returns: ``True`` if audio is playing, otherwise returns ``False``.

.. py:function:: stop()

Stops all audio playback.


Built-in sounds **V2**
======================

The built-in sounds can be called using ``audio.play(Sound.NAME)``.

* ``Sound.GIGGLE``
* ``Sound.HAPPY``
* ``Sound.HELLO``
* ``Sound.MYSTERIOUS``
* ``Sound.SAD``
* ``Sound.SLIDE``
* ``Sound.SOARING``
* ``Sound.SPRING``
* ``Sound.TWINKLE``
* ``Sound.YAWN``

Sounds Example
--------------

::

from microbit import *

while True:
if button_a.is_pressed() and button_b.is_pressed():
# When pressing both buttons only play via the edge connector
audio.play(Sound.HELLO, pin=pin0)
elif button_a.is_pressed():
# On button A play a sound and when it's done show an image
audio.play(Sound.HAPPY)
display.show(Image.HAPPY)
elif button_b.is_pressed():
# On button B play a sound and show an image at the same time
audio.play(Sound.TWINKLE, wait=False)
display.show(Image.BUTTERFLY)

sleep(500)
display.clear()


Sound Effects **V2**
====================

.. py:class::
SoundEffect(freq_start=500, freq_end=2500, duration=500, vol_start=255, vol_end=0, waveform=WAVEFORM_SQUARE, fx=FX_NONE, shape=SHAPE_LOG)

An ``SoundEffect`` instance represents a sound effect, composed by a set of
parameters configured via the constructor or attributes.

All the parameters are optional, with default values as shown above, and
they can all be modified via attributes of the same name. For example, we
can first create an effect ``my_effect = SoundEffect(duration=1000)``,
and then change its attributes ``my_effect.duration = 500``.

:param freq_start: Start frequency in Hertz (Hz), default: ``500``
:param freq_end: End frequency in Hertz (Hz), default: ``2500``
:param duration: Duration of the sound (ms), default: ``500``
:param vol_start: Start volume value, range 0-255, default: ``255``
:param vol_end: End volume value, range 0-255, default: ``0``
:param waveform: Type of waveform shape, one of these values:
``WAVEFORM_SINE``, ``WAVEFORM_SAWTOOTH``, ``WAVEFORM_TRIANGLE``,
``WAVEFORM_SQUARE``, ``WAVEFORM_NOISE`` (randomly generated noise).
Default: ``WAVEFORM_SQUARE``
:param fx: Effect to add on the sound, one of the following values:
``FX_TREMOLO``, ``FX_VIBRATO``, ``FX_WARBLE``, or ``FX_NONE``.
Default: ``FX_NONE``
:param shape: The type of the interpolation curve between the start and end
frequencies, different wave shapes have different rates of change
in frequency. One of the following values: ``SHAPE_LINEAR``,
``SHAPE_CURVE``, ``SHAPE_LOG``. Default: ``SHAPE_LOG``

.. py:function:: copy()

:returns: A copy of the SoundEffect.

.. py:attribute:: freq_start

Start frequency in Hertz (Hz), a number between ``0`` and ``9999``.

.. py:attribute:: freq_end

End frequency in Hertz (Hz), a number between ``0`` and ``9999```.

.. py:attribute:: duration

Duration of the sound in milliseconds, a number between ``0`` and
``9999``.

.. py:attribute:: vol_start

Start volume value, a number between ``0`` and ``255``.

.. py:attribute:: vol_end

End volume value, a number between ``0`` and ``255``.

.. py:attribute:: waveform

Type of waveform shape, one of these values: ``WAVEFORM_SINE``,
``WAVEFORM_SAWTOOTH``, ``WAVEFORM_TRIANGLE``, ``WAVEFORM_SQUARE``,
``WAVEFORM_NOISE`` (randomly generated noise).

.. py:attribute:: fx

Effect to add on the sound, one of the following values:
``FX_TREMOLO``, ``FX_VIBRATO``, ``FX_WARBLE``, or ``None``.

.. py:attribute:: shape

The type of interpolation curve between the start and end
frequencies, different wave shapes have different rates of change
in frequency. One of the following values: ``SHAPE_LINEAR``,
``SHAPE_CURVE``, ``SHAPE_LOG``.

The arguments used to create any Sound Effect,
can be inspected by looking at each of the SoundEffect instance attributes,
or by converting the instance into a string (which can be done via ``str()``
function, or by using a function that does the conversion automatically like
``print()``).

For example, with the :doc:`REPL </devguide/repl>` you can inspect the
default SoundEffects::

>>> print(audio.SoundEffect())
SoundEffect(freq_start=500, freq_end=2500, duration=500, vol_start=255, vol_end=0, waveform=WAVE_SQUARE, fx=FX_NONE, shape=SHAPE_LOG)

This format is "human readable", which means it is easy for us to read,
and it looks very similar to the code needed to create that SoundEffect,
but it's not quite right. The ``repr()`` function can be used to create a
string of Python code that can be stored or transferred
(you could transmit sounds via micro:bit radio!) and be executed with the
``eval()`` function::

>>> from audio import SoundEffect
>>> sound_code = repr(SoundEffect())
>>> print(sound_code)
SoundEffect(500, 2500, 500, 255, 0, 3, 0, 18)
>>> eval("audio.play({})".format(sound_code))

Sound Effects Example
---------------------

.. include:: ../examples/soundeffects.py
:code: python

AudioFrame
==========

.. py:class::
AudioFrame
Expand All @@ -48,16 +233,8 @@ Classes

:param other: ``AudioFrame`` instance from which to copy the data.


Using audio
===========

You will need a sound source, as input to the ``play`` function. You can generate your own, like in
``examples/waveforms.py``.


Technical Details
=================
-----------------

.. note::
You don't need to understand this section to use the ``audio`` module.
Expand All @@ -77,11 +254,11 @@ samples. When reading reaches the start or the mid-point of the buffer, it
triggers a callback to fetch the next ``AudioFrame`` which is then copied into
the buffer. This means that a sound source has under 4ms to compute the next
``AudioFrame``, and for reliable operation needs to take less 2ms (which is
32000 cycles, so should be plenty).
32000 cycles in micro:bit V1 or 128000 in V2, so should be plenty).


Example
=======
AudioFrame Example
------------------

.. include:: ../examples/waveforms.py
:code: python
17 changes: 16 additions & 1 deletion docs/ble.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Bluetooth
*********

micro:bit V1
============

While the BBC micro:bit has hardware capable of allowing the device to work as
a Bluetooth Low Energy (BLE) device, it only has 16k of RAM. The BLE stack
alone takes up 12k RAM which means there's not enough memory for MicroPython
to support Bluetooth.
to support Bluetooth on a micro:bit V1.

.. note::
MicroPython uses the radio hardware with the :mod:`radio` module. This
Expand All @@ -13,3 +16,15 @@ to support Bluetooth.

Furthermore, the protocol used in the :mod:`radio` module is a lot simpler
than BLE, making it far easier to use in an educational context.

micro:bit V2
============

The nRF52833 used by the micro:bit V2 has 128k of RAM, allowing Micropython to make
use of the BLE stack. Currently the only implemented feature is BLE flashing, allowing
a user to update the firmware on the micro:bit over Bluetooth.

At the time that this was written the `Nordic DFU service <https://infocenter.nordicsemi.com/topic/sdk_nrf5_v16.0.0/lib_bootloader_dfu_process.html>`_ is implemented, and partial flashing is currently working but in
beta. The Nordic DFU service updates everything in flash and will take a (relatively) long
time to complete, whereas the partial flashing service only updates the filesystem containing
the user scripts.
4 changes: 3 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@
yotta_module = json.load(open('../module.json'))

# The short X.Y version.
version = yotta_module['version']
# Overwrite here to v2
#version = yotta_module['version']
version = "2"
# The full version, including alpha/beta/rc tags.
release = version

Expand Down
56 changes: 54 additions & 2 deletions docs/devguide/flashfirmware.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
Build and Flash MicroPython
===========================

micro:bit V1
============

This applies to MicroPython for the micro:bit V1, the source of which can be
found here: `bbcmicrobit/micropython <https://github.com/bbcmicrobit/micropython>`_.

Dependencies
------------

- `CMake <https://cmake.org/>`_
- `Arm GCC <https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads>`_
- `Arm GCC <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
- `git <https://git-scm.com/>`_
- `ninja <https://ninja-build.org/>`_
- `python <https://www.python.org/downloads/>`_
Expand Down Expand Up @@ -68,8 +74,54 @@ is added to the script.::

It also accepts data on standard input.


micro:bit V2
============

This applies to MicroPython for the micro:bit V2, the source of which can be
found here: `microbit-foundation/micropython-microbit-v2 <https://github.com/microbit-foundation/micropython-microbit-v2>`_.

The repository also contains a history of
`MicroPython firmware builds <https://github.com/microbit-foundation/micropython-microbit-v2/actions>`_.

Dependencies
------------

- `Arm GCC <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
- `GCC <http://gcc.gnu.org/install/>`_
- `CMake <https://cmake.org/>`_
- `git <https://git-scm.com/>`_
- `Ninja <https://ninja-build.org/>`_
- `Python <https://www.python.org/downloads/>`_

Build MicroPython
-----------------

Clone the repository and change directory to it::

$ git clone https://github.com/microbit-foundation/micropython-microbit-v2
$ cd micropython-microbit-v2

Update the submodules::

$ git submodule update --init

Then build the MicroPython cross-compiler::

$ make -C lib/micropython/mpy-cross

After setting up, go to the src/ directory and build::

$ cd src

$ make

The resulting firmware will be ``MICROBIT.hex`` in the ``src/``
directory which can be copied to the micro:bit.


Flashing the micro:bit
----------------------
======================

The micro:bit mounts itself as a USB mass storage device named ``MICROBIT``.
When it detects that a .hex file has been copied to the USB drive, it will
Expand Down
Loading