messaging – Send and receive messages

Classes to send and receive messages from another device.

✅ ✅ ✅ ✅ ✅ ✅ ❌
radiobroadcast channel0observe channel1
class BLERadio(broadcast_channel=None, observe_channels=[])

Send and receive messages without a connection using Bluetooth Low Energy.

Added in version 4.0: This used to be part of each hub class.

Parameters:
  • broadcast_channel – Channel number (0 to 255) used to broadcast data. Choose None when not using broadcasting.

  • observe_channels – A list of channels to listen to when hub.ble.observe() is called. Listening to more channels requires more memory. Default is an empty list (no channels).

radio000list withbroadcast
await broadcast(data)

Starts broadcasting the given data on the previously selected broadcast_channel.

Data may be of type int, float, str, bytes, True, or False. It can also be a list or tuple of these.

Choose None to stop broadcasting. This helps improve performance when you don’t need the broadcast feature, especially when observing at the same time.

The total data size is quite limited (26 bytes). True and False take 1 byte each. float takes 5 bytes. int takes 2 to 5 bytes depending on how big the number is. str and bytes take the number of bytes in the object plus one extra byte.

When multitasking, only one task can broadcast at a time. To broadcast information from multiple tasks (or block stacks), you could use a dedicated separate task that broadcast new values when one or more variables change.

Parameters:

data – The value or values to be broadcast.

Raises:
  • RuntimeError – If no broadcast_channel was configured.

  • ValueError – If the encoded data exceeds 26 bytes.

  • TypeError – If data contains a value that is not bool, int, float, str, or bytes.

radioobserve0
observe(channel) → bool | int | float | str | bytes | tuple | None

Retrieves the last observed data for a given channel.

Receiving data is more reliable when the hub is not connected to a computer or other devices at the same time.

Parameters:

channel (int) – The channel to observe. Must be one of the channels given to observe_channels when creating this object.

Returns:

The received data in the same format as it was sent, or None if no data has been received within the last second.

Raises:

ValueError – If channel was not in observe_channels.

signal_strength(channel) → int: dBm

Gets the average signal strength in dBm for the given channel.

This indicates how near the broadcasting device is. Nearby devices may have a signal strength around -40 dBm, while far away devices might have a signal strength around -70 dBm.

Parameters:

channel (int) – The channel number. Must be one of the channels given to observe_channels when creating this object.

Returns:

The signal strength, or -128 if no data has been received within the last second.

Raises:

ValueError – If channel was not in observe_channels.

version() → str

Gets the firmware version from the Bluetooth chip.

redsmartcolor tracker
0zj3KVdmjsmartclassificationmodel
smartobject detectiondetectpersonpotted plantnothingnothing
smartline followerdark line
0bbbbsmartcustommodeformat
class AppData(modes)

Exchange raw data with the Pybricks Code host application over USB or Bluetooth. This is used by the smart sensor features like the vision processors.

Each processor has one mode and produces a fixed amount of data. These are continuously sent to the hub as they change. The user code can read these buffered values at any time without blocking. All values are initially zero.

From the hub’s perspective, writing back to the host is an awaitable operation. Can be used to configure modes and mode settings.

Only one instance may exist at a time. Must be created during program initialization. After that, all methods may be used while multi-tasking.

Parameters:

modes – A list of (mode, size) tuples, where mode is a mode number (0 to 255) and size is the number of bytes to allocate for that mode’s receive buffer. Mode numbers must be unique. The list is sorted by mode number automatically.

Raises:
  • RuntimeError – If an AppData instance already exists.

  • TypeError – If modes is not a list, or if any element is not a (mode, size) tuple with a mode value of 0 to 255.

  • ValueError – If any mode number appears more than once.

get_bytes(mode, index=None) → bytes | int

Gets data received from the host for the given mode.

Parameters:
  • mode (int) – The mode number to read.

  • index (int) – If given, returns the single byte at this position within the mode’s buffer as an integer. Otherwise returns the entire mode buffer as bytes.

Returns:

All received bytes for the mode, or a single byte as an integer if index is given.

Raises:

ValueError – If mode was not configured, or if index is out of range.

0smartvalue
await write_bytes(data)

Sends raw bytes to the host application.

Parameters:

data (bytes) – The data to send.

await configure(mode, parameter, value)

Sends a configuration command to the host for the given mode.

This is a wrapper around write_bytes(). It prepends a [0x01, mode, parameter] header to configure mode settings.

Parameters:
  • mode (int) – The mode number to configure.

  • parameter (int) – The parameter identifier within the mode.

  • value (bytes) – The configuration value to send.

close()

Deactivates the data callback and releases the receive buffer.

This is also called automatically when the object is garbage collected.

BLERadio examples

Broadcasting data to other hubs

from pybricks.messaging import BLERadio
from pybricks.parameters import Port
from pybricks.pupdevices import Motor
from pybricks.tools import wait

# Initialize the hub.
radio = BLERadio(broadcast_channel=1)

# Initialize the motors.
left_motor = Motor(Port.A)
right_motor = Motor(Port.B)

while True:
    # Read the motor angles to be sent to the other hub.
    left_angle = left_motor.angle()
    right_angle = right_motor.angle()

    # Set the broadcast data and start broadcasting if not already doing so.
    data = (left_angle, right_angle)
    radio.broadcast(data)

    # Broadcasts are only sent every 100 milliseconds, so there is no reason
    # to call the broadcast() method more often than that.
    wait(100)

