{"id":11618,"date":"2025-01-30T10:00:00","date_gmt":"2025-01-30T09:00:00","guid":{"rendered":"https:\/\/www.basyskom.de\/?p=11618"},"modified":"2025-02-06T08:05:55","modified_gmt":"2025-02-06T07:05:55","slug":"flutter-on-embedded-hmi-mobile-apps-and-middleware","status":"publish","type":"post","link":"https:\/\/www.basyskom.de\/en\/flutter-on-embedded-hmi-mobile-apps-and-middleware\/","title":{"rendered":"Flutter on Embedded: HMI, Mobile Apps and Middleware"},"content":{"rendered":"<div data-elementor-type=\"wp-post\" data-elementor-id=\"11618\" class=\"elementor elementor-11618\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-857e85f e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-equal-height-no e-con e-parent\" data-id=\"857e85f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-45044b0 elementor-widget elementor-widget-text-editor\" data-id=\"45044b0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In<a href=\"https:\/\/www.basyskom.de\/en\/state-of-flutter-on-embedded-linux\/\" target=\"_blank\" rel=\"noopener\"> part 1<\/a> of this series we showed the benefits of Flutter on embedded, in <a href=\"https:\/\/www.basyskom.de\/en\/how-does-flutter-work-on-embedded\/\" target=\"_blank\" rel=\"noopener\">part 2<\/a> we discussed the general technical requirement to run Flutter code on embedded devices.<\/p><p>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.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b1ab470 elementor-widget elementor-widget-text-editor\" data-id=\"b1ab470\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tLet us assume we are building an HMI for an embedded device. Our goal is to enable users to monitor and control the device&#8217;s state, not only locally on a display but also from mobile devices. In other words: Use Flutter&#8217;s cross-platform capabilities by creating an app that runs both directly on the embedded device and as a mobile application. \t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a611cf5 elementor-widget elementor-widget-image\" data-id=\"a611cf5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t<figure class=\"wp-caption\">\n\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1983\" height=\"787\" src=\"https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision.jpg\" class=\"attachment-2048x2048 size-2048x2048 wp-image-11620\" alt=\"Flutter use case\" srcset=\"https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision.jpg 1983w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision-300x119.jpg 300w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision-1024x406.jpg 1024w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision-768x305.jpg 768w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision-1536x610.jpg 1536w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision-18x7.jpg 18w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_vision-560x222.jpg 560w\" sizes=\"(max-width: 1983px) 100vw, 1983px\" \/>\t\t\t\t\t\t\t\t\t\t\t<figcaption class=\"widget-image-caption wp-caption-text\">Figure 1 shows what we want to achieve. <\/figcaption>\n\t\t\t\t\t\t\t\t\t\t<\/figure>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-edbfa20 elementor-widget elementor-widget-heading\" data-id=\"edbfa20\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">System Architecture<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-d81ef83 e-grid e-con-full wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-equal-height-no e-con e-child\" data-id=\"d81ef83\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-edec034 elementor-widget elementor-widget-image\" data-id=\"edec034\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t<figure class=\"wp-caption\">\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"2048\" height=\"1292\" src=\"https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-2048x1292.jpg\" class=\"attachment-2048x2048 size-2048x2048 wp-image-11621\" alt=\"basysKom, HMI Dienstleistung, Qt, Cloud, Azure\" srcset=\"https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-2048x1292.jpg 2048w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-300x189.jpg 300w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-1024x646.jpg 1024w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-768x484.jpg 768w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-1536x969.jpg 1536w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-18x12.jpg 18w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_mono-560x353.jpg 560w\" sizes=\"(max-width: 2048px) 100vw, 2048px\">\t\t\t\t\t\t\t\t\t\t\t<figcaption class=\"widget-image-caption wp-caption-text\">Figure 2<\/figcaption>\n\t\t\t\t\t\t\t\t\t\t<\/figure>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-511c135 elementor-widget elementor-widget-text-editor\" data-id=\"511c135\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>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.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ec4a32a elementor-widget elementor-widget-heading\" data-id=\"ec4a32a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">How to Build our Target Use Case and Ensure Reusable HMI Code?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0a3c8d2 elementor-widget elementor-widget-text-editor\" data-id=\"0a3c8d2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tIn 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:\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-edc7a7f elementor-widget elementor-widget-text-editor\" data-id=\"edc7a7f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ul><li>HMI code reusability: Avoid strong coupling to your embedded device! This means minimizing dependencies on platform-specific APIs, middleware, or hardware features.<\/li><li>Data consistency: Ensure consistent data across all devices.<\/li><li>Middleware: Ensure you can access your device business logic and middleware from external (mobile) systems and the embedded system.<\/li><li>Communication protocols: Implement reliable communication between mobile app and embedded device, ideally supporting concepts of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Schema_evolution\" target=\"_blank\" rel=\"nofollow noopener\">schema evolution<\/a>.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f376275 elementor-widget elementor-widget-text-editor\" data-id=\"f376275\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>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&#8217;s say mobile, neither the middleware nor the sensor is available &#8211; meaning we would have to reimplement the source of the data &#8211; and this is explicitly what we do <span style=\"text-decoration: underline;\"><strong>not<\/strong><\/span> want.<\/p><p>Lets note this requirement : &#8220;\u2705<strong>No direct access to local resources<\/strong>&#8220;.<\/p><p>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.<\/p><p>Lets note this requirement: &#8220;\u2705 <strong>Embedded Device is single point of truth and serves data and configuration<\/strong>&#8220;<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9d666ea elementor-widget elementor-widget-heading\" data-id=\"9d666ea\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Proposed System Architecture<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-18bb942 elementor-widget elementor-widget-image\" data-id=\"18bb942\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t<figure class=\"wp-caption\">\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"2048\" height=\"778\" src=\"https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-2048x778.jpg\" class=\"attachment-2048x2048 size-2048x2048 wp-image-11622\" alt=\"basysKom, HMI Dienstleistung, Qt, Cloud, Azure\" srcset=\"https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-2048x778.jpg 2048w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-300x114.jpg 300w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-1024x389.jpg 1024w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-768x292.jpg 768w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-1536x584.jpg 1536w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-18x7.jpg 18w, https:\/\/www.basyskom.de\/wp-content\/uploads\/2025\/01\/flutter_architecture_sc-560x213.jpg 560w\" sizes=\"(max-width: 2048px) 100vw, 2048px\">\t\t\t\t\t\t\t\t\t\t\t<figcaption class=\"widget-image-caption wp-caption-text\">Figure 3<\/figcaption>\n\t\t\t\t\t\t\t\t\t\t<\/figure>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-90647ce elementor-widget elementor-widget-text-editor\" data-id=\"90647ce\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>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.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-86fdabd elementor-widget elementor-widget-heading\" data-id=\"86fdabd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Integration of Middleware<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-714a202 elementor-widget elementor-widget-text-editor\" data-id=\"714a202\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tThe 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.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f653e5b elementor-widget elementor-widget-heading\" data-id=\"f653e5b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Protocols<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c25cdaa elementor-widget elementor-widget-text-editor\" data-id=\"c25cdaa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>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, <span class=\"inline-comment-marker\" data-ref=\"aaa44372-1e29-480e-8a5c-59d6cb494d7f\">Unix Sockets (local)<\/span> 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 <span class=\"inline-comment-marker\" data-ref=\"360b13c5-5313-4959-a616-fbd5cde646e1\">proprietary<\/span> <span class=\"inline-comment-marker\" data-ref=\"4b6bc32e-600f-4cb3-9dee-3e3394019c22\">protocols<\/span>.\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-544754b elementor-widget elementor-widget-heading\" data-id=\"544754b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Comparison of Communication Protocols you may consider:<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-789996c wpr-data-table-type-custom wpr-table-align-items-left elementor-widget elementor-widget-wpr-data-table\" data-id=\"789996c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"wpr-data-table.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\n\t\t\t\t\n\t\t<div class=\"wpr-table-container\">\n\t\t<div class=\"wpr-table-inner-container\" data-table-sorting=\"no\" data-custom-pagination=\"no\" data-row-pagination=\"\" data-entry-info=\"no\" data-rows-per-page=\"\">\n\n\t\t\n\t\t\t<table class=\"wpr-data-table\" id=\"wpr-data-table\">\n\t\t\t\t\t\t\t\t\n\t\t\t\t<thead>\n\t\t\t\t\t<tr class=\"wpr-table-head-row wpr-table-row\">\n\t\t\t\t\t\n\t\t\t\t\t\t<th class=\"wpr-table-th elementor-repeater-item-8fde228\" colspan=\"1\">\n\t\t\t\t\t\t\t<div class=\"\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">PROTOCOL<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/th>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<th class=\"wpr-table-th elementor-repeater-item-8220505\" colspan=\"1\">\n\t\t\t\t\t\t\t<div class=\"\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">ADVANTAGES<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/th>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<th class=\"wpr-table-th elementor-repeater-item-b31d6a9\" colspan=\"1\">\n\t\t\t\t\t\t\t<div class=\"\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">DISADVANTAGES<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/th>\n\t\t\t\t\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t<\/thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t<tr class=\"wpr-table-body-row wpr-table-row elementor-repeater-item-07c1b0a wpr-odd\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-73928d9 wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tgRPC\/Protobuf\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-83f698e wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tEfficient, supports bi-directional streaming, language-agnostic.\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-3de23dc wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tRequires both server and client setup, higher learning curve. Protobuf as a data format (not grpc) can also be sent over Bluetooth LE.\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t<\/tr>\n\t\t\t        \t\t\t\t\t<tr class=\"wpr-table-body-row wpr-table-row elementor-repeater-item-12ed849 wpr-odd\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-f5493fd wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tRESTful API\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-713a0a6 wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tEasy to implement, widely supported, good for request-response.\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-6a63884 wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tStateless, less suited for real-time updates or streaming.\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t<\/tr>\n\t\t\t        \t\t\t\t\t<tr class=\"wpr-table-body-row wpr-table-row elementor-repeater-item-ae25e45 wpr-odd\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-768c6ba wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tWebSockets\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-b070425 wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tFull-duplex communication, good for real-time data.\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<td colspan=\"\" rowspan=\"\" class=\"elementor-repeater-item-07ee365 wpr-table-td\">\n\n\t\t\t\t\t\t\t\t<div class=\"wpr-td-content-wrapper\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t \n\t\t\t\t\t\t\t\t\t\t\t<span class=\"wpr-table-text\">\n\t\t\t\t\t\t\t\t\t\t\t\tRequires more resources, increased complexity.\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t\t\t\t\t<\/tr>\n\t\t\t        \t\t\t\t<\/tbody>\n\t\t\t<\/table>\n\t\t<\/div>\n\t\t<\/div>\n    \t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-00fa379 elementor-widget elementor-widget-text-editor\" data-id=\"00fa379\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tWhile 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. \t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6aba7a2 elementor-widget elementor-widget-text-editor\" data-id=\"6aba7a2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tJust 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. \t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a8913ca elementor-widget elementor-widget-text-editor\" data-id=\"a8913ca\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tThe 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.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1339d8c elementor-widget elementor-widget-heading\" data-id=\"1339d8c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Challenges and Limitations of Flutter on Embedded<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-11e818b elementor-widget elementor-widget-text-editor\" data-id=\"11e818b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>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.<\/p><ul><li><strong>Hardware acceleration and GPU support<\/strong>: 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.<\/li><li><strong>Integration of embedded hardware<\/strong>: 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.<\/li><li><strong>Dependency on specific Embedders<\/strong>: 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.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6a87cca elementor-widget elementor-widget-heading\" data-id=\"6a87cca\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Conclusion<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4825551 elementor-widget elementor-widget-text-editor\" data-id=\"4825551\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tComing to an end of this article, let&#8217;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. \t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fc84940 elementor-widget elementor-widget-text-editor\" data-id=\"fc84940\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tWe 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.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fae7898 elementor-widget elementor-widget-text-editor\" data-id=\"fae7898\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tOverall, 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&#8217;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.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-15ed5c0 elementor-widget elementor-widget-text-editor\" data-id=\"15ed5c0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tWe 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.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>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.<\/p>","protected":false},"author":1,"featured_media":4020,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1,2,803,802],"tags":[223],"class_list":["post-11618","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-allgemein","category-blog","category-flutter","category-newsletter-2025-01","tag-flutter"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts\/11618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/comments?post=11618"}],"version-history":[{"count":19,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts\/11618\/revisions"}],"predecessor-version":[{"id":11640,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts\/11618\/revisions\/11640"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/media\/4020"}],"wp:attachment":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/media?parent=11618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/categories?post=11618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/tags?post=11618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}