basysKom Application Development Services

Flutter on Embedded: HMI, Mobile Apps and Middleware
Essential Summary
In this blog we show you a possible architecture approach to increase cross platform reusability of your Flutter HMI Code. From Embedded to Mobile to Desktop.

In part 1 of this series we showed the benefits of Flutter on embedded, in part 2 we discussed the general technical requirement to run Flutter code on embedded devices.

Now in part 3 we will outline a system architecture to implement a cross-platform Flutter application. Our main objective is to achieve close to 100% reusability of our Flutter source code across mobile, desktop, and embedded platforms, meaning that the vast majority of application logic, UI components, and data-handling code can be shared without modification, with only minimal platform-specific adjustments where necessary.

Let us assume we are building an HMI for an embedded device. Our goal is to enable users to monitor and control the device’s state, not only locally on a display but also from mobile devices. In other words: Use Flutter’s cross-platform capabilities by creating an app that runs both directly on the embedded device and as a mobile application.
Flutter use case
Figure 1 shows what we want to achieve.

System Architecture

Flutter on Embedded: HMI, Mobile Apps and Middleware 1 basysKom, HMI Dienstleistung, Qt, Cloud, Azure
Figure 2

Figure 2 shows a classic HMI system architecture approach on an embedded device; you easily end up with a strong coupling between your HMI code and the existing filesystem and middleware. These strong coupling can complicate the reuse of your code on mobile.

How to Build our Target Use Case and Ensure Reusable HMI Code?

In general, when you want to build a companion app and want to ensure the reusability of HMI code between embedded devices and mobile platforms, you will have to address several topics:
  • HMI code reusability: Avoid strong coupling to your embedded device! This means minimizing dependencies on platform-specific APIs, middleware, or hardware features.
  • Data consistency: Ensure consistent data across all devices.
  • Middleware: Ensure you can access your device business logic and middleware from external (mobile) systems and the embedded system.
  • Communication protocols: Implement reliable communication between mobile app and embedded device, ideally supporting concepts of schema evolution.

First, we want to avoid strong coupling, but what is strong coupling, how does it manifest? A strong coupling, you may also call it dependency, occurs when the HMI code, in our case Flutter, does access APIs or features that are only available on a specific (embedded) platform. In the embedded case, as shown in Figure 2, these are APIs provided through middleware or direct filesystem access. This could be, for example, reading a sensor value from our hardware. On cross-plattform, let’s say mobile, neither the middleware nor the sensor is available – meaning we would have to reimplement the source of the data – and this is explicitly what we do not want.

Lets note this requirement : “✅No direct access to local resources“.

Second, data consistency and middleware. Assume our cross-platform application runs on a mobile phone and on the embedded device. Also assume the app on the mobile phone is connected to the embedded device. I think we can all agree on the expectation that the data displayed on all screens is consistent and up-to-date. We expect to see the same values, the same configuration on all screens (while we may allow unsaved local states). In this assumption we define the embedded device as single point of truth. The embedded device delivers data and holds the active configuration. Furthermore the embedded device serves this information to the mobile applications.

Lets note this requirement: “✅ Embedded Device is single point of truth and serves data and configuration

Proposed System Architecture

Flutter on Embedded: HMI, Mobile Apps and Middleware 2 basysKom, HMI Dienstleistung, Qt, Cloud, Azure
Figure 3

Concluding from our two requirements we have drawn Figure 3. It shows an approach to achieve the requirements. The proposed architecture follows a typical client-server model. The server, running on the embedded hardware, manages the system state and provides access for clients. Clients comprise both the local HMI and remote HMI. The server handles all application logic, while the clients focus on displaying information and handling user interactions in the simplest way possible.

Integration of Middleware

The server acts as the link between your middleware and client HMIs. Importantly, this server can be written in any language that suits your needs best. Such as C++, Python, or Rust. The key is access to your hardware interface and middleware. Secondly it needs to provide a reliable communication interface to your client HMIs or client apps.

Protocols

The communication with the HMIs and apps (including the local HMI on your embedded device) should be done using protocols that work over Bluetooth LE, TCP, Unix Sockets (local) or any other communication method that fit your use case. Common examples include gRPC, RESTful APIs or protocols on top of WebSockets as well as proprietary protocols. 

Comparison of Communication Protocols you may consider:

