Skip to content

Commit d7cf216

Browse files
authored
[PC-1027] Portenta X8: Data Exchange Between Python on Linux and an Arduino Sketch Redefintion (#356)
* Initial commit - minor content update * Tutorial content update * Tutorial content minor update * Tutorial content update * Tutorial content update
1 parent e259a98 commit d7cf216

File tree

1 file changed

+28
-17
lines changed
  • content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange

1 file changed

+28
-17
lines changed

Diff for: content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/content.md

+28-17
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ hardware:
1111

1212
## Overview
1313

14-
The container infrastructure provided by Arduino contains a pre-built Python® image that you can use to run Python® applications on the Portenta X8. In this tutorial we're going to build a container based on a provided one. While all the peripherals can be accessed from the iMX8 processor running the Linux environment, it can be useful to let the onboard microcontroller take care of certain peripheral handling and just exchange the required data between the microcontroller and the Python® application. In this tutorial you will learn how to do that. If you haven't done so, read through the [foundations article](/tutorials/portenta-x8/x8-fundamentals) to understand the fundamental concepts of the X8 and the provided infrastructure.
14+
The container infrastructure provided by Arduino contains a pre-built Python® image that you can use to run Python® applications on the Portenta X8. In this tutorial, we're going to build a container based on a provided one.
15+
16+
While all the peripherals are accessible from the iMX8 processor running the Linux environment, it can be useful to let the onboard microcontroller take care of certain peripheral handling and exchange only the required data between the microcontroller and the Python® application.
17+
18+
Thus you will learn how to do that. If you haven't done so, read through the [foundations article](/tutorials/portenta-x8/x8-fundamentals) to understand the fundamental concepts of the X8 and the provided infrastructure.
1519

1620
## Goals
1721

@@ -20,25 +24,28 @@ The container infrastructure provided by Arduino contains a pre-built Python® i
2024
- Learn how to modify a container and run it
2125
- Learn how to use commands to debug the container and service infrastructure
2226

23-
## Required Hardware and Software
27+
### Required Hardware and Software
2428

2529
- [Portenta X8](https://store.arduino.cc/products/portenta-x8) board
2630
- [Portenta breakout](https://docs.arduino.cc/hardware/portenta-breakout) board
27-
- Any sensor (in this example we'll use an [BME680](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme680/) I<sup>2</sup>C module)
31+
- Any sensor (in this example, we'll use an [BME680](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme680/) I<sup>2</sup>C module)
32+
- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor)
2833

2934
## Python® on the X8
3035

31-
Python® is a modern and powerful scripting language that can be used for all sorts of use cases. In this tutorial we only read sensor data from an Arduino sketch without doing anything interesting with it, but you could extend the example and process the data further.
36+
Python® is a modern and powerful scripting language used for a wide range of applications. In this tutorial, we only read sensor data from an Arduino sketch, but you could extend the example and process the data further.
3237

3338
### Communication Between Linux and Arduino Sketches
3439

35-
The Python® script will run on the Linux side and therefore on the iMX8 processor. The Arduino sketch on the other hand will run on the STM32H747 microcontroller. That allows for real-time processing on the Arduino side while running a fully fledged operating system on iMX8. However the two processors need a communication mechanism to exchange data with one another. The communication mechanism that is being used is referred to as RPC (Remote Procedure Call). To facilitate the communication the M7 core on the STM32H747 microcontroller is used which hands over any data / request to the M4 core. That means your Arduino sketch will solely run on the M4 core. Dual core processing on the Arduino side is currently not supported.
40+
The Python® script will run on the Linux side and therefore on the iMX8 processor. The Arduino sketch, on the other hand, will run on the STM32H747 microcontroller. It allows for real-time processing on the Arduino side while running a fully-fledged operating system on iMX8.
41+
42+
However, the two processors need a communication mechanism to exchange data with one another. RPC (Remote Procedure Call) is the communication mechanism for this task. To facilitate communication, the M7 core on the STM32H747 microcontroller is used to hand over any data/request to the M4 core. That means your Arduino sketch will solely run on the M4 core. Dual-core processing on the Arduino side is currently not supported.
3643

37-
On the Linux side there is a service that takes care of sending data between the two worlds. It's called `m4-proxy`. You can check if the service is running by logging into the X8 via `adb shell` and then executing `sudo journalctl -fu m4-proxy`. If, for whatever reason, the service has stopped, you can restart it with `sudo systemctl restart m4-proxy`
44+
On the Linux side, there is a service that takes care of sending data between the two worlds. It's called `m4-proxy`. You can check if the service is running by logging into the X8 via `adb shell` and then executing `sudo journalctl -fu m4-proxy`. If the service has stopped unexpectedly, you can restart it with `sudo systemctl restart m4-proxy`.
3845

3946
## The Arduino Sketch
4047

41-
The Arduino sketch to read sensor data doesn't look much different from an ordinary sketch. The only thing that differs is that we expose the sensor data via RPC.
48+
The Arduino sketch to read sensor data doesn't look much different from an ordinary sketch. The only difference is that we expose the sensor data via RPC.
4249

4350
```arduino
4451
RPC.bind("temperature", []{ return bme.temperature; });
@@ -48,30 +55,34 @@ RPC.bind("gas", []{ return bme.gas_resistance / 1000.0; });
4855
RPC.bind("altitude", []{ return bme.readAltitude(SEALEVELPRESSURE_HPA); });
4956
```
5057

51-
Two additional header files need to be included:
58+
Two additional header files need to be included to enable the RPC mechanism on Portenta X8:
5259

5360
```arduino
5461
#include <RPC.h>
5562
#include <SerialRPC.h>
5663
```
5764

58-
The bind function makes the data available via the specified name e.g. "temperature". In our example an anonymous function is created that returns the corresponding sensor property whenever requested. Alternatively you could bind the name to an existing, named function instead. The data can then easily be requested using that name (e.g. "humidity") by querying the `m4-proxy` service. Once data is being requested it is packaged as a message and sent over SPI to the iMX8.
65+
The `RPC.bind()` method makes the data available via the specified name e.g. "temperature". In our example, an anonymous function is created to return the corresponding sensor property whenever requested. Alternatively, you could bind the name to an existing, named function instead. The data can then easily be requested using that name (e.g. "humidity") by querying the `m4-proxy` service. Once data is requested, it is packaged as a message and sent over SPI to the iMX8.
5966

6067
![The iMX8 and the STM32H747 processor communicate via SPI](assets/component-placement.svg)
6168

62-
You can find the sketch in the software package [here](assets/python-sensor-rpc.zip). You may need to change the sketch depending on what sensor you would like to read from. If you're using an I<sup>2</sup>C sensor, you can connect SCL to **PWM6** and SDA to **PWM8** on the Portenta breakout. That's because the labeled I<sup>2</sup>C pins on the Portenta Breakout are only available on the Linux side. If you're using an analog sensor you can connect it to any analog pin. Please refer to the pinout diagram on the Portenta Breakout [documentation page](/hardware/portenta-breakout).
69+
You can find the sketch in the software package [here](assets/python-sensor-rpc.zip). You may need to change the sketch depending on the choice of the sensor to read from. If you're using an I<sup>2</sup>C sensor, you can connect SCL to **PWM6** and SDA to **PWM8** on the Portenta breakout. That's because the labeled I<sup>2</sup>C pins on the Portenta Breakout are only available on the Linux side. If you're using an analog sensor, you can connect it to any analog pin. Please refer to the pinout diagram on the Portenta Breakout [documentation page](/hardware/portenta-breakout).
6370

6471
![Wiring diagram of an I2C sensor attached to the X8 via Portenta Breakout](assets/sensor-wiring-breakout.svg)
6572

66-
Make sure you've installed the "Arduino Mbed OS Portenta Boards" core and upload the sketch to the X8 in the Arduino IDE or via Arduino CLI.
73+
Make sure you have installed the "Arduino Mbed OS Portenta Boards" core and upload the sketch to the X8 in the Arduino IDE or via Arduino CLI.
6774

6875
### Debugging the Arduino Sketch
6976

70-
To check if the Arduino sketch is working correctly you may want to read the messages from the `Serial.println` statements. You can't currently read them directly in the serial monitor of the Arduino IDE. Instead, you can use a simple service called `py-serialrpc` which listens for those messages and prints them to the console. This service needs to run on the Linux side of the X8. You can get the files [here](assets/py-serialrpc.zip). From the command prompt of your local machine, navigate to the adb tool folder and upload the files to the X8 with `adb push <local directory path>/py-serialrpc /home/fio`.
77+
To check if the Arduino sketch is working correctly, you may want to read the messages from the `Serial.println` statements. You cannot currently read them directly in the serial monitor of the Arduino IDE. Instead, you can use a simple service called `py-serialrpc`, which listens for those messages and prints them to the console.
78+
79+
This service needs to run on the Linux side of the X8. You can get the files [here](assets/py-serialrpc.zip). From the command prompt of your local machine, navigate to the adb tool folder and upload the files to the X8 with `adb push <local directory path>/py-serialrpc /home/fio`.
7180

7281
Log into the X8 shell with `adb shell` and navigate into the `serialrpc` folder. Build the container using `sudo docker build . -t py-serialrpc`. The `-t` flag assigns a tag to the container. Then run the container by executing `cd..` and then `sudo docker-compose up -d`. The `-d` flag detaches the container so it runs in the background. Note that this will run the docker container persistently across reboots by registering it as a systemd service. To stop the container, run `sudo docker-compose stop`.
7382

74-
Check if the container is running by executing `sudo docker ps`. You can then access the log of this service at any time by executing `sudo docker-compose logs -f --tail 20` from the **same directory**. If you don't run the container in the background (skip the `-d` flag), you will get the console output directly in the executing shell. Once the container is running you will see the messages that are being sent from the M4.
83+
Check if the container is running by executing `sudo docker ps`. You can then access the log of this service at any time by executing `sudo docker-compose logs -f --tail 20` from the **same directory**.
84+
85+
If you do not wish to run the container in the background, skip the `-d` flag, you will get the console output directly in the executing shell. Once the container is running, you will see the messages being sent from the M4.
7586

7687
## The Python® Application
7788

@@ -85,7 +96,7 @@ rpc_client = RpcClient(rpc_address)
8596
temperature = rpc_client.call('temperature')
8697
```
8798

88-
The files for the complete Python® application can be found in the same package as the Arduino sketch (see above). Like in the previous step, upload the `python-sensor-rpc` folder to the X8 via `adb push <local directory path>/python-sensor-rpc /home/fio`. Log into the X8 via `adb shell`. Then navigate into the `python-sensor-rpc` folder and execute `sudo docker build . -t python-sensor-rpc`. When it's done you can run the container with `sudo docker-compose up`. After a few seconds you should see the output from the Python application featuring the sensor readings on the M4 that were piped through the RPC mechanism. The output should look similar to the following:
99+
The complete Python® application files are in the same package as the Arduino sketch (see above). Like in the previous step, upload the `python-sensor-rpc` folder to the X8 via `adb push <local directory path>/python-sensor-rpc /home/fio`. Log into the X8 via `adb shell`. Then navigate into the `python-sensor-rpc` folder and execute `sudo docker build . -t python-sensor-rpc`. When it is finished, you can run the container with `sudo docker-compose up`. After a few seconds, you should see the output from the Python application featuring the sensor readings on the M4 that exchanges through the RPC mechanism. The output should look similar to the following:
89100

90101
```
91102
python-sensor-rpc_1 | ============================================
@@ -99,7 +110,7 @@ python-sensor-rpc_1 | Gas: 136.496
99110
python-sensor-rpc_1 | Altitude: 311.0769348144531
100111
```
101112

102-
Keep in mind that, whenever you change anything in the Python® script on your computer you will have to sync it back to the X8 and re-build the container:
113+
Whenever you change anything in the Python® script on your computer, you will have to sync it back to the X8 and re-build the container. Following command sequence will help you to do this process:
103114

104115
```
105116
# On your computer
@@ -111,11 +122,11 @@ sudo docker build . -t python-sensor-rpc
111122
sudo docker-compose up
112123
```
113124

114-
Alternatively you could modify the files directly on the X8 using an editor such as VIM so you don't need to upload the files all the time. Re-building the container will be necessary in any case though. In case you wonder how to specify the Python® script that is executed when running a container, have a look at the `Dockerfile` file. There you'll find the `ENTRYPOINT` command that takes multiple arguments. In our example: `ENTRYPOINT [ "python3", "m4_to_python.py"]`
125+
Alternatively, you could modify the files directly on the X8 using an editor such as VIM, so you don't need to upload the files every time. Re-building the container will be necessary in any case though. If you wonder how to specify the Python® script that is executed when running a container, have a look at the `Dockerfile` file. There you'll find the `ENTRYPOINT` command that takes multiple arguments. In our example: `ENTRYPOINT [ "python3", "m4_to_python.py"]`.
115126

116127
## Conclusion
117128

118-
In this tutorial you learned how to use the docker infrastructure to build a container that runs a Python® application. You have also learned how to use the RPC mechanism to exchange data between the microcontroller and the iMX8 which runs the Linux operating system.
129+
In this tutorial, you learned how to use the docker infrastructure to build a container that runs a Python® application. You have also learned how to use the RPC mechanism to exchange data between the microcontroller and the iMX8, which runs the Linux operating system.
119130

120131
### Next Steps
121132

0 commit comments

Comments
 (0)