Skip to content
Snippets Groups Projects
Select Git revision
  • main default protected
1 result

mpy_bridge

  • Clone with SSH
  • Clone with HTTPS
  • Name Last commit Last update
    docs
    examples
    .gitignore
    README.md
    mpy_bridge.py

    Python <-> MicroPython bridge

    This project lets you interact with MicroPython devices by directly having access to an equivalent Python object on your host computer. All functions are dynamically generated based on the signatures found in the source code of the MicroPython project.

    Sending and receiving Python objects is seamlessly supported, as long as those objects have a string representation.

    How to use

    Let's assume the following MicroPython file main.py is present on the device:

    # main.py (MicroPython)
    import machine
    
    # create a pin object
    p = machine.Pin(4, machine.Pin.OUT)
    
    def led_on():
        # turn the LED on
        p.on()

    The following Python code on the host computer lets you instantiate the device and call the function that was automatically discovered:

    # test_led.py (Python)
    import mpy_bridge
    
    # instantiate the device on serial port COM1
    d = mpy_bridge.Device("COM1")
    
    # call the function
    d.led_on()

    Function parameters and return values are supported, but they need to have valid string representations. This is the case for all built-in types.

    Here is a more complex example of a MicroPython script:

    # main.py (MicroPython)
    import machine
    
    # create a pin object
    pins = {}
    
    def setup_inputs(pin_list):
        global pins
        # create a dictionary of {pin number: pin object}
        pins = {p: machine.Pin(p, machine.Pin.IN) for p in pin_list}
    
    def read_inputs():
        # return a dictionary of {pin number: pin value}
        return {p: pins[p].value for p in pins.keys()}

    A host program can send Python objects, and receive some in return. In this case, an entire dictionary of pin values is returned:

    # test_pins.py (Python)
    import mpy_bridge
    
    # instantiate the device on serial port COM5
    d = mpy_bridge.Device("COM5")
    
    # setup 3 pins at once
    d.setup_inputs([2, 6, 15])
    
    # return values of all requested pins
    values = d.read_inputs()
    
    print(values) # prints {2: 1, 6: 0, 15: 1}

    Error handling

    Exceptions on the MicroPython side are turned into Python exceptions, which can help you debug the embedded code. You can catch them and react accordingly:

    # test_exceptions.py (Python)
    import mpy_bridge
    
    d = mpy_bridge.Device("COM5")
    
    try:
        d.read_inputs()
    except mpy_bridge.MicroPythonError as e:
        print(f"Error on the device: {e}")

    Upload code

    This module includes a basic tool to update the main file on the MicroPython device:

    # test_upload.py (Python)
    import mpy_bridge
    
    # instantiate the device on serial port COM34
    d = mpy_bridge.Device("COM34")
    
    # upload main file
    d.upload("embedded/main.py", "main.py")
    
    # see new function list
    print(d)

    The object is automatically updated after each upload. By default, functions are searched in a file named main.py. You can have other files on the device, such as libraries, but those functions won't appear in the generated Python object.

    Results

    To evaluate the speed of the transmission back and forth, a simple round-trip time estimation was performed between an rp2040 and a typical laptop. The result show an average of ~3.4ms per function call in the most basic scenario:

    License

    This project is provided under the MIT License.