PROTOCOL
ADVANTAGES
DISADVANTAGES
gRPC/Protobuf
Efficient, supports bi-directional streaming, language-agnostic.
Requires both server and client setup, higher learning curve. Protobuf as a data format (not grpc) can also be sent over Bluetooth LE.
RESTful API
Easy to implement, widely supported, good for request-response.
Stateless, less suited for real-time updates or streaming.
WebSockets
Full-duplex communication, good for real-time data.
Requires more resources, increased complexity.
While no single protocol fits all use cases, supporting TCP/Network is rather simple. If you want to implement Bluetooth LE you have to thoughtfully handle data formats.
Just as an example, if you are plan utilizing gRPC and Protobuf for TCP communication and need to support Bluetooth LE, keeping Protobuf as a datacontainer and send it over Bluetooth LE is possible. This can ensure consistency and simplify integration on the app side. Before you wonder if you really want this, keep in mind we are discussing an approach to share as much code as possible between a local HMI and mobile applications, and this may include the HMI layer that receives and handles incoming and outgoing data. You probably want to avoid specific implementations for BTLE and local HMI.
The outlined architectural approach serves as a starting point, with the specifics shaped by your system, your middleware, and your use cases. The architecture promotes independence of your HMI code, ensures high reusability, and facilitates the development for a wide variety of devices.

Challenges and Limitations of Flutter on Embedded

Now that we have outlined an approach of how a Flutter app can be implemented for embedded, you need to be aware of the limitations and be prepared to address the unique issues that arise in embedded environments.

  • Hardware acceleration and GPU support: Currently, Flutter heavily relies on GPU support to provide a smooth and responsive UI. There is no simple software rendering option available for Flutter on embedded platforms, meaning that your embedded device must have a GPU. This requirement limits the types of hardware that can effectively run Flutter and may increase hardware costs.
  • Integration of embedded hardware: The server-client architecture that we propose in this blog allows for easy integration of embedded hardware, much like you would without using Flutter. Of course accessing low-level hardware features (like GPIOs, I2C, or SPI) could be done in Flutter, but as it was not initially designed for such use cases, we strongly suggest using a server-client approach even in cases where no external HMIs or apps are required.
  • Dependency on specific Embedders: The availability of features and performance largely depends on the integration of the chosen Embedder. Different Embedders, like Flutter-Pi, Sony Embedder, or Toyota IVI Homescreen, offer different levels of functionality. Choosing the best Embedder, particularly for 64-bit systems (since on 32-bit there is only Flutter-Pi) is a crucial but also complicated decision. Each Embedder has specific strengths and limitations, which impact the suitability for certain projects.

Conclusion

Coming to an end of this article, let’s do a recap of what we have covered. We explored the use of Flutter for embedded systems, highlighting the advantages of using Flutter for HMIs across multiple platforms.
We presented an approach demonstrating how Flutter can be leveraged to build both embedded and mobile applications. This allows developers to use a single codebase across various environments, streamlining development and improving code reuse. This flexibility is especially beneficial when integrating embedded systems with mobile apps. But we also highlighted the challenges. Particularly when integrating Flutter with embedded hardware and existing middleware. We addressed those challenges by showing a possible system architecture approach.
Overall, we think that Flutter is a promising solution for HMI on embedded devices, particularly when mobile applications are required. Its open-source, permissive licensing and the large and still growing community makes it a compelling option to consider for future embedded projects. Flutter’s growth in the embedded space shows its significant potential, bridging the gap between mobile, desktop, and embedded environments. While there are still challenges, particularly in terms of hardware integration, the benefits of a unified codebase and strong capabilities on mobile platforms make it an option worth exploring. For cost aware projects that need high-quality user interfaces and a versatile, cross-platform approach, Flutter stands out as a practical choice.
We can only encourage you to evaluate Flutter for your next embedded project and would love to support you in this journey. We are happy to share our experiences with you and would like to find the best fit technology for your use case.
Picture of Jeremias Bosch

Jeremias Bosch

Jeremias Bosch consults in his position as Technical Project Manager our customers in building embedded HMI applications, as well as the implementation of next generation cloud projects. He is responsible for the system/software-architecture and the development within customer projects as well as the agile project management. He has over 12 years of experience in developing HMIs and Web Applications. He has delivered multiple large and medium scale Qt Quick and cloud applications in industries such as automotive, aerospace and manufacturing engineering. He holds a diploma of computer science from the University of Applied Sciences in Isny. Is a certifed SCRUM Master and Product Owner as well as a certifed Qt Developer.

Leave a Reply

Your email address will not be published. Required fields are marked *

More Blogarticles

basysKom Newsletter

We collect only the data you enter in this form (no IP address or information that can be derived from it). The collected data is only used in order to send you our regular newsletters, from which you can unsubscribe at any point using the link at the bottom of each newsletter. We will retain this information until you ask us to delete it permanently. For more information about our privacy policy, read Privacy Policy