Skip to content

Commit 851ba3f

Browse files
committed
Tutorial documentation update
1 parent f91abc2 commit 851ba3f

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed
86.6 KB
Loading

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

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ docker compose up -d
151151

152152
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.
153153

154-
If you encounter issues with `docker compose` (such as `invalid reference format` errors), you can run the container directly using:
154+
The provided `docker-compose.yml` files are preconfigured to pull images from a specific container registry (`hub.foundries.io/${FACTORY}/python-rpc-serial:latest`). When building locally, the `${FACTORY}` environment variable may not be defined in your environment, causing `invalid reference format` errors. For local development with locally-built images, it is recommended to use `docker run` directly as shown below:
155155

156156
```bash
157157
docker run -d \
@@ -247,7 +247,7 @@ When it has finished, you can run the container with:
247247
docker compose up
248248
```
249249

250-
If you encounter issues with `docker compose`, you can run the container directly using:
250+
The `docker-compose.yml` file requires a `${FACTORY}` environment variable for registry configuration. If undefined, this causes `invalid reference format` errors. You can run the container directly using your locally-built image:
251251

252252
```bash
253253
docker run -d \
@@ -263,7 +263,7 @@ docker run -d \
263263
python-rpc-sensors:latest
264264
```
265265

266-
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:
266+
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:
267267

268268
![Portenta X8 RPC Example](assets/x8-python-sensor-factory.gif)
269269

@@ -317,16 +317,34 @@ docker run -d --name python-rpc-sensors --restart unless-stopped -e PYTHONUNBUFF
317317

318318
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.
319319

320-
If you're wondering how to specify the Python® script to run when a container is started, have a look at the `Dockerfile` in the repository. There you will find the `ENTRYPOINT` command that takes multiple arguments. In this example:
320+
The repository contains the Python® script at `/python/main.py` which is copied into the container at `/app/python/main.py` during the build process. The Arduino sketch is also included in the repository at `/firmware/rpc-sensors` for reference.
321+
322+
If you are wondering how to specify the Python® script to run when a container is started, have a look at the `Dockerfile` in the repository. For the `python-rpc-sensors` example, the Dockerfile uses:
321323

322324
```python
323-
ENTRYPOINT ["python3", "main.py"]
325+
CMD ["python","-u","main.py"]
324326
```
325327

328+
The `-u` flag runs Python® in unbuffered mode, making sure that print statements and logs appear in the container output.
329+
326330
## Sensor Implementation
327331

328332
The example provided in the repository uses preset sensor values for testing. To connect and read from actual sensors, you need to modify the Arduino sketch to include the appropriate sensor library and implement proper sensor initialization and reading.
329333

