智慧农业中控面板

QuecPython 基于 U-235 开发板推出了一款智慧农业中控面板的 GUI 解决方案,包括天气预报、农业环境数据监测、实时数据显示、历史数据曲线、农业设备控制、报警和故障事件提醒、系统设置等功能。

U-235 开发板默认板载 EC600U 模组,并外接一个 MIPI 接口的、分辨率为 480*854 的 5 寸屏幕,同时板载丰富的传感器和外设接口,详情可查看 U-235 开发板说明文档

智慧农业中控面板使用 LVGL 绘制图形化界面,它是一个轻量级的、开源的嵌入式图形库。QuecPython 集成了 LVGL,并且使用 NXP 公司的 GUI Guider 作为图形化界面设计工具,能自动生成 QuecPython 代码,极大提高了嵌入式平台图形化界面设计的效率。

界面介绍

智慧农业中控面板提供首页、环境数据显示、系统设置、设备控制和参数设置等多个界面。用于集中监控和管理农业活动。

首页

首页是农业管理的信息中心。其设计理念为直观易用,集成多种功能,以支持有效的农业管理。

Main_interface

组成部分:

  1. 天气信息

    • 当前天气状况:包括温度、天气状况(晴、雨、云等),风速和风向。
    • 未来天气预报:提供未来几天或一周的天气预测,包括气温变化、降水概率等。

    点击后,即可进入完整的天气界面

  2. 温度和湿度历史曲线

    • 实时更新的温度和湿度数据,以曲线图形式展现,方便观察短期和长期的变化趋势。
    • 可能包括日、周、月甚至年的数据对比。
  3. 常见环境参数

    • 土壤湿度:显示不同区域土壤的湿度水平。
    • 土壤PH值:监测土壤酸碱度。
    • O2浓度:显示当前环境氧气浓度。
    • CO2 浓度:对温室作物生长尤其关键。
  4. 告警信息

    • 系统实时监测并提醒任何异常情况,如温度或湿度突然偏离正常范围,未授权入侵,设备故障等。
    • 告警历史记录,方便回溯和分析过去的事件。

环境数据显示页面

环境数据显示界面提供了农业中的各种环境参数的实时数据,能够让农业管理者快速获取并分析这些关键数据,从而作出及时的决策以优化农作物的生长条件。

Detection_interface

该界面包括了对温度、湿度、光照度、土壤温度、氧气浓度、二氧化碳浓度、土壤ph值和土壤EC值的实时数据显示。

设备状态显示页面

设备状态显示界面用于监测和显示各个设备和传感器的运行状态, 以便于快速识别任何潜在问题,并采取相应措施,确保农业操作的顺畅和效率。通过这样的中控面板,农业管理者能够有效监控和维护农场的关键设备和传感器,提高整体的生产力和可靠性。

Device_Status_Interface

该界面包括了农业中常见的环境传感器状态。 包括温湿度、关照、土壤PH值、土壤EC、二氧化碳浓度、氧气浓度、风速风向和土壤的温湿度。

系统设置页面

系统设置界面是用户配置和个性化其农业管理系统的关键部分,允许用户调整各种系统参数以满足特定的需求和偏好 。 通过这些设置,用户可以确保系统的高效运行,同时符合其个人偏好和操作习惯。

Local_Settings_Interface

该界面包括如下功能:

  1. 关于本机
    • 提供系统的基本信息,如制造商、型号、操作系统版本。
    • 显示系统的硬件配置,如处理器类型、内存大小、存储空间等。
  2. 音量设置
    • 允许用户调整系统的音量,包括警报声、通知声等。
    • 可以设定静音模式,特别是在需要减少干扰的环境中。
  3. 检查更新
    • 用于检查系统软件的更新,确保所有功能都是最新版本。
    • 可能包括自动更新的选项,允许系统在有新版本时自动下载和安装。
  4. 低功耗模式
    • 这个选项可以减少系统的能源消耗,特别是在电源有限的环境中非常有用。
    • 低功耗模式可能会限制某些功能或降低系统的性能。
  5. 息屏时间设置
    • 允许用户设定屏幕在无操作时自动关闭的时间,有助于节能。
    • 用户可以根据需要设置不同的时间间隔。
  6. 模式选择
    • 用户可以选择不同的操作模式,例如日常模式、节能模式、夜间模式等。
    • 每种模式可能会调整屏幕亮度、音量、能源使用等设置。

