SerialTalk documentation
This is a library for robust, near real-time communication between two UART devices. We developed it on python 3.9 with LEGO EV3, SPIKE Prime and other MicroPython (ESP/STM32) modules. The library is available on github: UartRemote on GitHub. The library has the following properties:
It is fast enough to read sensor data at 30-50Hz.
It is fully symmetrical, so master and slave can have the same import.
It includes a RAW REPL mode to upload code to a slave module. This means you can develop code for both modules in one file.
It is implemented in MicroPython and Arduino/C code. With Arduino code, much higher sensor reading speeds are possible, but flashing is a bit less user friendly.
The library has a command loop to wait and listen for calls. That loop is customizable and non-blocking so you can add your own code to it.
The python-struct-like encoding is included in the payload, so the other side always knows how to decode it.
Compatable with most RS232-TTL 3.3v/5v converter board to further expand i/o possibilities.
Remote module importing
Usage: you can use all of the parts of this library for your own projects. Please give us credits at least. We put a lot spare time in this. You are also welcome to contribute. Please fork and PR.
Goal
The package aims to facilitate communication between devices like Robots and peripheral embedded systems or monitors over a serial communication line. Sounds abstract? Think connecting an OpenMV camera to a LEGO SPIKE Prime Robot. Or linking up two pyboards.
Installation
The easiest way to install it is with the mpy-robot-tools installer.
Usage
When you want default UART for the platform you’re running on, just go:
from serialtalk.auto import SerialTalk
When you want special channels like sockets or Bluetooth, do it like this:
from serialtalk import SerialTalk
from serialtalk.sockets import ClientSocketSerial
ser = SerialTalk(ClientSocketSerial("127.0.0.1",8080))
ser.call('echo','read?')
Example with OpenMV H7
Copy the complete serialtalk directory to the OpenMV flash (not the whole repo, just the library)
Create a main.py with this code. It is an adaptation of the OpenMV Hello world
import sensor, image, time
from serialtalk.auto import SerialTalk
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.skip_frames(time = 2000) # Wait for settings take effect.
clock = time.clock() # Create a clock object to track the FPS.
st = SerialTalk() # Create UART comm object
def fps(): # Create function to call from uart
return clock.fps()
st.add_command(fps,"repr") # Add function to callable uart commands
while(True):
clock.tick() # Update the FPS clock.
img = sensor.snapshot() # Take a picture and return the image.
st.process_uart() # Process aurt calls
print(clock.fps()) # Note: OpenMV Cam runs about half as fast when connected
# to the IDE. The FPS should increase once disconnected.
On the SPIKE Prime Install mpy-robot-tools with the installer script. Note that the installer may seem unresponsive. Just have some patience.
Run this script on SPIKE Prime:
from projects.mpy_robot_tools.serialtalk import SerialTalk
from projects.mpy_robot_tools.mshub import MSHubSerial
st = SerialTalk(MSHubSerial('F'))
print(st.call('echo','Hello there OpenMV!'))
print(st.call('fps'))
This should be the result: Spike result
SerialTalk modules
- class serialtalk.SerialTalk(serial_device, timeout=1500, debug=False, **kwargs)
Bases:
object
Symmetrical communication library for Micropython devices: use the same SerialTalk class on both sides of the serial connection. This library allows you to call functions on a remote device. Use call(‘some_function’, arg1, arg2, …) for this. You can also listen for commands on a local device. Use add_command() to add functions to listen for.
- Parameters:
serial_device – The serial device to use for communication. It should have a write(), read() and any() method.
timeout – The timeout in milliseconds to wait for a reply, default 1500.
debug – If True, print debug messages, default False.
- add_command(command_function, return_format='', name=None)
Add a function or method to the list of commands that can be called from a remote instance of SerialTalk.
- Parameters:
command_function (function or method) – The function to add.
return_format (struct.pack format string or "repr" for returning Python objects.) – The format of the return value, default “” for no return value.
name (str) – The name of the command, default None for the function name.
- add_module(module: str)
Load a module on the remote device and execute add_commands(serialtalk_instance) within that module to add the module’s commands to the remote command list.
- Parameters:
module (str) – The name of the module to load.
- call(command: str, *args, wait=False)
Send a command to a remote host that is processing serialtalk commands. Wait until an answer comes or until self.timeout. Return the answer, or (err, …) if there was a problem.
- Parameters:
command (str) – The command to send.
args – Any number arguments to send with the command.
wait – If True, wait for a reply forever, default False.
- loop()
Start processing incoming commands until the repl is enabled remotely. (If repl is supported by the local device)
- process()
Process incoming commands. Call this in your main loop. It will handle incoming commands, if any, reply to them, and return.
- repl_activate()
Cajole the other side into a raw REPL with a lot of ctrl-c and ctrl-a.
- repl_run(command: str, reply=True, raw_paste=True)
Execute MicroPython remotely via raw repl. RAW repl must be activated first! with repl_activate()
- Parameters:
command (str) – The micropython code to execute
reply (bool) – If True, return the result of the command, if False, return None, default True.
raw_paste (bool) – If True, use raw paste. Turn off for more compatility, default True.
- send_command(command: str, *argv, flush=True)
Send a command to a remote host that is processing serialtalk commands. Does not wait for an answer.
- Parameters:
command (str) – The command to send.
argv – Any number arguments to send with the command.
- class serialtalk.auto.SerialTalk(*args, **kwargs)
Bases:
SerialTalk
SerialTalk class that automatically detects the platform and uses the correct SerialTalk implementation also sets the correct default values for the platform.
- class serialtalk.sockets.ClientSocketSerial(host, port)
Bases:
SocketSerial
Serial interface for python3 client sockets. Connects to a server host on a port.
For Micropython use usockets module. Harmonized behavior for SerialTalk.
- Parameters:
host (str) – Hostname or IP address of the server
port (int) – Port number of the server
- class serialtalk.sockets.SocketSerial(socket)
Bases:
object
Serial interface for python3 sockets. For Micropython use usockets module. Harmonized behavior for SerialTalk.
- Parameters:
socket (socket.socket) – Your server socket object
Roadmap, todo
test on esp8266 platform
test on bt comm channels
create pyserial/desktop channels