334+
### Required Arduino Libraries
335+
336+
To try out the sensor examples, you need to install the corresponding libraries in the Arduino IDE:
337+
338+
- [Adafruit BME680 Library](https://github.com/adafruit/Adafruit_BME680)
339+
- [Adafruit BME280 Library](https://github.com/adafruit/Adafruit_BME280_Library)
340+
- Adafruit Unified Sensor (Notified when installing either libraries above using the Arduino IDE's library manager)
341+
342+
Install these libraries via the Arduino IDE Library Manager **Sketch > Include Library > Manage Libraries**, then upload the modified sketch to the Portenta X8.
343+
344+
![Adafruit BMEX80 Library](assets/bme-library-manager.png)
345+
346+
The Python® script and Docker configuration do not require any changes when switching from preset sensor values to real sensors. The same `main.py`, `Dockerfile`, and container setup work with both implementations since they use the same RPC function names (`temperature`, `humidity`, `pressure`, `gas`, `altitude`).
347+
330348
### BME680 Sensor Example
331349

332350
The BME680 is an environmental sensor that provides temperature, humidity, pressure, gas resistance, and altitude readings. Here is an example implementation:
@@ -405,7 +423,7 @@ void loop()
405423
}
406424
```
407425

408-
This sketch includes sensor initialization with error checking, configuration of oversampling rates, and continuous sensor readings in the loop that can be monitored through the serial output or accessed via RPC from the Python application.
426+
This sketch includes sensor initialization with error checking, configuration of oversampling rates, and continuous sensor readings in the loop that can be monitored through the serial output or accessed via RPC from the Python® application.
409427

410428
### BME280 Sensor Example
411429

@@ -469,13 +487,13 @@ void loop()
469487
}
470488
```
471489

472-
For the BME280, a dummy gas RPC binding that returns 0 is included since this sensor does not have gas sensing capabilities. This provides compatibility with the Python script that expects all five RPC calls.
490+
For the BME280, a dummy gas RPC binding that returns 0 is included since this sensor does not have gas sensing capabilities. This provides compatibility with the Python® script that expects all five RPC calls.
473491

474492
![Portenta X8 RPC](assets/x8-rpc-c.gif)
475493

476-
### Python Script Considerations
494+
### Python® Script Considerations
477495

478-
The Python script in the repository uses an optimized approach for making multiple RPC calls:
496+
The Python® script in the repository uses an optimized approach for making multiple RPC calls:
479497

480498
```python
481499
def get_data_from_m4(rpc_address):
@@ -495,7 +513,7 @@ This approach creates a new `RpcClient` instance for each call due to a known li
495513

496514
### RPC Communication Issues
497515

498-
If you are experiencing issues with RPC communication, such as the Python script outputting:
516+
If you are experiencing issues with RPC communication, such as the Python® script outputting:
499517

500518
```
501519
Unable to retrieve data from the M4
@@ -535,7 +553,7 @@ Flash the firmware using the programming script:
535553
sudo /usr/arduino/extra/program.sh
536554
```
537555

538-
The programming script will verify and flash the new firmware. You should see output indicating the programming progress, verification, and successful reset. After flashing completes, restart the X8 and try rerunning your Python application or [example](#building-the-image-from-source).
556+
The programming script will verify and flash the new firmware. You should see output indicating the programming progress, verification, and successful reset. After flashing completes, restart the X8 and try rerunning your Python® application or [example](#building-the-image-from-source).
539557

540558
![Portenta X8 STM32H7 firmware flashed](assets/stm32h7-flash-rpc.png)
541559

@@ -569,9 +587,33 @@ Replace `YOUR_USERNAME` with your actual Windows username. Build the firmware:
569587
make
570588
```
571589

590+
The compiled binary will be located at:
591+
592+
```
593+
build/STM32H747AII6_CM7.bin
594+
```
595+
596+
If you encounter compilation errors with `src/pwm.c` regarding `initializer element is not constant`, you may need to apply a fix. Edit line 38 in `src/pwm.c` and change:
597+
598+
```c
599+
static unsigned int const MAX_PWM_CHANNEL_NUM = (NUM_PWM_CHANNELS - 1);
600+
```
601+
602+
To
603+
604+
```c
605+
#define MAX_PWM_CHANNEL_NUM (NUM_PWM_CHANNELS - 1)
606+
```
607+
608+
Then run the following command again:
609+
610+
```bash
611+
make clean && make
612+
```
613+
572614
## Conclusion
573615

574-
In this tutorial, you learned how to use the Docker infrastructure to run a Python® application on the Portenta X8. You explored two approaches to running the application: using a prebuilt Docker image for quick deployment and building the image from source for customization. You have also learned how to use the RPC mechanism to exchange data between the microcontroller and the iMX8, which runs Linux, and how to implement real sensor readings using BME680 and BME280 sensors.
616+
In this tutorial, you learned how to use the Docker infrastructure to run a Python® application on the Portenta X8. You explored two approaches to running the application: using a prebuilt Docker image for quick deployment and building the image from source for customization. You have also learned how to use the RPC mechanism to exchange data between the microcontroller and the iMX8, which runs Linux, and how real sensor readings can be implemented using BME680 and BME280 sensors.
575617

576618
### Next Steps
577619

0 commit comments

Comments
 (0)