UartRemote Library
This library implements a class with methods that help to set up robust communication between instances running MicroPython which are connected over a UART interface.
The library is available on github: UartRemote on GitHub.
Platforms
The following platforms are supported:
Lego EV3
Lego Mindstroms Robot Inventor 51515
Lego SPIKE Prime
Espressif ESP8266
Espressif ESP32
Espressif ESP32-S2
OpenMV H7 and M7 (STM32 chipset)
MaixPy (K210 chipset)
Windows
Mac OSX
These platforms are automatically detected by querying sys.platform. Within uartremote.py these platforms are defined by the constants: _EV3,_SPIKE,_ESP8266,_ESP32,_ESP32_S2,_H7,_K210,_MAC,_WIN32, respectively. There are small differences in the implementation of MicroPython for these platforms. The UartRemote takes these into account based on the platform type.
Constructor
- class uartremote.UartRemote(port=0, baudrate=115200, timeout=1500, debug=False, rx_pin=18, tx_pin=19)
Construct a UartRemote object on the port given by:
portidentifies a port for using the UART.
portis board specific:SPIKE: port = : has one I2S bus with id=2.
ESP8266: port = 0.
ESP32: Use 1 for UART1.
The following keyword arguments are supported on all platforms:
portis the hardware uart port used to by UartRemote class; for LEGO it indicated the harware port, i.e. “A”baudrateis the baudrate at which the UART communicates, defaults to 115200timeoutis the timeout (in ms) for waiting for data coming in on the UART in thereceive_command(), default to 1500debugis a Boolean flag to generate debug output, default to False
Only for ESP32 platform:
rx_pinis only used for ESP32 and indicates the pin on which the UART will receive information, default to 18tx_pinis the pin on which the UART will receive information, default to 19
Methods
- UartRemote.flush()
Flushes the read buffer, by reading all remaining bytes from the Uart.
- UartRemote.available()
Return a non zero value if there is a received command available. Note: on the SPIKE prime, you should use the
receive_commandor theexecute_command, always with the parameterreply=False, after using theavailable()method.
- UartRemote.send_command(command, *type_data)
Sends a command
command.*type_dataare a number of argument that consist of a type defintiont, followed by one ore more variables of the type corresponding with the paramatert.For example:
ur=UartRemote() ur.send_command('led_color','4B',n,t,g,b) # will encode a command to remotely calls the function ``led_color`` # where the values of the variables ``n,t,g,b`` are passed to that function.
- UartRemote.receive_command(wait=True)
Receives a command and returns a tuple
(<command>, <data>). If there is a failure, the<command>will be equal to ‘err’. Ifwaitis True, the methods waits until it receives a command.
- UartRemote.call(command, *type_data, **kwargs)
Sends a command to a remote host that is waiting for a call and will wait until an answer comes back. Optionally a parameter
timeout=...for the answer is self.timout, or passable as timeout=…
- UartRemote.process_uart(self, sleep=-2)
Processes a remote call if there is any. Upon receiving a remote call, the command is processed and the result is send back by internally calling the
reply_commandmethod. Sleeps forsleepms after every listen. This method is only used in a loop and is non-blocking (as not for the sleep period).
- UartRemote.reply_command(self, command, value)
Processes the received command by calling the function with name command(value) and passes the arguments as defined in
value. The result of this function call is send back by calling thesend_command(ack_command,result)method with with theack_commandis the received command prepended with ack_ and the result (if any) is the return value of the function formatted according to the functions format string.
- UartRemote.loop()
This is an endless loop around the
process_uartmethod, replying on all incoming calls. The slave side instants typically has the following code running:from uartremote import * ur = UartRemote() ur.loop() # wait for incoming commands
- UartRemote.add_module(module_name)
Sends a command to the other side instructing it to import the module with name
module_name. Themodule_nameargument has type string. After importing the module, the remote side calls the function <module>.add_commands(). This is a function that you should add to the modules you want to remotely import. See for usage Example load module.
- UartRemote.add_command(command_function, format='', name=None)
Adds a command command to the dictionary of
UartRemote.commandstogether with a function namecommand_function. Optionally, if thecommand_functionreturns any parameters, theformat_stringdescribes the type of the returned parameters. If thecommand_functiondoes not return a value, the format_string is ommited. The dictionary with commands is used by theUartRemote.reply_command()method to call the function as defined upon receiving a specific command. As an argument thedatathat is received is used.Below is an example of how to use the
add_commandmethod:def example(a,b): # example function receiving two arguments and returning the sum of a and b return (a+b) ur.add_command(example,'f')
Here
uris the instantiation of theUartRemoteclass and the functionexamplewill return the sum as type float.
- UartRemote.get_remote_commands()
Returns an array containing the commands available by the remote uartremote. You will see a number of default built-in commands such as echo. This method can be used to query the commands that are added by remotely importing a new module. See for usage Example load module.
Helper Methods
The methods below are internally called by the methods listed above. You can use these methods should you like to have more low level control.
- Uartremote.command
Dictionary with the mapping of command name to corresponding functions.
- UartRemote.encode(command, *typedata)
Encodes a command
command.*type_dataare a number of arguments that consist of a type defintiont, followed by one ore more variables of the type corresponding with the paramatert.For example:
ur=UartRemote() ur.encode('led_color','4B',1,2,3,4) >>> b'\x11\tled_color\x024B\x01\x02\x03\x04'
- UartRemote.decode(bytestr)
Decodes an encoded bytestring
bytestras a tuple with the command and the parameters. If a command without parameters was encoded, the parameters will beNone.For example:
ur=UartRemote() ur.decode(b'\x11\tled_color\x024B\x01\x02\x03\x04') >>> ('led_color', (1, 2, 3, 4))
- UartRemote.read_all()
Returns all bytes that are available in the UART receive buffer.
- UartRemote.force_read(self, size=1, timeout=50)
Some platforms read too fast from the UART and return 0 or None. This method loops until it receives a valid number of
sizebytes withintimeoutms.