Observing data from other hubs

from pybricks.messaging import BLERadio
from pybricks.parameters import Port
from pybricks.pupdevices import Motor
from pybricks.tools import wait

# Initialize the hub.
radio = BLERadio(observe_channels=[1])

# Initialize the motors.
left_motor = Motor(Port.A)
right_motor = Motor(Port.B)

while True:
    # Receive broadcast from the other hub.

    data = radio.observe(1)

    if data is not None:
        # Data was received and is less that one second old.
        # It contains the same values in the same order
        # that were passed to radio.broadcast() on the
        # other hub.
        left_angle, right_angle = data

        # Make the motors on this hub mirror the position of the
        # motors on the other hub.
        left_motor.track_target(left_angle)
        right_motor.track_target(right_angle)

    # Broadcasts are only sent every 100 milliseconds, so there is
    # no reason to call the observe() method more often than that.
    wait(100)

Messaging between EV3 Bricks

❌ ❌ ❌ ✅ ✅ ✅ ✅
class HubNetwork(inbox_size=1024)

Send and receive messages between supported hubs using Bluetooth.

Create this object in every program that takes part in the network. One hub, called the manager, then connects to others identified by their address. For example: connect('00:16:53:12:34:56'). After that, all hubs are equal: each one can send messages to any other brick.

You can find the address of each hub in the EV3 settings menu, or print it with the address() method. Connections are preserved when you restart a program.

The protocol ensures that messages get delivered. But they will only be seen in your program if there is enough room. The manager takes care of relaying messages in the background, which only works while the manager program is still running.

Added in version 4.1.

Parameters:

inbox_size (int) – How many bytes of messages to store for each brick that sends them.

Raises:
  • RuntimeError – If a HubNetwork object already exists, or if this is used after multitasking has started.

  • OSError – If this brick has no working Bluetooth.

  • ValueError – If inbox_size is too small to hold one message.

address() → str

Gets the Bluetooth address of this brick.

This is the same address that is shown on the brick’s screen. You can print it to find out which address to type in the programs of the other bricks.

Returns:

The address of this brick, such as '00:16:53:AB:CD:EF'. The letters are always uppercase.

await connect(address)

Connects to one other hub (EV3 Brick) to set up the network.

Only one hub in the network does this. That hub is called the manager. The other hubs don’t have to run a program yet. They just won’t receive messages until their programs run.

Connecting is slow. It takes up to about fifteen seconds per brick, and it does not always work on the first try, so it tries again a few times before it gives up. This is why you normally do this at the start of your program.

A brick that is already connected is ready right away, so it is safe to use this again later. This makes the second run very quick to start.

Parameters:

address (str) – The Bluetooth address of the brick to connect to, such as '00:16:53:12:34:56'. You can connect to up to seven other bricks.

Raises:

OSError – If the brick could not be reached. ValueError: If address is not a valid Bluetooth address, or if it is the address of this brick.

is_connected() → bool
is_connected(address) → bool

Checks whether a brick has joined the network.

This is useful on the bricks that wait. They can keep checking is_connected() until the manager brick has reached them, instead of guessing how long the network takes to set up.

Only the manager brick can use the address argument to check individual bricks.

Parameters:

address (str) – The Bluetooth address of the hub to check.

Returns:

True if the hub has joined the network, False if not. If no address is given, it is True if any hub is connected.

Raises:

ValueError – If address is not a valid Bluetooth address.

await send(data) send(data, address)

Sends a message to all hubs on the network, or to one specific hub.

A message is one object, or a tuple of objects. An object may be of type int, float, str, bytes, True, False, or None. The brick that receives it gets the same objects back, so sending (60, "left") arrives as (60, "left").

A message that is only bytes is sent just as it is, which is what you want if you build your own messages. Such a message can hold 255 bytes. Every other message also carries a short description of the objects in it, so a little less fits: True, False and None take 2 bytes each, int and float take 5 bytes each, and str and bytes take the number of bytes in them plus 2 to 4. One message holds up to 32 objects.

Messages from this brick to one other brick arrive in the order that you sent them.

Parameters:
  • data – The message to send.

  • address (str) – The Bluetooth address of the brick to send to. Leave out to send to every other brick on the network. A brick never receives its own messages.

Raises:
  • ValueError – If address is not a valid Bluetooth address, or if the message is too big to send.

  • TypeError – If the message holds an object that cannot be sent.

inbox(latest=False) → tuple

Gets the messages that have arrived since you last read them.

This never waits. If nothing has arrived, you get an empty result, so a for loop over it simply does nothing. Reading removes the messages from this brick’s memory, so each message is given to you only once.

Every brick that sends to you gets an inbox of its own internally. When one brick sends more than fits in its inbox, its oldest message is dropped. A brick that sends all the time cannot push another brick’s messages out.

A program never receives messages that were sent before it started. Messages are given to you in the order that they arrived, no matter which brick sent them.

Parameters:

latest (bool) – Choose True to keep only the newest message from each brick and throw the older ones away. This is what you want when a brick keeps sending you its latest value, such as a sensor reading, and only the newest one is of any use.

Returns:

A tuple of (address, data) pairs, where address is the Bluetooth address of the brick that sent the message, and data is the message in the same form as it was sent. With latest, there is at most one pair per brick.

Raises:

ValueError – If a message does not match the description it carries with it, which means that it was damaged on the way.