智慧农业中控面板
QuecPython 基于 U-235 开发板推出了一款智慧农业中控面板的 GUI 解决方案,包括天气预报、农业环境数据监测、实时数据显示、历史数据曲线、农业设备控制、报警和故障事件提醒、系统设置等功能。
U-235 开发板默认板载 EC600U 模组,并外接一个 MIPI 接口的、分辨率为 480*854 的 5 寸屏幕,同时板载丰富的传感器和外设接口,详情可查看 U-235 开发板说明文档。
智慧农业中控面板使用 LVGL 绘制图形化界面,它是一个轻量级的、开源的嵌入式图形库。QuecPython 集成了 LVGL,并且使用 NXP 公司的 GUI Guider 作为图形化界面设计工具,能自动生成 QuecPython 代码,极大提高了嵌入式平台图形化界面设计的效率。
界面介绍
智慧农业中控面板提供首页、环境数据显示、系统设置、设备控制和参数设置等多个界面。用于集中监控和管理农业活动。
首页
首页是农业管理的信息中心。其设计理念为直观易用,集成多种功能,以支持有效的农业管理。
组成部分:
天气信息:
- 当前天气状况:包括温度、天气状况(晴、雨、云等),风速和风向。
- 未来天气预报:提供未来几天或一周的天气预测,包括气温变化、降水概率等。
点击后,即可进入完整的天气界面
温度和湿度历史曲线:
- 实时更新的温度和湿度数据,以曲线图形式展现,方便观察短期和长期的变化趋势。
- 可能包括日、周、月甚至年的数据对比。
常见环境参数:
- 土壤湿度:显示不同区域土壤的湿度水平。
- 土壤PH值:监测土壤酸碱度。
- O2浓度:显示当前环境氧气浓度。
- CO2 浓度:对温室作物生长尤其关键。
告警信息:
- 系统实时监测并提醒任何异常情况,如温度或湿度突然偏离正常范围,未授权入侵,设备故障等。
- 告警历史记录,方便回溯和分析过去的事件。
环境数据显示页面
环境数据显示界面提供了农业中的各种环境参数的实时数据,能够让农业管理者快速获取并分析这些关键数据,从而作出及时的决策以优化农作物的生长条件。
该界面包括了对温度、湿度、光照度、土壤温度、氧气浓度、二氧化碳浓度、土壤ph值和土壤EC值的实时数据显示。
设备状态显示页面
设备状态显示界面用于监测和显示各个设备和传感器的运行状态, 以便于快速识别任何潜在问题,并采取相应措施,确保农业操作的顺畅和效率。通过这样的中控面板,农业管理者能够有效监控和维护农场的关键设备和传感器,提高整体的生产力和可靠性。
该界面包括了农业中常见的环境传感器状态。 包括温湿度、关照、土壤PH值、土壤EC、二氧化碳浓度、氧气浓度、风速风向和土壤的温湿度。
系统设置页面
系统设置界面是用户配置和个性化其农业管理系统的关键部分,允许用户调整各种系统参数以满足特定的需求和偏好 。 通过这些设置,用户可以确保系统的高效运行,同时符合其个人偏好和操作习惯。
该界面包括如下功能:
- 关于本机:
- 提供系统的基本信息,如制造商、型号、操作系统版本。
- 显示系统的硬件配置,如处理器类型、内存大小、存储空间等。
- 音量设置:
- 允许用户调整系统的音量,包括警报声、通知声等。
- 可以设定静音模式,特别是在需要减少干扰的环境中。
- 检查更新:
- 用于检查系统软件的更新,确保所有功能都是最新版本。
- 可能包括自动更新的选项,允许系统在有新版本时自动下载和安装。
- 低功耗模式:
- 这个选项可以减少系统的能源消耗,特别是在电源有限的环境中非常有用。
- 低功耗模式可能会限制某些功能或降低系统的性能。
- 息屏时间设置:
- 允许用户设定屏幕在无操作时自动关闭的时间,有助于节能。
- 用户可以根据需要设置不同的时间间隔。
- 模式选择:
- 用户可以选择不同的操作模式,例如日常模式、节能模式、夜间模式等。
- 每种模式可能会调整屏幕亮度、音量、能源使用等设置。
设备控制页面
设备控制界面是一个用于管理和操作农场各种设备的关键部分。其提供直观的控制选项和实时反馈,确保用户可以轻松而有效地管理农场的关键设备。通过这种智能化的设备控制,农场管理者可以优化生产条件,提高效率,同时减少资源浪费。
该界面包括了农业中常见的设备控制。 包括通风设备、灌溉设备、加湿设备、驱虫设备、升温设备和报警设备。
参数设置页面
参数设置界面允许用户自定义和调整各种环境和设备操作参数。这些设置帮助确保农业生产环境与作物的需求相匹配,从而优化生长条件和提高生产效率。
用户可以为各种环境参数设定阈值,如温度、湿度、光照度、土壤湿度、二氧化碳浓度等,当这些参数达到或超过设定阈值时,系统可以自动调整设备运行或发送警报。
通过这个界面,用户可以根据具体情况和需求精细调整农业操作的各个方面,确保系统的高效运行和作物的最佳生长条件。这种高度的可定制性是智慧农业系统的一个主要优势,它允许农业生产者根据变化的环境和市场需求灵活调整操作策略。
应用代码介绍
代码 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。
界面绘制
该部分将开始绘制主页中的各个模块。
左侧 Dock 栏
- 组件:imgbtn。
- 图标:使用易于识别的图标作为快捷方式,访问主页、显示数据、设置、控制等功能。
- 布局:图标垂直对齐,放置在界面左侧,便于使用。
- 交互性:为图标添加选中效果,提升交互体验。
在GUI Guider软件中,使用
imgbtn
组件来创建智慧农业图形化界面中的左侧快捷键栏时,您会需要关注几个关键设计要素:- 图标选择:
- 每个
imgbtn
应选择一个直观的图标,代表它的功能,如家庭形状的图标代表主页,齿轮形状代表设置。 - 图标设计应简洁明了,以便用户一眼就能识别其功能。
- 每个
- 大小和间距:
- 每个
imgbtn
的大小应足够大,用户可以轻松点击,特别是在触摸屏设备上。 - 快捷键之间应有适当间距,以防止误触,并使界面看起来更加整洁。
- 每个
- 图标状态:
- 设计不同状态的图标,如默认状态、悬浮状态、点击状态,这样可以提供视觉反馈,增强用户交互体验。
imgbtn
组件应支持状态切换,使得用户可以看到他们的交云动作导致了界面的响应。
- 功能性:
- 每个
imgbtn
都应配置正确的事件处理器,以确保当用户点击时能够触发正确的动作或导航到相应的界面。 - 如果
imgbtn
代表的功能当前已激活或位于当前页面,它应以不同的视觉样式显示,以指示其活动状态。
- 每个
顶端信息显示栏:
- 组件:label、image。
- 运营商信息:在界面顶部左侧显示移动运营商或网络状态。
- 时间显示:在界面顶部中间位置显示当前时间。
- 信号强度和电量指示:在界面顶部右侧显示Wi-Fi或网络信号强度以及当前电量的图标。
在使用 GUI Guider 软件设计智慧农业中控面板的顶端信息显示栏时,结合
label
和image
组件来创建一个信息丰富且视觉上易于识别的状态栏。以下是如何使用这些组件来设计顶端信息显示栏的详细步骤:- 运营商信息(Label 组件):
- 使用
label
组件来显示运营商信息。选择清晰易读的字体和大小,确保在不同的设备上都能轻松阅读。 - 将
label
组件放置在顶端信息栏的左侧,并设置合适的对齐方式,通常是左对齐。
- 使用
- 时间显示(Label 组件):
- 另一个
label
组件用于显示时间。您可以设置一个定时器,以确保时间始终是更新的。 - 时间
label
通常位于信息栏的右侧位置,并且要有足够的辨识度,可以通过增大字体和加粗来实现。
- 另一个
- 信号强度(Image 组件):
- 信号强度可以通过一系列预定义的信号图标来表示。这些图标可以根据信号强度的不同显示不同的图像。
- 使用
image
组件来放置信号强度图标,并将其放置在顶端信息栏的右侧
- 电量指示(Image 组件):
- 电量指示同样使用
image
组件来显示,您可以准备一组电量图标来反映不同的电量状态。 - 将电量图标放置在顶端信息栏最右侧,紧邻信号强度图标
- 电量指示同样使用
天气模块:
- 组件:label、container、image。
- 当前天气:展示当前天气状况和温度。
- 未来天气预报:在当前天气旁边或下方提供横向滚动或小网格,显示未来几天的天气预报。
在 GUI Guider 中设计左上侧的天气信息模块时,可以通过组合
label
、image
和container
组件来创建一个直观并且信息丰富的天气显示区域。以下是如何使用这些组件来设计天气信息模块的步骤:- 基础容器设置(Container 组件):
- 在界面左上角放置一个
container
组件,作为天气模块的基础。这个容器将包含所有天气相关的子组件。 - 调整
container
的大小,确保它可以容纳所有子组件而不显得拥挤。
- 在界面左上角放置一个
- 位置显示(Label 组件):
- 使用一个
label
组件在容器的顶部显示当前的地理位置或农场名。 - 这个
label
可以使用较大的字体和加粗效果,以便用户可以清晰地识别位置信息。
- 使用一个
- 当前温度和天气(Label 组件):
- 为当前温度和天气描述使用两个
label
组件。这些应该使用清晰、易读的字体,并且大小适当,以便一目了然。 - 当前温度的
label
应该是最显眼的,可能需要使用更大的字号和突出的颜色
- 为当前温度和天气描述使用两个
- 天气图标(Image 组件):
- 使用
image
组件来显示当前天气状况的图标,如晴天、阴天、雨天等。 - 天气图标应该与当前温度的
label
相邻,提供直观的天气视觉表示。
- 使用
- 天天气预报(Label 和 Image 组件):
- 在
container
的下方或旁边,使用多个label
和image
组件来显示未来5天的天气预报。 - 每天的预报可以使用一个小型
image
组件显示天气图标,旁边跟随个label
组件显示日期。
- 在
- 自适应设计:
- 设计时要确保天气信息区域能够适应不同的屏幕尺寸和分辨率,特别是在响应式界面上。
- 子组件应该能够在
container
大小变化时,自动调整其大小和位置。
温度湿度历史曲线图:
- 组件:container,chart ,label。
- 图表样式:使用线状图展示温度和湿度的历史数据趋势。
- 时间选择:提供查看不同时间段数据的选项,如日、周、月。
- 交互性:允许用户悬停或点击图表上的点来查看特定数据点。
在使用 GUI Guider 设计智慧农业图形化界面的左下侧温度历史曲线时,布局
label
、chart
和container
组件。这些组件将共同构成一个展示温度变化趋势的图表区域,以下是具体的设计说明:- 容器布局(Container 组件):
- 在界面的左下侧放置一个
container
组件,用来作为温度历史曲线的背景和框架。这个容器将包含图表和相关的标签。 - 设定
container
的宽度和高度,以适应曲线图的展示需求,同时与其他界面元素保持协调。
- 在界面的左下侧放置一个
- 曲线图表(Chart 组件):
- 在
container
内部添加一个chart
组件,用于绘制温度的历史数据曲线。 - 配置
chart
组件来展示时间序列的温度数据,如设置 x 轴为时间轴,y 轴为温度值,确保数据点清晰可见。 - 定义曲线样式,如曲线颜色、粗细,以及是否显示数据点的标记。
- 在
- 标题标签(Label 组件):
- 在曲线图的上方或容器的顶部,使用
label
组件来显示标题,例如“历史曲线”。 - 选择合适的字体大小和风格,以保证标题清晰且与整体设计风格一致。
- 在曲线图的上方或容器的顶部,使用
- 响应式设计:
- 对于响应式界面,确保
container
和其中的chart
和label
组件能够根据不同屏幕尺寸适当缩放。 - 在不同分辨率和设备上测试图表的显示效果,确保数据始终清晰可见。
- 对于响应式界面,确保
常见环境参数显示:
- 组件:container,label。
- 数据展示块:以独立的“块”或“卡片”形式展示关键参数,如土壤 pH 值、土壤温度、氧气和二氧化碳浓度等当前读数。
在 GUI Guider 软件中设计智慧农业图形化界面的右上侧环境参数显示时,可以使用
label
和container
组件来清晰地展示土壤 pH 值、氧气浓度、土壤湿度和二氧化碳浓度等关键信息。以下是详细的设计步骤:- 环境参数容器(Container 组件):
- 在界面的右上侧放置一个
container
组件,作为所有环境参数的包裹元素。这个容器将帮助组织并分隔不同的参数显示。 - 设置容器的宽度和高度,以适应内部
label
的排列,同时确保整体布局的美观和协调。
- 在界面的右上侧放置一个
- 参数标签(Label 组件):
- 对于每个环境参数,使用单独的
label
组件来显示参数名称和数值。例如,一个label
显示“土壤PH值:7.1”,另一个label
显示“氧气浓度:50%”等。 - 参数名称的
label
可以使用较小的字体,而数值的label
可以使用更大或加粗的字体,以突出显示数值信息。
- 对于每个环境参数,使用单独的
- 参数更新机制:
- 如果可能的话,设计一个数据更新机制,以定时刷新显示的环境参数数值。这可以通过绑定
label
组件到数据源,并设置定时器来更新数值。
- 如果可能的话,设计一个数据更新机制,以定时刷新显示的环境参数数值。这可以通过绑定
告警信息区:
- 组件:container,label,table。
- 列表视图:以列表或日志形式显示最近的告警和警告。
- 优先级指示:使用颜色编码或图标来指示告警的优先级或严重性。
- 交互性:允许用户点击告警以获取更多详情或确认并清除通知。
在使用 GUI Guider 软件设计智慧农业图形化界面的右下侧告警信息区时,可以利用
label
、container
和table
组件来有效地展示告警标题和具体的告警信息。这个区域将为用户提供关键的安全和系统状态更新,以下是详细的设计流程:- 告警信息容器(Container 组件):
- 在界面的右下侧放置一个
container
组件,用作告警信息区的主要框架。这个容器将包含告警信息的标题和具体内容。 - 设定容器的尺寸,确保足够的空间来展示告警信息,同时保持与界面其他元素的协调。
- 在界面的右下侧放置一个
- 告警信息标题(Label 组件):
- 使用一个
label
组件在容器的顶部显示标题,例如“告警信息”。 - 选择醒目且易于阅读的字体和大小,确保用户能够清楚地识别这一区域的功能。
- 使用一个
- 告警信息表格(Table 组件):
- 在
container
下方使用table
组件来列出具体的告警信息。这可以包括告警时间、类型、状态等列。 - 调整
table
的列宽和行高,确保所有信息都是清晰可见的。
- 在
- 告警信息样式:
- 为
table
组件设置合适的背景色、边框色和字体颜色,以便与整体界面风格保持一致。 - 考虑使用不同的颜色或图标来表示不同级别的告警,如红色表示紧急告警,黄色表示警告。
- 为
- 告警信息更新机制:
- 设计一个数据更新机制,允许
table
组件动态显示最新的告警信息。这可能需要将table
组件绑定到后端数据源,并设定定时刷新。
- 设计一个数据更新机制,允许
- 响应式设计:
- 确保
container
和其中的table
和label
组件在不同屏幕尺寸和分辨率上能够适当缩放。 - 在小屏幕上可能需要调整
table
的布局,以保证信息的可读性。
- 确保
在 GUI Guider 中放置这些元素时,要确保每个组件都根据网格或灵活布局系统放置,以适应不同的屏幕尺寸和分辨率。界面设计应简洁,保持足够的空白避免拥挤,使用的颜色方案应使得重要信息突出但又不刺眼,交互元素应提供即时反馈,例如悬浮或点击时改变外观。此外,应在不同设备上测试设计,以确保其可用性和性能。
如果系统将在各种光照条件下使用,比如直射阳光下,应能调整对比度和亮度以增强可见性。最后,界面设计应直观,使新用户无需广泛培训即可导航,反映出良好的用户体验(UX)设计原则。