UNO Q: Possible to connect Python (not containerized) with Arduino ?

Hello !

As the title says, I would like to know it it is possible for a Python file executed directly in the system, so not in a container like when launched with App Lab, to use RPC with a .ino file.

For a school project I need to program an autonomous RC car with a LiDAR that send data through a ttyACM0 device. But since Python containers in App Lab don’t have access to tty devices (please Arduino devs, change that, this makes the potential of this card so much below what it could be…), I thought that I could maybe use a Python code executed outside of App Lab and connect to my Arduino file through RPC. But I don’t know if it’s possible…

I follow these steps to communicate between Command Prompt Window and Arduino UNO R3 using Python script:
1. This is my Python script saved in my working folder.

import serial
import time

# Replace with your COM port (e.g., COM3, COM5)
PORT = "COM3"
BAUDRATE = 9600

try:
    # Open serial port
    ser = serial.Serial(PORT, BAUDRATE, timeout=1)
    time.sleep(2)  # Wait for Arduino to reset

    print(f"Connected to {PORT}")

    while True:
        # Send data to Arduino
        user_input = input("Enter message (or 'exit'): ")

        if user_input.lower() == 'exit':
            break

        ser.write((user_input + '\n').encode())

        # Read response from Arduino
        time.sleep(0.1)
        while ser.in_waiting:
            response = ser.readline().decode(errors='ignore').strip()
            print("Arduino:", response)

except serial.SerialException as e:
    print("Error:", e)

finally:
    if 'ser' in locals() and ser.is_open:
        ser.close()
        print("Serial port closed")

2. This is my Arduino sketch uploaded in my UNO R3.

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    String msg = Serial.readStringUntil('\n');
    Serial.print("Received: ");
    Serial.println(msg);
  }
}

3. Interactive message in Console Window:

Connected to COM3
Enter message (or 'exit'): Hello
Arduino: Received: Hello
Enter message (or 'exit'): I am ok!
Arduino: Received: I am ok!
Enter message (or 'exit'):

Unfortunately that’s not what I was talking about, I’m using and Arduino UNO Q, AND I need the Python code to run directly on the Linux system on the board itself.

You might take a look at this thread:

I suggest examining the LIDAR datasheet to see if there are interface options other than USB. Some have UART 3.3V logic level and/or I2C 3.3V logic level. The UNO Q STM32 has a UART interface (Serial) on pins 0 and 1. It also has two I2C interfaces (Wire and Wire1).

Hi @ashio.

You can use the same "bridge" interface in Python scripts that run directly on the standard Linux machine of the UNO Q. I'll provide instructions you can follow to do that:

A. Open a Terminal

This demo will use command line invocations run on the UNO Q's Linux machine. For this reason, you first need to open a command line terminal on the Linux machine.

If you are single-board computer (SBC) mode, open the terminal via the desktop menu.


If you are using the board in PC hosted mode, you can open a terminal using Android Debug Bridge (ADB) via the USB connection to the board, by following the instructions here:

https://docs.arduino.cc/tutorials/uno-q/adb/

Or open a terminal using Secure Shell (SSH) via the network connection to the board, by following the instructions here:

https://docs.arduino.cc/tutorials/uno-q/ssh/

B. Create Virtual Python Environment

When you are working with Python scripts on the standard Linux machine of the UNO Q, it is a good idea to create a virtual environment for the project. This ensures the installed Python package dependencies of the script are isolated from the global environment, both to avoid the possibility of their presence affecting other Python scripts, and so that any Python scripts installed in the global environment can't interfere with the script you are working with.

I would normally recommend using my favorite tool, Poetry for this purpose. However, the tool chosen by the developers of the Arduino App framework is uv. It makes sense to utilize the same tool used in the App's container. Furthermore, I believe this is actually more lightweight than Poetry, and thus well suited for use on the UNO Q where we must conserve our use of computing resources.

So let's start by installing uv:

https://docs.astral.sh/uv/getting-started/installation/

I did it by running the following command from the terminal:

curl -LsSf https://astral.sh/uv/install.sh | sh && source $HOME/.local/bin/env

Now create a uv project by running the following command from the terminal:

uv init --bare --no-package ~/bridgetest && cd ~/bridgetest

C. Install Project Dependencies

Now we need to install the arduino Python package that provides the arduino.app_utils module, which facilitates communication between the Python script running on the UNO Q's Linux machine with the sketch program running on the board's microcontroller via the "bridge" interface. We can use the uv add command to install that package into the virtual environment for our "bridgetest" project. Normally we can do this by simply specifying the package name as the argument to the command. However, Arduino has not published the arduino package to the Python package registry, so that is not possible. For this reason, we must instead install it from the wheel file published by Arduino on the "Releases" page of the arduino/app-bricks-py GitHub repository. Currently the latest release of the package is version 0.8.0, which we can install into the virtual environment by using this command:

uv add https://github.com/arduino/app-bricks-py/releases/download/release%2F0.8.0/arduino_app_bricks-0.8.0-py3-none-any.whl

