> For the complete documentation index, see [llms.txt](https://andromeda-interfaces-inc.gitbook.io/andromeda-interfaces/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://andromeda-interfaces-inc.gitbook.io/andromeda-interfaces/advanced-telematics-display-module/software-development/can-interface-sample-app.md).

# CAN Interface Sample App

Here is an example of a Qt application that uses the CAN interface from TorizonOS to receive CAN messages and display them on the screen.

#### Prerequisites

* Ensure you have a CAN interface set up and connected to your ATDM.
* Ensure that the necessary CAN utilities and libraries are installed on your ATDM.

#### Example Code

This example uses the Python `python-can` library to interact with the CAN interface. You'll need to install this library in your Docker container.

**Dockerfile**

First, update your `Dockerfile` to include the `python-can` library:

```Dockerfile
Dockerfile FROM torizon/qt5-wayland:latest

# Install necessary packages
RUN apt-get update && apt-get install -y \
    python3-pip \
    can-utils \
    && apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*

# Install python-can library
RUN pip3 install python-can

# Copy application files
COPY . /app
WORKDIR /app

CMD ["python3", "main.py"]
```

**main.py**

Here's an example of the Qt application that receives CAN messages and displays them on the screen:

```python
python import sys
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
import can
import threading

class CANReceiver(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()
        self.initCAN()

    def initUI(self):
        self.setWindowTitle('CAN Message Receiver')
        self.layout = QVBoxLayout()
        self.label = QLabel('Waiting for CAN messages...')
        self.layout.addWidget(self.label)
        self.setLayout(self.layout)
        self.resize(400, 200)

    def initCAN(self):
        # Initialize CAN interface
        self.bus = can.interface.Bus(channel='can0', bustype='socketcan')

        # Start a thread to read CAN messages
        self.can_thread = threading.Thread(target=self.read_can_messages)
        self.can_thread.start()

    def read_can_messages(self):
        while True:
            message = self.bus.recv()
            if message:
                self.display_message(message)

    def display_message(self, message):
        msg = f'ID: {message.arbitration_id}, Data: {message.data}'
        self.label.setText(msg)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    receiver = CANReceiver()
    receiver.show()
    sys.exit(app.exec_())
```

#### Running the Application

1. **Build the Docker Container**

   Build your Docker container with the following command:

   ```bash
   docker build -t my-qt-can-app .
   ```
2. **Deploy the Application to ATDM**

   Deploy the Docker container to your ATDM:

   ```bash
   docker run -d --rm --name my-qt-can-app-container --network host --privileged my-qt-can-app
   ```

#### Summary

This example demonstrates how to create a simple Qt application that uses the CAN interface on TorizonOS to receive and display CAN messages. The application initializes the CAN interface, starts a separate thread to read CAN messages, and updates the UI to display the received messages. This provides a foundation for developing more complex CAN-based applications on your ATDM.

For more information on working with CAN in Python, you can refer to the [python-can documentation](https://python-can.readthedocs.io/en/master/).
