PUPRemote documentation

Use this library to communicate from a pyboard like OpenMV or LMS-ESP32 as a Powered UP (PUP) Device with LEGO smart hubs. It has a PUPRemote library that acts more like RPC (Remote Procedure Calling). The library is compatible with Pybricks, SPIKE2, and Robot Inventor.

pupremote.py works on all platforms, also on Pybricks. However, for Pybricks, there is also a smaller file, called pupremote_hub.py that only contains the PUPRemoteHub class. So on Pybricks, we suggest using from pupremote_hub import PUPRemoteHub

Example

Run this on OpenMV

# Copy this file to OpenMV Cam H7 Plus or LMS-ESP32
# Be sure to also copy pupremote.py and lpf2.py to the device

### Setup pupremote code
from pupremote import PUPRemoteSensor

def msg(txt):
    print(txt)
    return txt+txt

def num(n):
    print(n)
    return 2*n

p=PUPRemoteSensor()
# Send and receive any object with 'repr' encoding
p.add_command('msg',"repr","repr")

# Send and receive a signed byte with 'b'
# See https://docs.python.org/3/library/struct.html#format-characters
p.add_command('num',from_hub_fmt="b", to_hub_fmt="b")

# Do no execute procedures, but only present new data to hub
p.add_channel('one_way', to_hub_fmt="bbb")

### End of pupremote setup code

### Main loop
while(True):
    # Add more sensor processing code here
    # ....
    p.update_channel('one_way', 1,2,3)
    # Try to connect, send data and return the connected state.
    connected=p.process()

Run this on Pybricks. Be sure to create a file called pupremote.py with the contents of pupremote.py.

from pybricks.parameters import Button, Color, Direction, Port, Side, Stop
from pupremote import PUPRemoteHub

p=PUPRemoteHub(Port.A)
p.add_command('msg',"repr","repr")
p.add_command('num',from_hub_fmt="b",to_hub_fmt="b")

# Print something on the openmv console
print(p.call('msg','hello'))
print(p.call('num',45))
print(p.call('num',42))

PUPRemote API documentation

class pupremote.PUPRemote(max_packet_size=micropython.const)

Base class for PUPRemoteHub and PUPRemoteSensor. Defines a list of commands and their formats. Contains encoding/decoding functions.

add_channel(mode_name: str, to_hub_fmt: str = '')

Define a data channel to read on the hub. Use this function with identical parameters on both the sensor and the hub. You can call a channel like a command, but to update the data on the sensor side, you need to update_channel(<name>, *args).

Parameters:
  • mode_name (str) – The name of the mode you defined on the sensor side.

  • to_hub_fmt (str) – The format string of the data sent from the sensor to the hub. Use ‘repr’ to receive any python object. Or use a struct format string, to receive a fixed size payload. See https://docs.python.org/3/library/struct.html

add_command(mode_name: str, to_hub_fmt: str = '', from_hub_fmt: str = '', command_type=micropython.const)

Define a remote call. Use this function with identical parameters on both the sensor and the hub.

Parameters:
  • mode_name (str) – The name of the mode you defined on the sensor side.

  • to_hub_fmt (str) – The format string of the data sent from the sensor to the hub. Use ‘repr’ to receive any python object. Or use a struct format string, to receive a fixed size payload. See https://docs.python.org/3/library/struct.html

  • from_hub_fmt (str) – The format string of the data sent from the hub

class pupremote.PUPRemoteHub(port, max_packet_size=micropython.const)

Class to communicate with a PUPRemoteSensor. Use this class on the hub side, on any hub that runs Pybricks. Copy the commands you defined on the sensor side to the hub side.

Parameters:
  • port (Port (Example: Port.A)) – The port to which the PUPRemoteSensor is connected.

  • max_packet_size (int) – Set to 16 for Pybricks compatibility, defaults to 32.

call(mode_name: str, *argv, wait_ms=0)

Call a remote function on the sensor side with the mode_name you defined on both sides.

Parameters:
  • mode_name (str) – The name of the mode you defined on the sensor side.

  • argv (Any) – As many arguments as you need to pass to the remote function.

  • wait_ms (int) – The time to wait for the sensor to respond after a write from the hub, defaults to 100ms. This does not delay the read, i.e. when you don’t pass any arguments, the read will happen immediately.

class pupremote.PUPRemoteSensor(sensor_id=micropython.const, power=False, max_packet_size=micropython.const, **kwargs)

Class to communicate with a PUPRemoteHub. Use this class on the sensor side, on any board that runs MicroPython. You can enable 8V power on the M+ wire, so the buck converter on the SPIKE-OPENMV or LMS-ESP32 board side can supply high currents (op to 1700mA) to your appliances.

Parameters:
  • sensor_id (int) – The id of the sensor of the sensor to emulate, defaults to 62.

  • power (bool) – Set to True if the PUPRemoteHub needs 8V power on M+ wire, defaults to False.

  • platform (int) – Set to ESP32 or OPENMV, defaults to ESP32.

  • max_packet_size (int) – Set to max 32 bytes of payload, defaults to 16 for Pybricks compatibility.

add_command(mode_name: str, to_hub_fmt: str = '', from_hub_fmt: str = '', command_type=micropython.const)

Define a remote call. Use this function with identical parameters on both the sensor and the hub.

Parameters:
  • mode_name (str) – The name of the mode you defined on the sensor side.

  • to_hub_fmt (str) – The format string of the data sent from the sensor to the hub. Use ‘repr’ to receive any python object. Or use a struct format string, to receive a fixed size payload. See https://docs.python.org/3/library/struct.html

  • from_hub_fmt (str) – The format string of the data sent from the hub

