Skip to content

Commit 1bf483a

Browse files
authored
Merge pull request #1882 from arduino/sync/taddy/x8-docker-tutorials-revision
[PC-1623] Portenta X8: Docker Concept Update on Available Documentation
2 parents 108ee82 + 52dc9eb commit 1bf483a

File tree

6 files changed

+305
-170
lines changed

6 files changed

+305
-170
lines changed

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

+101-21
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ hardware:
1212

1313
## Overview
1414

15-
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+
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 are going to build a container based on a provided one.
1616

1717
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.
1818

19-
Thus you will learn how to do that. If you haven't done so, read through the [user manual](https://docs.arduino.cc/tutorials/portenta-x8/user-manual) to understand the fundamental concepts of the X8 and the provided infrastructure.
19+
You will be guided on how to achieve this setup. It is recommendable to familiarize yourself with the foundational elements of the Portenta X8 and its infrastructure by reading the [user manual](https://docs.arduino.cc/tutorials/portenta-x8/user-manual) if you have not already done so.
2020

2121
## Goals
2222

@@ -27,9 +27,9 @@ Thus you will learn how to do that. If you haven't done so, read through the [us
2727

2828
### Required Hardware and Software
2929

30-
- [Portenta X8](https://store.arduino.cc/products/portenta-x8) board
31-
- [Portenta breakout](https://docs.arduino.cc/hardware/portenta-breakout) board
32-
- 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)
30+
- [Portenta X8](https://store.arduino.cc/products/portenta-x8)
31+
- [Portenta breakout](https://docs.arduino.cc/hardware/portenta-breakout)
32+
- Any sensor (in this example, we will use an [BME680](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme680/) I<sup>2</sup>C module)
3333
- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor)
3434

3535
## Python® on the X8
@@ -40,9 +40,21 @@ Python® is a modern and powerful scripting language used for a wide range of ap
4040

4141
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.
4242

43-
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.
43+
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 establish 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.
4444

45-
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`.
45+
On the Linux side, there is a service that takes care of sending data between the two worlds. It is called **`m4-proxy`**.
46+
47+
You can check if the service is running by logging into the X8 via `adb shell` and then executing the next command:
48+
49+
```bash
50+
sudo journalctl -fu m4-proxy
51+
```
52+
53+
If the service has stopped unexpectedly, you can restart it with the following command:
54+
55+
```bash
56+
sudo systemctl restart m4-proxy
57+
```
4658

4759
## The Arduino Sketch
4860

@@ -63,25 +75,61 @@ Two additional header files need to be included to enable the RPC mechanism on P
6375
#include <SerialRPC.h>
6476
```
6577

66-
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.
78+
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.
79+
80+
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.
6781

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

70-
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).
84+
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.
85+
86+
That is because the labeled I<sup>2</sup>C pins on the Portenta Breakout are only available on the Linux side. If you are 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).
7187

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

74-
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.
90+
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.
7591

7692
### Debugging the Arduino Sketch
7793

78-
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.
94+
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.
95+
96+
This service needs to run on the Linux side of the X8. You can get the files [here](assets/py-serialrpc.zip). The compressed file will have every file needed to build a container as the docker compose app. From the command prompt of your local machine, navigate to the adb tool folder and upload the files to the X8 with command:
97+
98+
```bash
99+
adb push <local directory path>/py-serialrpc /home/fio
100+
```
101+
102+
Log into the X8 shell with `adb shell` and navigate into the `serialrpc` folder. Build the container using
103+
104+
```bash
105+
sudo docker build . -t py-serialrpc`
106+
```
107+
108+
The `-t` flag assigns a tag to the container. Then run the container by executing `cd..` and then:
109+
110+
```bash
111+
sudo docker compose up -d
112+
```
113+
114+
The `-d` flag detaches the container so it runs in the background. Note that this will run the docker compose app and have the container built persistently across reboots by registering it as a systemd service.
79115

80-
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`.
116+
To stop the container, run:
81117

82-
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`.
118+
```bash
119+
sudo docker compose stop
120+
```
83121

84-
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**.
122+
Check if the container is running by executing:
123+
124+
```bash
125+
sudo docker ps
126+
```
127+
128+
You can then access the log of its service at any time by using following command from the **same directory**:
129+
130+
```bash
131+
sudo docker compose logs -f --tail 20
132+
```
85133

86134
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.
87135

@@ -97,7 +145,25 @@ rpc_client = RpcClient(rpc_address)
97145
temperature = rpc_client.call('temperature')
98146
```
99147

100-
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:
148+
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 Portenta X8 via:
149+
150+
```bash
151+
adb push <local directory path>/python-sensor-rpc /home/fio
152+
```
153+
154+
Log into the X8 via `adb shell`. Then navigate into the `python-sensor-rpc` folder and execute:
155+
156+
```bash
157+
sudo docker build . -t python-sensor-rpc
158+
```
159+
160+
When it has finished, you can run the container with:
161+
162+
```bash
163+
sudo docker compose up
164+
```
165+
166+
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:
101167

102168
```bash
103169
python-sensor-rpc_1 | ============================================
@@ -111,27 +177,41 @@ python-sensor-rpc_1 | Gas: 136.496
111177
python-sensor-rpc_1 | Altitude: 311.0769348144531
112178
```
113179

114-
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:
180+
Whenever you change anything in the Python® script on your computer, you will have to resync and push the new script to the Portenta X8 and rebuild the container. Following command sequence will help you to do this process:
115181

116182
```bash
117183
# On your computer
118184
adb push python-sensor-rpc /home/fio
119185
```
120186

121187
```bash
122-
# On X8
123-
sudo docker-compose down
188+
# On the Portenta X8
189+
sudo docker compose down
190+
```
191+
192+
```bash
193+
# On the Portenta X8
124194
sudo docker build . -t python-sensor-rpc
125-
sudo docker-compose up
126195
```
127196

128-
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"]`.
197+
```bash
198+
# On the Portenta X8
199+
sudo docker compose up
200+
```
201+
202+
Alternatively, you could modify the files directly on the X8 using an editor such as **VIM**, so you do not need to upload the files every time. Rebuilding the container will be necessary in any case though.
203+
204+
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 will find the `ENTRYPOINT` command that takes multiple arguments. In our example:
205+
206+
```python
207+
ENTRYPOINT [ "python3", "m4_to_python.py"]`
208+
```
129209
130210
## Conclusion
131211
132212
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.
133213
134214
### Next Steps
135215
136-
- You may now further process the data that you receive from the Arduino sketch and e.g. upload it to a Cloud service or similar.
216+
- You may further process the data you receive from the Arduino sketch and, e.g., upload it to a Cloud service or similar.
137217
- Familiarize yourself with Docker commands to adjust the docker configuration to your needs.

0 commit comments

Comments
 (0)