It is also necessary to install some standard packages that are dependencies of the arduino package. These are in the Python package registry, so can be installed in the ordinary manner:

uv add numpy watchdog

Now we can use the arduino.app_utils module in the Python script running directly on the standard Linux machine, just the same as we would do in the Python script component of an Arduino App.

D. Create Project Code

For the purpose of this demonstration, let's just use the existing Python script and Arduino sketch from the simple "Blink LED" example App:

wget --directory-prefix=python https://raw.githubusercontent.com/arduino/app-bricks-examples/refs/tags/0.8.0/examples/blink/python/main.py && wget --directory-prefix=sketch https://raw.githubusercontent.com/arduino/app-bricks-examples/refs/tags/0.8.0/examples/blink/sketch/sketch.ino https://raw.githubusercontent.com/arduino/app-bricks-examples/refs/tags/0.8.0/examples/blink/sketch/sketch.yaml

E. Run Project

Since we are using the bridge, we must have an appropriate sketch program running on the microcontroller, in addition to the Python script on the Linux machine. So we should start by compiling and uploading the sketch, which we obtained from the "Blink LED" example App.

You can use Arduino IDE to upload sketches to your UNO Q board if you like. However, for the sake of simplicity in this demo, I'll use the Arduino CLI command line tool, which is preinstalled on the UNO Q's Linux machine:

arduino-cli compile --fqbn arduino:zephyr:unoq --upload sketch/

Now let's run the Python script:

uv run python/main.py

You should now see the built-in LED on the UNO Q board blinking at 0.5 Hz.

Thank you so much ! I followed your answer meticulously and it worked immediatly !

I’m marking this as answer.

You are welcome. I'm glad if I was able to be of assistance.

Regards, Per

As I understand it, the OP has a Linux-based PC; where, upon connecting a USB/UART LiDAR sensor, it appears as a /dev/ttyACM0 device in the Linux filesystem. This allows him to perform read and write operations on the device.

He wants to apply the same idea on the UNO Q platform, which has a Linux-driven MPU. The difficulty he faced is that a native Python script must be loaded into the eMMC memory, bypassing App Lab, since the containerized environment of App Lab cannot access the /dev/ttyACM0 device. @ptillisch has provided him with a solution in #8.

Unfortunately, the OP was quite reluctant to explain exactly what he wants in response to my post #2.

Now, the question to OP @ashio — how does he plan to connect his USB- or UART-based LiDAR sensor to the 1.8 V MPU of the UNO Q board? Why is he interested in connecting the sensor to the MPU instead of the MCU, which would allow direct data acquisition and peripheral control?

I would be very interested to see OP's @ashio native Python script that accesses the /dev/ttyACM0 device, processes the LiDAR data, and then issues commands to the MCU via the Router Bridge to control peripherals or motors.

The goal of the project I’m making is for my college. We are participating in a race of autonomous RC cars in groups of 4 by car. I am in charge of the LiDAR so I have to read and decode the data sent, then make the calculation needed to format correctly the data and send it to the core program (that another peron in my group is in charge of). I had to connect it to the MPU because it what is asked in the project requirements, and we also believe that it makes the communication between the LiDAR and core programs more reliable.

Note that for the moment the project is still being developped so I don’t have much to show at the time. But in the following 2/3 months everything will be completed so I will put the link to a repository containing what we’ve made with my crew.

Which terminal is it?
1. Terminal opened in Section-A using Android Debug Bridge?

or

2. Shell Terminal opened from within App Lab clicking on >_ icon located at the bottom-left?

You can use any terminal you like. I didn't mention the option of opening a terminal via the >_ button ("Connect to the board's shell") in Arduino App Lab because this topic is about making projects with the UNO Q outside the Arduino App framework. Arduino App Lab is a tool for developing Arduino Apps. So it is not useful for this use case. It doesn't make sense to open Arduino App Lab only for the purpose of opening a terminal, and this might even cause confusion by making people think that Arduino App Lab can somehow be utilized in the development of the project.

That said, you are welcome to use the >_ button in Arduino App Lab to open the shell terminal if you find that convenient. Just be careful to avoid getting confused by erroneously thinking that you are going to be using the Arduino App framework.

The Command Prompt terminal (opened via Start ---> Cmd) does not accept those commands of your #8. But the Shell Terminal accepts them cordially.

The Shell Terminal automatically opens when I issue "C:\adb shell" command and you are right that I don't need to go to the App Lab for opening that.

I am not sure I am understanding.

Note: I just went through his #8 using my KiTTy window and it worked fine


And the LED was blinking at about .5hz...

But the window opened up by Start->Cmd opens up a command window, that is
talking directly to your own machine, not to the Q
Notice the prompt is to my local C: drive

Unless of course you use some SSH command to connect you to the Q like:

How have you opened this terminal?

Issuing c:\adb shell, I can open Shell Terminal to communicate with Linux OS of my UNO Q Board.

I am failing to execute this command:

Did you first create one? Like in his post #8

And if you tried running it again you probably just have to do the cd part...