设备控制页面

设备控制界面是一个用于管理和操作农场各种设备的关键部分。其提供直观的控制选项和实时反馈,确保用户可以轻松而有效地管理农场的关键设备。通过这种智能化的设备控制,农场管理者可以优化生产条件,提高效率,同时减少资源浪费。

Device_Control_Interfacd

该界面包括了农业中常见的设备控制。 包括通风设备、灌溉设备、加湿设备、驱虫设备、升温设备和报警设备。

参数设置页面

参数设置界面允许用户自定义和调整各种环境和设备操作参数。这些设置帮助确保农业生产环境与作物的需求相匹配,从而优化生长条件和提高生产效率。

Parameter_Setting_Interface

用户可以为各种环境参数设定阈值,如温度、湿度、光照度、土壤湿度、二氧化碳浓度等,当这些参数达到或超过设定阈值时,系统可以自动调整设备运行或发送警报。

通过这个界面,用户可以根据具体情况和需求精细调整农业操作的各个方面,确保系统的高效运行和作物的最佳生长条件。这种高度的可定制性是智慧农业系统的一个主要优势,它允许农业生产者根据变化的环境和市场需求灵活调整操作策略。

应用代码介绍

代码 github 仓库:https://github.com/QuecPython/solution-Agriculture-Control-Panel.git

代码目录结构

代码目录结构如下:

.
|-- Agri_ui.py
|-- EventMesh.py
|-- about_screen.py
|-- alarm_screen.py
|-- dev1_screen.py
|-- dev2_screen.py
|-- img
|   |-- mp-1092957702.png
|   |-- mp-1113916345.png
|   |-- mp-1120889833.png
|   |-- (Some pictures are omitted here)
|   |-- mp807599128.png
|   |-- mp910426373.png
|   `-- mp996516799.png
|-- main.py
|-- main_screen.py
|-- monitor_screen.py
|-- screen.py
|-- setting1_screen.py
|-- setting2_screen.py
|-- weather_screen.py
`-- welcome_screen.py

  • Agri_ui.py 用户执行智慧农业中控面板的所有初始化工作,包括 vlgl 初始化和 MIPI LCD 初始化;同时,提供了图形化界面的屏幕对象添加器和 GUI 启动器。屏幕对象添加器用于添加应用中所有可能需要显示的屏幕对象,GUI 启动器用于启动图形化界面功能。
  • screen.py 提供了屏幕对象的基类 class Screen() ,提供所有屏幕对象都需要的公共方法,如创建屏幕、状态栏信息显示(运营商名称、信号强度、系统时间、电池电量等)
  • 所有以 _screen.py 结尾的脚本文件,均实现了一个继承于 class Screen() 的类,是对应屏幕需要显示的画面的代码实现。界面代码的主体内容是由 GUI Guider 工具自动生成的,而后进行少许修改,主要是对象初始化方法 __init__() 和控件事件处理回调函数(__xxx_event_cb())的修改。
  • EventMesh.py 是一个事件管理器模块,当屏幕控件上的事件被触发时,用户仅需要调用相关接口发送事件即可,EventMesh 会自动进行屏幕内容切换。
  • img 文件夹提供了所有图像化界面需要依赖的图片资源。
  • main.py 是应用入口脚本文件,其调用 Agri_ui.py 提供的类 class AgriUi() 创建智慧农业中控面板的 GUI 对象,并调用该 GUI 对象的屏幕对象添加器添加需要的屏幕对象,而后调用 GUI 启动器启动图形化界面。

应用程序启动流程

应用程序的启动流程如下图所示:

软件设计

软件框架设计

应用程序设计

智慧农业中控面板软件的框图如下:

界面切换机制

