diff --git a/docs/audio.rst b/docs/audio.rst index f62f02b07..c607101b4 100644 --- a/docs/audio.rst +++ b/docs/audio.rst @@ -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 ` (**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 ` 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 @@ -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. @@ -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 diff --git a/docs/ble.rst b/docs/ble.rst index 739e087c4..5847dd492 100644 --- a/docs/ble.rst +++ b/docs/ble.rst @@ -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 @@ -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 `_ 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. diff --git a/docs/conf.py b/docs/conf.py index b945bdeaf..1a44b635a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -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 diff --git a/docs/devguide/flashfirmware.rst b/docs/devguide/flashfirmware.rst index f3731eec0..0ed1f1a48 100644 --- a/docs/devguide/flashfirmware.rst +++ b/docs/devguide/flashfirmware.rst @@ -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 `_. + Dependencies ------------ - `CMake `_ -- `Arm GCC `_ +- `Arm GCC `_ - `git `_ - `ninja `_ - `python `_ @@ -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 `_. + +The repository also contains a history of +`MicroPython firmware builds `_. + +Dependencies +------------ + +- `Arm GCC `_ +- `GCC `_ +- `CMake `_ +- `git `_ +- `Ninja `_ +- `Python `_ + +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 diff --git a/docs/devguide/hexformat.rst b/docs/devguide/hexformat.rst index 1b4663913..f42f019a5 100644 --- a/docs/devguide/hexformat.rst +++ b/docs/devguide/hexformat.rst @@ -22,8 +22,8 @@ The general memory layout used is: addresses of the data stored progress in incremental order. If there is an address jump backwards DAPLink will fail to flash the file. -UICR format ------------ +UICR format (micro:bit V1) +--------------------------- The User Information Configuration Registers (UICR) is a region of Non-Volatile Memory available to store user-specific settings. @@ -42,9 +42,62 @@ the UICR customer[16] register: - ``0x100010d4``: 4-byte integer with the address in the firmware of the version string - ``0x100010d8``: 4-byte integer with value ``0x00000000`` +Layout table (micro:bit V2) +--------------------------- + +A flash layout table is appended to the the hex file when building MicroPython +for a micro:bit V2. + +The layout table is a sequence of 16-byte entries. The last entry contains the +header (including magic numbers) and is aligned to the end of a page such that +the final byte of the layout table is the final byte of the page it resides in. +This is so it can be quickly and easily searched for. + +The layout table has the following format. All integer values are unsigned and +store little endian. + +:: + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e + + ID HT REG_PAGE REG_LEN HASH_DATA + (additional regions) + ... + MAGIC1 VERSION TABLE_LEN NUM_REG PSIZE_LOG2 MAGIC2 + + The values are: + + ID - 1 byte - region id for this entry, defined by the region + HT - 1 byte - hash type of the region hash data + REG_PAGE - 2 bytes - starting page number of the region + REG_LEN - 4 bytes - length in bytes of the region + HASH_DATA - 8 bytes - data for the hash of this region + HT=0: hash data is empty + HT=1: hash data contains 8 bytes of verbatim data + HT=2: hash data contains a 4-byte pointer to a string + + MAGIC1 - 4 bytes - 0x597F30FE + VERSION - 2 bytes - table version (currently 1) + TABLE_LEN - 2 bytes - length in bytes of the table excluding this header row + NUM_REG - 2 bytes - number of regions + PSIZE_LOG2 - 2 bytes - native page size of the flash, log-2 + MAGIC2 - 4 bytes - 0xC1B1D79D + + +This layout table is used to communicate the version of MicroPython and the +current memory layout to a Bluetooth client and enable `partial flashing `_ +(only updating the Python script, and keeping the existing version of +MicroPython in flash). + Steps to create the firmware.hex file ------------------------------------- +micro:bit V1 +============ + +This applies to MicroPython for the micro:bit V1, the source of which can be +found here: `bbcmicrobit/micropython `_. + The yotta tool is used to build MicroPython, but before that takes place additional files have to be generated by the Makefile in preparation for the build, and additional data is added to the hex file after. @@ -59,6 +112,25 @@ Running the ``make all`` command executes the following steps: - The user can optionally append a script using ``tools/makecombinedhex.py`` (or other tools) +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 `_. + +This is a port of MicroPython to the micro:bit which uses CODAL as the +underlying target platform. + +Running the ``make`` command executes the following steps: + +- Create build output directory, run cmake, and make sure codal libraries + exist (via cmake). +- Build both ``libmicropython.a`` (from source in ``src/codal_port/``) and the + CODAL app (from source in ``src/codal_app/``). +- Run ``addlayouttable.py`` to add the layout table to the .hex file +- Create the microbit-micropython firmware as ``MICROBIT.hex`` in the ``src/`` + directory, which can be copied to the micro:bit. + Including a user script ----------------------- @@ -73,10 +145,10 @@ add the filesystem to HEX files for MicroPython V1 & V2, and then combine both into a `Universal HEX `_ file to ensure compatibility with both hardware variants. -Appended script format (Deprecated) -=================================== +Appended script format (Deprecated) V1 +====================================== -This method of appending the script to the end of MicroPython +This method of appending the script to the end of MicroPython for micro:bit V1 is no longer used. Python files are now stored in the `filesystem <../filesystem.html>`_ and ``main.py`` is the program entry point. diff --git a/docs/i2c.rst b/docs/i2c.rst index 3224eb3f7..aa9266c16 100644 --- a/docs/i2c.rst +++ b/docs/i2c.rst @@ -28,8 +28,13 @@ Functions .. warning:: - Changing the I²C pins from defaults will make the accelerometer and - compass stop working, as they are connected internally to those pins. + On a micro:bit V1 board, changing the I²C pins from defaults will make + the accelerometer and compass stop working, as they are connected + internally to those pins. This warning does not apply to the **V2** + revision of the micro:bit as this has `separate I²C lines + `_ + for the motion sensors and the edge connector. + .. py:function:: scan() diff --git a/docs/index.rst b/docs/index.rst index 43e2b2ee2..687ac4c1c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,6 +17,13 @@ This documentation includes lessons for teachers and API documentation for developers (check out the index on the left). We hope you enjoy developing for the BBC micro:bit using MicroPython. +.. note:: + + The BBC micro:bit MicroPython documentation contains information for all + versions of the micro:bit board. Where functionality is applicable only + to the latest device, you will see a note or comment marking this as + **V2**. + If you're a new programmer, teacher or unsure where to start, begin with the :ref:`Tutorials ` and use the `micro:bit Python Editor `_ to program the micro:bit. @@ -72,18 +79,22 @@ Projects related to MicroPython on the BBC micro:bit include: ble.rst button.rst compass.rst + log.rst display.rst filesystem.rst i2c.rst image.rst machine.rst + microphone.rst micropython.rst music.rst neopixel.rst os.rst pin.rst + power.rst radio.rst random.rst + speaker.rst speech.rst spi.rst uart.rst diff --git a/docs/log-html-view.jpeg b/docs/log-html-view.jpeg new file mode 100644 index 000000000..f9b736c36 Binary files /dev/null and b/docs/log-html-view.jpeg differ diff --git a/docs/log-my_data.png b/docs/log-my_data.png new file mode 100644 index 000000000..b64e01a91 Binary files /dev/null and b/docs/log-my_data.png differ diff --git a/docs/log.rst b/docs/log.rst new file mode 100644 index 000000000..9cc21e6b2 --- /dev/null +++ b/docs/log.rst @@ -0,0 +1,122 @@ +Data Logging **V2** +******************* + +.. py:module:: log + +This module lets you log data to a ``MY_DATA`` file saved on a micro:bit +**V2** ``MICROBIT`` USB drive. + +.. image:: log-my_data.png + +The data is structured in a table format and it can be viewed and plotted with +a browser. + +.. image:: log-html-view.jpeg + +Further guidance on this feature can be found on the +`data logging page of the microbit.org website +`_. + +Functions +========= + +.. py:function:: set_labels(*labels, timestamp=log.SECONDS) + + Set up the log file header. + + This function accepts any number of positional arguments, each creates + a column header, e.g. ``log.set_labels("X", "Y", "Z")``. + + Ideally this function should be called a single time, before any data is + logged, to configure the data table header once. + + If a log file already exists when the programme starts, or if this function + is called multiple times, it will check the labels already defined in the + log file. + If this function call contains any new labels not already present, it will + generate a new header row with the additional columns. + + By default the first column contains a time stamp for each row. The time + unit can be selected via the ``timestamp`` argument, e.g. + ``log.set_labels("temp", timestamp=log.MINUTES)`` + + :param \*labels: Any number of positional arguments, each corresponding to + an entry in the log header. + :param timestamp: Select the timestamp unit that will be automatically + added as the first column in every row. Timestamp values can be one of + ``log.MILLISECONDS``, ``log.SECONDS``, ``log.MINUTES``, ``log.HOURS``, + ``log.DAYS`` or ``None`` to disable the timestamp. The default value + is ``log.SECONDS``. + +.. py:function:: set_mirroring(serial) + + Configure mirroring of the data logging activity to the serial output. + + Serial mirroring is disabled by default. When enabled, it will print to + serial each row logged into the log file. + + :param serial: ``True`` enables mirroring data to the serial output. + +.. py:function:: delete(full=False) + + Delete the contents of the log, including headers. + + To add the log headers again the ``set_labels`` function should to be + called after this function. + + There are two erase modes; "full" completely removes the data from the + physical storage, and "fast" invalidates the data without removing it. + + :param full: ``True`` selects a "full" erase and ``False`` selects the + "fast" erase method. + +.. py:function:: add( data_dictionary, /, *, **kwargs) + + Add a data row to the log. + + There are two ways to log data with this function: + + #. Via keyword arguments, each argument name representing a label. + + * e.g. ``log.add(X=compass.get_x(), Y=compass.get_y())`` + + #. Via a dictionary, each dictionary key representing a label. + + * e.g. ``log.add({ "X": compass.get_x(), "Y": compass.get_y() })`` + + The keyword argument option can be easier to use, and the dictionary option + allows the use of spaces (and other special characters), that could not be + used with the keyword arguments. + + New labels not previously specified via the ``set_labels`` function, or by + a previous call to this function, will trigger a new header entry to be + added to the log with the extra labels. + + Labels previously specified and not present in a call to this function will + be skipped with an empty value in the log row. + + :raise OSError: When the log is full this function raises an ``OSError`` + exception with error code 28 ``ENOSPC``, which indicates there is no + space left in the device. + +Examples +======== + +A minimal example:: + + from microbit import * + import log + + # Set the timer to log data every 5 seconds + @run_every(s=5) + def log_temp(): + log.add(temp=temperature()) + + while True: + # Needed so that the programme doesn't end + sleep(100) + +An example that runs through all of the functions of the log module API: + +.. include:: ../examples/data-logging.py + :code: python diff --git a/docs/microbit.rst b/docs/microbit.rst index 125e5e896..f258e591c 100644 --- a/docs/microbit.rst +++ b/docs/microbit.rst @@ -58,6 +58,16 @@ Functions :returns: The ``value`` converted to the ``to`` range. +.. py:function:: set_volume(volume) + + (**V2 only**) Configure the output volume of the micro:bit speaker and + pins:: + + microbit.set_volume(127) + + :param volume: An integer between 0 and 255 to set the volume. + + .. py:function:: sleep(n) Wait for ``n`` milliseconds. One second is 1000 milliseconds, so @@ -66,6 +76,39 @@ Functions :param n: An integer or floating point number indicating the number of milliseconds to wait. +.. py:function:: run_every(callback, days=None, h=None, min=None, s=None, ms=None) + + Schedule to run a function at the interval specified by the time arguments. + + ``run_every`` can be used in two ways: + + * As a **Decorator** - placed on top of the function to schedule. + For example:: + + @run_every(days=1, h=1, min=20, s=30, ms=50) + def my_function(): + # Do something here + + * As a **Function** - passing the callback as a positional argument. + For example:: + + def my_function(): + # Do something here + run_every(my_function, s=30) + + Each argument corresponds to a different time unit and they are additive. + So ``run_every(min=1, s=30)`` schedules the callback every minute and + a half. + + When an exception is thrown inside the callback function it deschedules + the function. To avoid this you can catch exceptions with ``try/except``. + + :param callback: Function to call at the provided interval. + :param days: Sets the days mark for the scheduling. + :param h: Sets the hour mark for the scheduling. + :param min: Sets the minute mark for the scheduling. + :param s: Sets the second mark for the scheduling. + :param ms: Sets the millisecond mark for the scheduling. .. py:function:: temperature() @@ -90,6 +133,7 @@ Classes :maxdepth: 1 image.rst + Sound Modules @@ -99,8 +143,11 @@ Modules :maxdepth: 1 accelerometer.rst + Audio V2 compass.rst display.rst i2c.rst + microphone.rst + speaker.rst spi.rst uart.rst diff --git a/docs/microbit_micropython_api.rst b/docs/microbit_micropython_api.rst index 2063c3381..19362fdac 100644 --- a/docs/microbit_micropython_api.rst +++ b/docs/microbit_micropython_api.rst @@ -26,6 +26,9 @@ There are a few functions available directly:: panic(error_code) # resets the micro:bit. reset() + # sets the output volume (0-255) of the micro:bit speaker **V2** and + # external speaker or headphones connected to the edge connector pins. + set_volume(128) # V2 The rest of the functionality is provided by objects and classes in the microbit module, as described below. @@ -74,11 +77,43 @@ The LED display is exposed via the `display` object:: # written messages). display.scroll(string, delay=400) +SoundEvent **V2** +----------------- +Sound events describe changes in the sound heard by the microphone:: + + # Value to represent the transition of sound events, from `quiet` to `loud` + # like clapping or shouting. + SoundEvent.LOUD = SoundEvent('loud') + # Value to represent the transition of sound events, from `loud` to `quiet` + # like speaking or background music. + SoundEvent.QUIET = SoundEvent('quiet') + +Microphone **V2** +----------------- + +The Microphone is accessed via the `microphone` object:: + + # Returns the name of the last recorded sound event. + current_event() + # A sound event, such as `SoundEvent.LOUD` or `SoundEvent.QUIET`. + # Returns`true` if sound was heard at least once since the last + # call, otherwise `false`. + was_event(event) + # Returns a tuple of the event history. The most recent is listed last. + # Also clears the sound event history before returning. + get_events() + # The threshold level in the range 0-255. For example, + # `set_threshold(SoundEvent.LOUD, 250)` will only trigger if the + # sound is very loud (>= 250). + set_threshold(128) + # Returns a representation of the sound pressure level in the range 0 to 255. + sound_level() + Pins ---- Provide digital and analog input and output functionality, for the pins in the -connector. Some pins are connected +connector, the **V2** logo and the **V2** speaker. Some pins are connected internally to the I/O that drives the LED matrix and the buttons. Each pin is provided as an object directly in the ``microbit`` module. This @@ -92,6 +127,8 @@ keeps the API relatively flat, making it very easy to use: * *Warning: P17-P18 (inclusive) are unavailable.* * pin19 * pin20 + * pin_logo **V2** + * pin_speaker **V2** Each of these pins are instances of the ``MicroBitPin`` class, which offers the following API:: @@ -112,6 +149,21 @@ Each of these pins are instances of the ``MicroBitPin`` class, which offers the # Only available for touch pins 0, 1, and 2. Returns boolean if the pin # is touched pin.is_touched() + # Only available for touch pins 0, 1, 2 and on micro:bit V2 also the logo. + # Sets the touch mode. Value can be either RESISTIVE or CAPACITIVE + pin.set_touch_mode(value) + +Except in the case of the pins marked **V2**, which offers the following API: + +pin_logo:: + + # returns boolean for logo touch pin + pin_logo.is_touched() + # Sets the touch mode. Value can be either RESISTIVE or CAPACITIVE + pin.set_touch_mode(value) + +pin_speaker, as the above ``MicroBitPin`` class, but does not include +``pin.is_touched()``. Images ------ @@ -277,6 +329,39 @@ There is an I2C bus on the micro:bit that is exposed via the `i2c` object. It h # write buf to device with addr; repeat=True means a stop bit won't be sent. i2c.write(addr, buf, repeat=False) +Sound **V2** +------------ + +A set of expressive sounds are available to the micro:bit **V2**. They can be +accessed via the ``microbit`` module and played with the :doc:`audio