process()

Process the commands. Call this function in your main loop, preferably at least once every 20ms. It will handle the communication with the LEGO Hub, connect to it if needed, and call the registered commands.

Returns:

True if connected to the hub, False otherwise.

update_channel(mode_name: str, *argv)

Update values in ‘sensor’ memory, so the hub can retrieve them with call(). This is simpler than defining a function that is called remotely from the hub.

Parameters:

mode_name (str) – mode name you defined when you used add_channel()

pupremote.SPIKE_COLOR = 61

SPIKE Color sensor id

pupremote.SPIKE_ULTRASONIC = 62

SPIKE Ultrasonic sensor id

pupremote.WEDO_ULTRASONIC = 35

WeDo Ultrasonic sensor id

BluePad API documentation

This is a small wrapper library to use with the BluePad32 LPF2 for Pybricks firmware. It uses the PUPRemote library to communicate with the firmware of the LMS-ESP32 acting like a Lego sensor and supporting reading the gamepad and driving NeoPixels and Servo’s that are connected to the LMS-ESP32 board. This firmware is based on the nice Bluepad32 for Arduino library made by Ricardo Quesada.

class bluepad.BluePad(port)

Class for using LMS-ESP32 running BluePad32 LPF2 firmware. Defines methods for reading connected Bluetooth gamepad (such as PS4 or Nintendo Switch) and for driving NeoPixels and Servo motors connected to the LMS-ESP32 board. Flash the LMS-ESP32 board with BluePad32 LPF2 for PyBricks projects from https://firmware.antonsmindstorms.com/.

Parameters:

port (Port (Example: Port.A)) – The port to which the LMS-ESp32 running BluePad32 is connected.

class PUPRemoteHub(port, max_packet_size=micropython.const)

Class to communicate with a PUPRemoteSensor. Use this class on the hub side, on any hub that runs Pybricks. Copy the commands you defined on the sensor side to the hub side.

Parameters:
  • port (Port (Example: Port.A)) – The port to which the PUPRemoteSensor is connected.

  • max_packet_size (int) – Set to 16 for Pybricks compatibility, defaults to 32.

call(mode_name: str, *argv, wait_ms=0)

Call a remote function on the sensor side with the mode_name you defined on both sides.

Parameters:
  • mode_name (str) – The name of the mode you defined on the sensor side.

  • argv (Any) – As many arguments as you need to pass to the remote function.

  • wait_ms (int) – The time to wait for the sensor to respond after a write from the hub, defaults to 100ms. This does not delay the read, i.e. when you don’t pass any arguments, the read will happen immediately.

btns_pressed(btns, nintendo=False)

Decodes the buttons pressed and converts the buttons to a string containing the pressed buttons [‘X’,’O’,’#’,’^’]

Parameters:
  • btns (Word) – The word read from the gamepad containing the binary encodeing of pressed buttons

  • nintendo – Indicates that a nintendo gamepad is used.

Returns:

String with pressed buttons

dpad_pressed(btns, nintendo=False)

Decodes the dpad-buttons pressed and converts the buttons to a string containing the pressed buttons [‘L’,’R’,’U’,’D’]

Parameters:

btns (Word) – The word read from the gamepad containing the binary encoding of pressed dpad-buttons

Returns:

String with pressed dpad-buttons

gamepad()

Returns the reading of a gamepad as a tuple. Returns the x- and y values of the left and right pads. Buttons are encoded as single bits in buttonss. The dpad values are encoded in dpad.

Returns:

Tuple (left_pad_x,left_pad_y,right_pad_x,right_pad_y,buttons,dpad)

neopixel_fill(color, write=True)

Fills all the neopixels with the same color.

Parameters:
  • color – tuple with (red,green,blue) color.

  • write (bool) – If True write the output to the NeoPixels. Defaults to True.

neopixel_init(nr_leds, pin)

Initializes a NeoPixel string with the given number of LEDs aconnected to the specified GPIO pin.

Parameters:
  • nr_leds (byte) – The number of leds in the NeoPixel string

  • pin (byte) – The GPIO pin number connected to the NeoPixel string

neopixel_set(led_nr, color, write=True)

Sets single NeoPixel at position led_nr with color=(r,g,b).

Parameters:
  • led_nr (byte) – Position of the led to set (counting from 0)

  • color – Tuple with color for led (r,g,b)

  • color – (r,g,b) with r,g,b bytes

  • write (bool) – If True writes the output to the NeoPixels. Defaults to True.

neopixel_set_multi(start_led, nr_led, led_arr, write=True)

Sets multiple NeoPixel value(s). Maximum number os leds is 4.

Parameters:
  • start_led (byte) – Starting led number (counting from 0).

  • nr_led (byte) – Number of leds to set.

  • led_arr – Array containing r,g,b for each neopixel.

  • write (bool) – If True write the output to the NeoPixels. Defaults to True.

neopixel_zero(write=True)

Zeros all neopixels with value (0,0,0)

Parameters:

write (bool) – If True writes the output to the NeoPixels. Defaults to False.

servo(servo_nr, pos)

Sets Servo motor servo_nr to the specified position. Servo motors should be connected to GPIO pins 21, 22, 23 and 25.

Parameters:
  • servo_nr (byte) – Servo motor counting from 0

  • pos – Position of the Servo motor

Type:

word (2 byte int)