EventMesh 事件管理框架

上文已经提及,界面切换采用 EventMesh 事件管理框架进行驱动。

  • EventMesh 是一个基于订阅和发布机制的应用框架,用户可以订阅任何感兴趣的主题,该主题即表示一个事件。
  • 在订阅主题的同时,还需要注册一个回调函数,用于处理产生的事件。
  • 用户可在任何产生事件的地方发布该事件,并可以携带消息内容。此时订阅者注册的回调函数会被调用,事件得到处理。

EventMesh 的设计框架如下图所示:

界面切换实现原理

在每一个带有控件触摸事件产生的屏幕界面脚本代码中,都会调用控件的 add_event_cb() 方法为对应的事件注册一个回调函数,当 lvgl 检测到事件发生时,会调用相应的回调函数。示例代码如下:

class MainScreen(Screen):
    def __init__(self):
    	# Some code is omitted here
        self.name = "MainScreen"
        super().create_style()

    # Some code is omitted here

    def create(self):

    	# Some code is omitted here

        self.weather_btn.add_event_cb(lambda e: self.__weather_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.alarm_btn.add_event_cb(lambda e: self.__alarm_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.monitor_btn.add_event_cb(lambda e: self.__monitor_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.monitor_btn_2.add_event_cb(lambda e: self.__monitor_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.dev_btn.add_event_cb(lambda e: self.__dev_btn_event_cb(e), lv.EVENT.PRESSED, None)
        self.setting_btn.add_event_cb(lambda e: self.__setting_btn_event_cb(e), lv.EVENT.PRESSED, None)

    def __weather_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("Click event occurs")
        EventMesh.publish("load_screen", "WeatherScreen")

    def __monitor_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("Click event occurs")
        EventMesh.publish("load_screen", "MonitorScreen")

    def __alarm_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("Click event occurs")
        EventMesh.publish("load_screen", "AlarmScreen")

    def __dev_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("Click event occurs")
        EventMesh.publish("load_screen", "Dev1Screen")

    def __setting_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("Click event occurs")
        EventMesh.publish("load_screen", "SettingScreen")

从上述代码可以看到,每一个触摸事件的回调函数的实现方式都是类似的。

以天气控件的触摸为例,代码如下:

    def __weather_btn_event_cb(self,e):
        src = e.get_target()
        code = e.get_code()
        print("Click event occurs")
        EventMesh.publish("load_screen", "WeatherScreen")

该段代码的核心语句是 EventMesh.publish("load_screen", "WeatherScreen") ,该语句发送一个名为 "load_screen" 的事件,意为加载新的屏幕界面;携带的消息为 "WeatherScreen",即屏幕界面的名称,表示加载的是天气显示界面。

GUI 启动

"load_screen" 事件在 Agri_ui.py 脚本文件的 class AgriUi(object) 类的 start() 方法中被订阅。

代码如下:

class AgriUi(object):

    # Some code is omitted here

    def __create(self):
        for screen in self.screens:
            screen.create()

    def start(self):
        self.__create()
        EventMesh.subscribe("load_screen", self.__route)
        EventMesh.publish("load_screen", "WelcomeScreen")
        utime.sleep(2)
        EventMesh.publish("load_screen", "MainScreen")

    def __route(self, topic, meta):
        for screen in self.screens:
            if screen.name == meta:
                lv.scr_load(screen.screen)

上述代码中的 start() 方法用于启动智慧农业中控面板的图形化界面,其工作流程如下:

  • 调用 __create() 方法创建每个屏幕界面的元数据。

  • 调用 EventMesh.subscribe() 方法订阅名为 "load_screen" 的事件,当该事件产生时,调用 __route() 方法处理该事件。

    __route() 方法根据发布事件时携带的消息,即屏幕界面的名称,去匹配相应的界面对象,调用 lvgl 的 lv.scr_load() 方法加载出新的界面。

    细心的读者会发现,每一个屏幕界面脚本文件中实现的类中,其对象初始化方法 __init__() 中,都会有类似 self.name = "MainScreen" 的语句。该语句便记录了屏幕界面的名称。

  • EventMesh.publish("load_screen", "WelcomeScreen") 语句用来触发第一个界面显示,即欢迎界面。而后等让欢迎界面的显示持续 2 秒钟,营造一种良好的视觉体验。

  • 欢迎界面结束后,通过EventMesh.publish("load_screen", "WelcomeScreen") 语句用来触发主界面的显示。

至此,智慧农业中控面板的图形化界面启动完毕,后续界面的切换由用户触摸控制。

图形化界面设计

上文提到,QuecPython 使用 NXP 公司的 GUI Guider 作为图形化界面设计工具,该工具不仅能够进行界面布局设计,还能自动生成 QuecPython 代码。[点此查看 GUI Guider 工具的使用教程](LVGL-UI工具 - QuecPython (quectel.com))。

下文以智慧农业中控面板的首页为例,来介绍图形化界面的设计过程。

布局和背景设置

创建一个智慧农业工程,选择一个适合的布局摸板和背景设计。 该阶段将从空白布局开始设计,即选择空白摸板,设置分辨率为 854*480。

Creat_Project

界面绘制

该部分将开始绘制主页中的各个模块。

  1. 左侧 Dock 栏

    Shortcut_Bar

    • 组件:imgbtn。
    • 图标:使用易于识别的图标作为快捷方式,访问主页、显示数据、设置、控制等功能。
    • 布局:图标垂直对齐,放置在界面左侧,便于使用。
    • 交互性:为图标添加选中效果,提升交互体验。

    在GUI Guider软件中,使用 imgbtn 组件来创建智慧农业图形化界面中的左侧快捷键栏时,您会需要关注几个关键设计要素:

    1. 图标选择
      • 每个 imgbtn 应选择一个直观的图标,代表它的功能,如家庭形状的图标代表主页,齿轮形状代表设置。
      • 图标设计应简洁明了,以便用户一眼就能识别其功能。
    2. 大小和间距
      • 每个 imgbtn 的大小应足够大,用户可以轻松点击,特别是在触摸屏设备上。
      • 快捷键之间应有适当间距,以防止误触,并使界面看起来更加整洁。
    3. 图标状态
      • 设计不同状态的图标,如默认状态、悬浮状态、点击状态,这样可以提供视觉反馈,增强用户交互体验。
      • imgbtn 组件应支持状态切换,使得用户可以看到他们的交云动作导致了界面的响应。
    4. 功能性
      • 每个 imgbtn 都应配置正确的事件处理器,以确保当用户点击时能够触发正确的动作或导航到相应的界面。
      • 如果 imgbtn 代表的功能当前已激活或位于当前页面,它应以不同的视觉样式显示,以指示其活动状态。
  2. 顶端信息显示栏

    Information_Display_Bar

    • 组件:label、image。
    • 运营商信息:在界面顶部左侧显示移动运营商或网络状态。
    • 时间显示:在界面顶部中间位置显示当前时间。
    • 信号强度和电量指示:在界面顶部右侧显示Wi-Fi或网络信号强度以及当前电量的图标。

    在使用 GUI Guider 软件设计智慧农业中控面板的顶端信息显示栏时,结合 labelimage 组件来创建一个信息丰富且视觉上易于识别的状态栏。以下是如何使用这些组件来设计顶端信息显示栏的详细步骤:

    1. 运营商信息(Label 组件)
      • 使用 label 组件来显示运营商信息。选择清晰易读的字体和大小,确保在不同的设备上都能轻松阅读。
      • label 组件放置在顶端信息栏的左侧,并设置合适的对齐方式,通常是左对齐。
    2. 时间显示(Label 组件)
      • 另一个 label 组件用于显示时间。您可以设置一个定时器,以确保时间始终是更新的。
      • 时间 label 通常位于信息栏的右侧位置,并且要有足够的辨识度,可以通过增大字体和加粗来实现。
    3. 信号强度(Image 组件)
      • 信号强度可以通过一系列预定义的信号图标来表示。这些图标可以根据信号强度的不同显示不同的图像。
      • 使用 image 组件来放置信号强度图标,并将其放置在顶端信息栏的右侧
    4. 电量指示(Image 组件)
      • 电量指示同样使用 image 组件来显示,您可以准备一组电量图标来反映不同的电量状态。
      • 将电量图标放置在顶端信息栏最右侧,紧邻信号强度图标
  3. 天气模块

    Weather_Column

    • 组件:label、container、image。
    • 当前天气:展示当前天气状况和温度。
    • 未来天气预报:在当前天气旁边或下方提供横向滚动或小网格,显示未来几天的天气预报。

    在 GUI Guider 中设计左上侧的天气信息模块时,可以通过组合 labelimagecontainer 组件来创建一个直观并且信息丰富的天气显示区域。以下是如何使用这些组件来设计天气信息模块的步骤:

    1. 基础容器设置(Container 组件)
      • 在界面左上角放置一个 container 组件,作为天气模块的基础。这个容器将包含所有天气相关的子组件。
      • 调整 container 的大小,确保它可以容纳所有子组件而不显得拥挤。
    2. 位置显示(Label 组件)
      • 使用一个 label 组件在容器的顶部显示当前的地理位置或农场名。
      • 这个 label 可以使用较大的字体和加粗效果,以便用户可以清晰地识别位置信息。
    3. 当前温度和天气(Label 组件)
      • 为当前温度和天气描述使用两个 label 组件。这些应该使用清晰、易读的字体,并且大小适当,以便一目了然。
      • 当前温度的 label 应该是最显眼的,可能需要使用更大的字号和突出的颜色
    4. 天气图标(Image 组件)
      • 使用 image 组件来显示当前天气状况的图标,如晴天、阴天、雨天等。
      • 天气图标应该与当前温度的 label 相邻,提供直观的天气视觉表示。
    5. 天天气预报(Label 和 Image 组件)
      • container 的下方或旁边,使用多个 labelimage 组件来显示未来5天的天气预报。
      • 每天的预报可以使用一个小型 image 组件显示天气图标,旁边跟随个 label 组件显示日期。
    6. 自适应设计
      • 设计时要确保天气信息区域能够适应不同的屏幕尺寸和分辨率,特别是在响应式界面上。
      • 子组件应该能够在 container 大小变化时,自动调整其大小和位置。
  4. 温度湿度历史曲线图

    History_Curve_Bar

    • 组件:container,chart ,label。
    • 图表样式:使用线状图展示温度和湿度的历史数据趋势。
    • 时间选择:提供查看不同时间段数据的选项,如日、周、月。
    • 交互性:允许用户悬停或点击图表上的点来查看特定数据点。

    在使用 GUI Guider 设计智慧农业图形化界面的左下侧温度历史曲线时,布局 labelchartcontainer 组件。这些组件将共同构成一个展示温度变化趋势的图表区域,以下是具体的设计说明:

    1. 容器布局(Container 组件)
      • 在界面的左下侧放置一个 container 组件,用来作为温度历史曲线的背景和框架。这个容器将包含图表和相关的标签。
      • 设定 container 的宽度和高度,以适应曲线图的展示需求,同时与其他界面元素保持协调。
    2. 曲线图表(Chart 组件)
      • container 内部添加一个 chart 组件,用于绘制温度的历史数据曲线。
      • 配置 chart 组件来展示时间序列的温度数据,如设置 x 轴为时间轴,y 轴为温度值,确保数据点清晰可见。
      • 定义曲线样式,如曲线颜色、粗细,以及是否显示数据点的标记。
    3. 标题标签(Label 组件)
      • 在曲线图的上方或容器的顶部,使用 label 组件来显示标题,例如“历史曲线”。
      • 选择合适的字体大小和风格,以保证标题清晰且与整体设计风格一致。
    4. 响应式设计
      • 对于响应式界面,确保 container 和其中的 chartlabel 组件能够根据不同屏幕尺寸适当缩放。
      • 在不同分辨率和设备上测试图表的显示效果,确保数据始终清晰可见。
  5. 常见环境参数显示

    Parameter_Display_Bar

    • 组件:container,label。
    • 数据展示块:以独立的“块”或“卡片”形式展示关键参数,如土壤 pH 值、土壤温度、氧气和二氧化碳浓度等当前读数。

    在 GUI Guider 软件中设计智慧农业图形化界面的右上侧环境参数显示时,可以使用 labelcontainer 组件来清晰地展示土壤 pH 值、氧气浓度、土壤湿度和二氧化碳浓度等关键信息。以下是详细的设计步骤:

    1. 环境参数容器(Container 组件)
      • 在界面的右上侧放置一个 container 组件,作为所有环境参数的包裹元素。这个容器将帮助组织并分隔不同的参数显示。
      • 设置容器的宽度和高度,以适应内部 label 的排列,同时确保整体布局的美观和协调。
    2. 参数标签(Label 组件)
      • 对于每个环境参数,使用单独的 label 组件来显示参数名称和数值。例如,一个 label 显示“土壤PH值:7.1”,另一个 label 显示“氧气浓度:50%”等。
      • 参数名称的 label 可以使用较小的字体,而数值的 label 可以使用更大或加粗的字体,以突出显示数值信息。
    3. 参数更新机制
      • 如果可能的话,设计一个数据更新机制,以定时刷新显示的环境参数数值。这可以通过绑定 label 组件到数据源,并设置定时器来更新数值。
  6. 告警信息区

    Alarm_Information_Bar

    • 组件:container,label,table。
    • 列表视图:以列表或日志形式显示最近的告警和警告。
    • 优先级指示:使用颜色编码或图标来指示告警的优先级或严重性。
    • 交互性:允许用户点击告警以获取更多详情或确认并清除通知。

    在使用 GUI Guider 软件设计智慧农业图形化界面的右下侧告警信息区时,可以利用 labelcontainertable 组件来有效地展示告警标题和具体的告警信息。这个区域将为用户提供关键的安全和系统状态更新,以下是详细的设计流程:

    1. 告警信息容器(Container 组件)
      • 在界面的右下侧放置一个 container 组件,用作告警信息区的主要框架。这个容器将包含告警信息的标题和具体内容。
      • 设定容器的尺寸,确保足够的空间来展示告警信息,同时保持与界面其他元素的协调。
    2. 告警信息标题(Label 组件)
      • 使用一个 label 组件在容器的顶部显示标题,例如“告警信息”。
      • 选择醒目且易于阅读的字体和大小,确保用户能够清楚地识别这一区域的功能。
    3. 告警信息表格(Table 组件)
      • container 下方使用 table 组件来列出具体的告警信息。这可以包括告警时间、类型、状态等列。
      • 调整 table 的列宽和行高,确保所有信息都是清晰可见的。
    4. 告警信息样式
      • table 组件设置合适的背景色、边框色和字体颜色,以便与整体界面风格保持一致。
      • 考虑使用不同的颜色或图标来表示不同级别的告警,如红色表示紧急告警,黄色表示警告。
    5. 告警信息更新机制
      • 设计一个数据更新机制,允许 table 组件动态显示最新的告警信息。这可能需要将 table 组件绑定到后端数据源,并设定定时刷新。
    6. 响应式设计
      • 确保 container 和其中的 tablelabel 组件在不同屏幕尺寸和分辨率上能够适当缩放。
      • 在小屏幕上可能需要调整 table 的布局,以保证信息的可读性。

在 GUI Guider 中放置这些元素时,要确保每个组件都根据网格或灵活布局系统放置,以适应不同的屏幕尺寸和分辨率。界面设计应简洁,保持足够的空白避免拥挤,使用的颜色方案应使得重要信息突出但又不刺眼,交互元素应提供即时反馈,例如悬浮或点击时改变外观。此外,应在不同设备上测试设计,以确保其可用性和性能。

如果系统将在各种光照条件下使用,比如直射阳光下,应能调整对比度和亮度以增强可见性。最后,界面设计应直观,使新用户无需广泛培训即可导航,反映出良好的用户体验(UX)设计原则。