基于物联网设计的智慧菜地种植系统

举报
DS小龙哥 发表于 2024/12/25 11:27:36 2024/12/25
【摘要】 本项目的开发背景来源于传统菜地管理中存在的灌溉不均、土壤质量监测不足、环境条件变化不可预测等问题。传统的菜地管理方式往往依赖人工巡查,效率低下且容易受到人为因素的影响,无法实现对土壤、环境、作物生长状态的精准监控和调控。而智能化的菜地种植系统通过集成多种传感器,实现对土壤水分、温度、氮磷钾含量、环境温湿度、光照强度等数据的实时采集,能够为种植者提供及时、精准的决策支持,进而优化水资源的使用,促进作

一、前言

1.1 项目开发背景

随着全球人口的增加和城市化进程的加快,传统农业面临着一系列挑战,如土地资源的匮乏、环境污染、气候变化等问题。为了应对这些挑战,智能农业作为一种新兴的技术趋势,逐渐成为现代农业发展的重要方向。智慧菜地种植系统作为智能农业的应用之一,利用物联网技术、传感器技术、自动化控制技术和云计算技术,可以实现农业生产的精准管理和自动化控制,显著提高作物的生长效率和资源利用率,同时降低人力成本和管理难度。

本项目的开发背景来源于传统菜地管理中存在的灌溉不均、土壤质量监测不足、环境条件变化不可预测等问题。传统的菜地管理方式往往依赖人工巡查,效率低下且容易受到人为因素的影响,无法实现对土壤、环境、作物生长状态的精准监控和调控。而智能化的菜地种植系统通过集成多种传感器,实现对土壤水分、温度、氮磷钾含量、环境温湿度、光照强度等数据的实时采集,能够为种植者提供及时、精准的决策支持,进而优化水资源的使用,促进作物的健康生长。

此外,随着物联网技术的发展和普及,农业领域的数字化转型也逐渐成为趋势。通过物联网技术,将各种传感器与设备连接起来,实现数据的远程采集和自动化控制,已成为提高农业生产效率和可持续性的重要手段。通过远程监控系统,种植者可以实时查看菜地的环境数据,并根据数据变化进行调整和优化,达到提高产量、降低成本、减少资源浪费的目的。

随着云计算技术和4G网络的发展,数据存储和处理的能力大大提升,云平台的应用使得智能农业管理系统的可扩展性和稳定性得到了极大的提升。本项目通过将设备数据实时上传至华为云物联网平台,能够实现多点分布式管理,为种植者提供更加灵活、便捷的管理手段。通过开发微信小程序和Web可视化大屏,用户可以在任何地点随时随地查看菜地的实时数据,并远程控制灌溉系统,实现真正的智慧化菜地管理。

在此背景下,本项目的智慧菜地种植系统应运而生,在利用物联网技术,结合现代农业的需求,提供一种全面的解决方案,助力农业智能化发展,提高菜地种植的精准度和效率,推动农业产业的现代化进程。


现场部署的场景:

image-20241225013601630


image-20241225013719765


image-20241225013734167


监控安装:

image-20241225013642154


设备安装控制盒:

image-20241225013811002


微信小程序远程灌溉:

image-20241225013847703


image-20241225013914964


查看远程视频监控: 远程看菜地的情况。

image-20241225013934862


image-20241225014002710


远程灌溉: 控制电磁阀,开启喷淋系统。

image-20241225014129413


image-20241225014147981



image-20241225014034120


image-20241225014105666

image-20241225014206835




1.2 设计实现的功能

(1)远程灌溉与自动灌溉控制 系统支持远程控制和自动灌溉功能。通过控制电磁阀,系统能够实现对浇水喷头的精准控制,确保在土壤水分不足时自动启动灌溉。同时,用户也可以通过微信小程序或Web网页进行远程手动控制,调整灌溉策略,满足不同作物的需求。

(2)土壤数据检测与分析 系统通过RS485接口连接的3合1土壤检测仪,实时监测土壤的水分含量、温度以及氮、磷、钾等营养元素的含量。土壤数据持续采集并上传至云平台,帮助用户实时掌握土壤状态,制定科学的灌溉和施肥计划。

(3)环境光照强度监测 系统集成了BH1750光照强度传感器,能够实时监测菜地的光照强度。用户可根据光照数据调整作物种植或采取相应措施,如调整遮阳网、控制人工光源等,确保作物获得适宜的光照条件。

(4)环境温湿度监测 系统内置SHT30温湿度传感器,用于实时监测菜地的环境温度和湿度。环境数据会不断上传至云平台,用户可以查看温湿度变化趋势,并进行适当的环境调节,如启动风扇或加湿设备,确保作物生长在最佳环境下。

(5)视频远程监控 通过独立的4G网络摄像头,系统支持实时视频监控,菜地的各个区域可以通过视频流进行实时观看。视频数据通过NGINX流媒体服务器传输至云平台,用户可以随时查看菜地的实时画面,确保种植环境的安全和健康。

(6)设备数据云端上传 所有采集到的设备数据(如土壤水分、环境温湿度、光照强度等)会通过4G模块(Air724UG)实时上传至华为云物联网平台。云平台提供了稳定的存储和处理能力,确保数据的安全性和可靠性,并支持大数据分析,为用户提供科学的种植决策支持。

(7)数据监测与远程控制 通过微信小程序和Web网页,用户可以方便地查看菜地的实时数据(如温湿度、土壤水分、光照强度等),并根据数据变化情况进行远程控制。例如,当土壤水分过低时,系统可以自动启动灌溉,或用户可手动调整灌溉时间和量。同时,用户可以通过平台进行设备控制和设置,确保菜地管理的高效性和智能化。

(8)设备API接口与集成 系统支持通过调用华为云物联网平台的API接口,实现设备与云平台之间的数据交互。通过API接口,用户可以获取设备实时数据,并向设备发送控制指令,确保系统的灵活性和可扩展性。系统支持多设备并行管理,能够适应不同规模的智慧菜地管理需求。

(9)实时报警与提醒功能 系统具备数据异常报警功能。当土壤水分、环境温湿度等关键参数超出设定范围时,系统会自动向用户发送报警信息,提醒用户采取相应措施,防止因参数异常而影响作物生长。此外,系统还可结合灌溉控制,根据环境变化进行自动调节,最大化减少资源浪费。

(10)用户权限管理与多终端支持 系统支持用户权限管理,确保不同级别的用户可以访问相应的功能。通过微信小程序、Web网页以及移动端应用,用户可以跨平台查看数据、控制设备,随时随地管理菜地,实现灵活、高效的远程管理和监控。


1.3 项目硬件模块组成

(1)主控芯片 - STM32F103RCT6 STM32F103RCT6作为系统的核心控制单元,负责处理各传感器采集的数据、控制灌溉系统、环境调节设备、视频监控及数据上传等任务。该芯片具有高性能的处理能力、丰富的外设接口以及低功耗特性,适合物联网应用中的智能控制。

(2)4G模块 - Air724UG Air724UG 4G模块用于实现设备的远程联网功能。它通过4G网络将设备数据上传至华为云物联网平台,支持高速、稳定的数据传输,保证远程控制和数据采集的实时性。该模块也支持SMS和TCP/IP通信,适应各种远程控制需求。

(3)土壤数据检测仪 - RS485接口3合1土壤传感器 该土壤检测仪通过RS485接口与主控芯片连接,支持土壤水分、温度、氮、磷、钾等营养元素的长期检测。传感器可埋入土壤中,长期工作,实时采集土壤数据,保证土壤环境监测的精确性和连续性。

(4)光照强度传感器 - BH1750 BH1750光照强度传感器用于检测菜地的环境光照强度,支持高精度的光照数据采集,帮助系统根据光照强度调整灌溉策略和作物生长环境,确保作物获得合适的光照条件。

(5)环境温湿度传感器 - SHT30 SHT30传感器用于实时监测菜地的环境温度和湿度。该传感器具有高精度、低功耗和快速响应的特点,确保环境数据的实时采集与反馈。

(6)4G独立摄像头 独立摄像头通过4G网络上传视频流,进行实时的菜地监控。摄像头将实时图像数据传输至NGINX流媒体服务器,用户可以通过微信小程序或Web平台进行远程查看。摄像头还支持夜视功能,确保在不同光照条件下都能提供清晰的视频监控。

(7)电磁阀控制模块 电磁阀用于控制灌溉系统的开关。通过STM32的控制信号,电磁阀能够精确控制水流的开关,确保灌溉系统在需要时精准启动,同时在灌溉完成后自动关闭,避免水资源浪费。

(8)继电器模块 继电器模块用于控制与主控芯片连接的其他高功率设备,如灌溉泵、水泵、风扇等。通过继电器模块,系统可以实现对不同设备的精确控制,保证菜地环境调节的自动化与智能化。

(9)NGINX流媒体服务器 NGINX流媒体服务器用于接收并分发来自4G独立摄像头的视频流。该服务器采用RTMP协议,支持视频数据的实时传输与播放,确保用户能够在Web平台上实时查看菜地的监控视频。

(10)华为云物联网平台 华为云物联网平台用于设备数据的存储和处理。通过4G模块将采集到的土壤数据、环境数据等上传至云平台,平台提供数据可视化、存储和分析功能,支持远程监控、报警、数据回溯等操作,是系统实现远程管理的关键组成部分。



1.4 设计思路

本项目的设计思路是基于物联网技术,结合现代农业需求,提供一个全面的智能菜地种植管理解决方案。该系统旨在通过实时监测土壤、环境和作物生长状态,采用自动化控制和远程管理手段,帮助用户实现精确灌溉、环境调控以及远程监控,最大程度提高作物生产效率和资源利用率。

系统的核心思想是实现土壤和环境数据的实时监测与分析。通过部署土壤水分、温度、氮磷钾含量、环境温湿度和光照强度等传感器,系统可以全面了解菜地的生长环境,确保作物在最佳条件下生长。土壤传感器(RS485接口的3合1土壤检测仪)能够长期埋入土壤中,实时监测土壤的各项指标。环境传感器(如SHT30和BH1750)则不断监测空气中的温湿度和光照强度,为系统提供实时的环境数据。这些数据将通过4G网络上传至云平台,实现数据的集中存储和分析,确保数据的完整性和实时性。

系统注重自动化控制与远程管理的结合。基于传感器采集的数据,系统能够实现自动化控制,如根据土壤水分水平自动启动灌溉系统,或根据环境温湿度自动调整通风设备或加湿器等。灌溉控制是该系统的关键功能之一,系统通过控制电磁阀来实现精确的灌溉控制,不仅减少人工干预,还避免水资源浪费。此外,系统支持远程手动控制,用户可以通过微信小程序或Web界面实时查看和调整灌溉策略,提供了灵活的管理方式。

为了增强系统的可操作性和智能性,设计了基于视频监控的远程管理功能。通过4G独立摄像头,系统可以实时传输菜地的监控视频到云平台,用户可以随时查看菜地的生长情况和环境状态,确保菜地管理的透明度和安全性。视频流通过NGINX流媒体服务器处理,支持多终端访问,保证用户能够在任何地点进行实时监控。

设备数据上传至华为云物联网平台,保证了数据的长期存储、分析和处理。云平台不仅为数据提供高效的存储空间,还支持基于大数据分析的智能决策和设备管理。系统通过调用华为云的API接口,实现与设备的双向通信,用户可以通过API获取设备的实时数据并发送控制指令,从而实现精准的设备控制。

为了提高系统的稳定性和应急响应能力,设计时还考虑了故障检测与报警机制。例如,系统能够监测各项参数是否超出设定范围,一旦出现异常,自动向用户发送报警信息,并启动预设的应急措施,以减少不良影响。

系统设计围绕“智能化、自动化、远程管理”的核心思想展开,通过物联网和云计算技术的结合,为用户提供一个高效、可持续的智慧菜地管理解决方案。该系统不仅提高了农业管理的效率,减少了人工成本,还优化了资源使用,具有较高的环境友好性和经济效益。


1.5 系统功能总结

功能模块 描述
远程灌溉与自动灌溉控制 支持远程手动控制和自动灌溉功能,通过电磁阀控制灌溉喷头,确保精准浇水,避免水资源浪费。
土壤数据监测与分析 实时监测土壤水分、温度、氮磷钾等元素含量,帮助用户了解土壤状态并做出科学决策,保证作物健康生长。
环境光照强度监测 通过BH1750光照强度传感器实时监测菜地的光照强度,确保作物获得足够的光照条件,调整光照策略。
环境温湿度监测 通过SHT30温湿度传感器监测菜地环境的温湿度,系统可以自动调整通风、加湿等设备,确保作物生长环境的适宜性。
视频远程监控 支持通过4G独立摄像头实时视频监控菜地,视频流通过NGINX流媒体服务器传输,用户可以随时查看菜地的实时画面。
设备数据云端上传 通过4G模块(Air724UG)将设备数据实时上传至华为云物联网平台,保证数据存储、处理和访问的高效性与安全性。
数据监测与远程控制 用户通过微信小程序或Web平台查看土壤、环境数据,并进行远程控制,如调整灌溉、光照、环境温湿度等,提供灵活的管理方式。
实时报警与提醒功能 系统当监测到数据超出预设范围时,自动向用户发送报警信息,提醒用户采取必要的措施,确保作物生长不受影响。
设备API接口与集成 通过华为云物联网平台的API接口,实现设备与云平台之间的数据交互,支持设备状态查询、远程控制和数据上传。
用户权限管理与多终端支持 支持不同用户权限管理,提供微信小程序、Web平台等多终端支持,用户可以随时随地远程监控和管理菜地。



1.8 模块的技术详情介绍

【1】Air724UG-4G模块

Air724UG是一款功能强大且广泛应用于物联网(IoT)领域的4G通信模块。它专为低功耗广域网(LPWAN)应用设计,兼具高性能和稳定性,适用于多种物联网终端设备,包括智能表计、移动支付、智能家居、车载电子等场景。该模块支持4G LTE Cat 1网络制式,是一款具备高性价比的无线通信解决方案。

Air724UG这款模块支持LTE FDD网络,能够提供稳定的语音和数据传输服务,并向下兼容2G GSM网络,使得在4G信号弱或不可用的区域仍可正常通信。由于其双网支持能力,这一模块可以灵活适应不同的网络环境,从而更广泛地满足客户需求。

在数据通信方面,Air724UG模块支持SMS(短消息服务)、TCP/UDP、HTTP/HTTPS、MQTT等协议,为用户开发与应用提供了多种可选方案。其良好的传输能力,能够满足物联网设备对数据可靠性、响应速度等方面的严苛需求。这使其在多种行业和领域中得到了广泛应用,如工业自动化、智能物流、移动支付等。模块具备高效的数据传输和低延迟特性,是许多物联网解决方案中的理想选择。

Air724UG模块在设计上注重低功耗特性,这在许多长期依赖电池供电的IoT设备中显得尤为重要。模块支持深度睡眠模式和待机模式,有效降低功耗,延长设备的使用寿命。此外,Air724UG的尺寸较为紧凑,提供易于集成的设计,能够在有限的空间内实现灵活部署,适应各种复杂应用场景。

在接口和硬件配置方面,Air724UG-4G模块集成了丰富的接口,包括UART、I2C、SPI、ADC、GPIO等,为用户提供了极大的开发灵活性。此外,模块还具备支持多种通信协议和功能的AT指令集,便于用户进行功能扩展和定制。模块的工作温度范围广,能够在严苛的环境下保持稳定性能,使其在工业、户外和其他环境条件变化较大的场景中表现出色。

综合而言,Air724UG模块是一款兼顾高性能与灵活性的4G模块,专注于物联网应用的低功耗和高稳定性需求。它的多网络支持、强大的数据传输能力、低功耗特性以及灵活的硬件接口设计,使其成为物联网设备开发中备受青睐的选择。

【2】MQTT协议

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是一种轻量级、发布/订阅模式的消息传输协议,专为低带宽、不可靠网络环境设计。它最早由IBM提出,现已成为物联网(IoT)通信的重要协议之一。由于其高效、低功耗和实时性等特点,MQTT在智能家居、工业自动化、远程监控和车联网等领域得到了广泛应用。

MQTT的工作原理基于发布/订阅模型。这种模型有别于传统的客户端-服务器模型,通信方不需要直接建立连接。MQTT由三个核心组件构成:客户端、代理(Broker)和主题(Topic)。客户端可以作为消息的发布者或订阅者,消息通过代理进行路由。代理是一个中间服务端,用于接收和分发来自不同客户端的消息。发布者发送消息到一个特定的主题上,代理负责将这些消息分发给所有订阅了该主题的客户端。通过这种解耦的架构设计,客户端之间可以实现松耦合的通信,降低了复杂性和依赖性。

在MQTT协议中,消息被分为不同的主题(Topic),例如“home/sensor/temperature”可以用来代表温度传感器数据。客户端可以订阅这个主题,当发布者发送新的数据到该主题时,所有订阅该主题的客户端都会收到更新信息。这种灵活的主题结构和层次化的命名规则,使得MQTT在复杂场景下也能快速组织和管理消息流。

MQTT协议支持三种服务质量(QoS)等级,分别为“至多一次”(QoS 0)、“至少一次”(QoS 1)和“仅一次”(QoS 2)。QoS 0表示消息传输尽力而为,可能会丢失或重复;QoS 1确保消息至少送达一次,但可能会有重复;QoS 2则确保消息恰好传输一次,保证消息的严格可靠性。这种设计使MQTT能够适应不同的应用场景,用户可以根据应用需求选择合适的QoS级别。

为了保证通信的安全性,MQTT支持用户名和密码验证,代理可以对连接进行身份认证。此外,许多实现中还支持TLS/SSL加密通信,确保数据在传输过程中不会被窃取或篡改。用户也可以使用不同的认证方式来增强系统的安全性,适应物联网应用中对安全性的高需求。

MQTT非常注重轻量化和低功耗。它的报文头非常小,通信开销很低,这使其特别适合在资源受限的设备或不稳定的网络环境中使用。MQTT支持“保持连接”和“遗嘱消息”功能,客户端可以在连接断开时自动向代理发送遗嘱消息,通知其他客户端连接状态的变化。这种特性有助于提高网络的健壮性和系统的可用性。

MQTT的典型使用场景包括物联网设备数据采集、实时监控、消息推送和控制命令的发布。比如在智能家居中,传感器可以发布环境数据,如温湿度、烟雾浓度等,控制设备根据收到的消息作出响应,实现自动化操作。在工业场景中,MQTT可以帮助收集和管理大规模设备的运行状态,实现集中化和高效的设备监控。

MQTT协议凭借其低功耗、高效能、实时性强等优势,已成为物联网通信的主要协议之一。它的发布/订阅模式简化了设备之间的通信,使其特别适合多对多、低延迟、高可靠性的数据传输场景。MQTT易于使用、拓展性强,为开发者提供了灵活的解决方案来构建各种物联网应用。


【3】BH1750模块

BH1750是一款数字光照强度传感器模块,主要用于测量环境的光照强度。它使用I2C通信协议与微控制器(如STM32)进行数据交换,具有高精度和较低功耗的特点,广泛应用于智能照明、环境监测、自动化控制等领域。BH1750模块的核心功能是感知环境中的光强,输出的光照值以Lux(勒克斯)为单位,能够准确反映周围环境的亮度。

该模块内置光敏元件和数字处理电路,能够直接输出数字信号,而不需要模拟转换过程。这使得BH1750模块能够提供较高的测量精度和稳定性,避免了传统模拟光传感器需要额外的模拟转数字电路,从而简化了硬件设计,降低了系统的复杂性。BH1750的测量范围从1 Lux到65535 Lux,适用于从暗到极亮的环境光照监测。

BH1750传感器具有多个测量模式,包括连续测量模式和一次性测量模式。在连续模式下,传感器会周期性地测量光照强度并不断输出数据,而在一次性测量模式下,用户可以在需要时启动单次测量,传感器在完成一次测量后停止工作,节省功耗。此外,BH1750还支持多个工作模式,可以根据不同应用场景选择最适合的测量方式。

在实际应用中,BH1750模块常用于智能照明系统中,用以自动调节灯光亮度,或用于环境监测系统中,以监测光照变化并自动触发其他设备的控制。例如,在智慧菜地种植系统中,BH1750可以监测环境的光照强度,当光照强度不足时,系统可以自动开启人工光源或调节遮阳设备,确保作物在最佳光照条件下生长。

BH1750模块凭借其高精度、低功耗和简便的I2C接口,成为了许多智能控制和环境监测系统中的关键传感器之一,特别适用于需要实时监测环境光照强度的物联网应用。


【4】SHT30模块

SHT30是一款高精度的温湿度传感器模块,广泛应用于环境监测、物联网设备、智能家居等领域。它由瑞士Sensirion公司设计制造,采用数字输出方式,能够精确测量环境中的温度和湿度,并通过I2C接口将数据传输给主控芯片,如STM32或其他微控制器。SHT30模块的高精度和稳定性使其成为众多应用中的首选传感器。

SHT30传感器的测量范围宽广,温度范围为-40°C至+125°C,湿度范围为0%至100% RH(相对湿度)。它具有较高的测量精度,温度的精度可达到±0.3°C,湿度的精度为±2% RH,确保数据的准确性。这使得SHT30模块能够在多种环境条件下提供可靠的温湿度数据,适用于对环境变化要求较高的场景,例如室内空气质量监测、智能气候控制和农业种植系统。

该模块采用I2C接口进行通信,具有多种工作模式,包括单次测量和连续测量模式。在单次测量模式下,传感器执行一次测量并将数据返回主控芯片;而在连续测量模式下,传感器会定期自动采样,持续提供温湿度数据,适用于需要实时监测的应用。SHT30传感器支持低功耗工作,非常适合需要长时间稳定运行的设备,尤其是在电池供电的物联网设备中表现突出。

SHT30还具备较高的抗干扰能力,并且具有快速响应时间。在环境温湿度发生变化时,传感器能够迅速更新数据,确保系统能够根据最新的环境条件进行调节。在智能农业系统中,SHT30能够实时监测菜地或温室的环境温湿度数据,从而帮助系统调整灌溉、加湿、通风等设备,保证作物在最佳的生长环境中生长。

SHT30模块以其高精度、稳定性、低功耗和易于集成的特点,成为了物联网和智能控制领域中温湿度监测的重要组件。在智能家居、环境监测、农业物联网等应用中,SHT30发挥着重要作用,帮助用户实现环境的自动化调控和智能管理。



二、硬件选型(搭建模型参考)

如果大家想自己搭建模型,完成这个项目的功能测试。

那么可以看参考下面的部分硬件模块选型。


2.1 土壤信息检测

链接:

https://item.taobao.com/item.htm?abbucket=8&id=637621818080&ns=1&pisk=frsIL3MscXcIIgaUlYew1Vuz9GxWA_ZqOY9RnTnEeHKpwN6cNByu-H76N1C69Dy3-Ud5tHLl8QReN36lGRP40oWhK3xLgSrqX2IN8nvK2QhyWlpy-5yZ_oWhKQDIw-7T0baSMK3KyQCJXFpW33pp92KTCL9Xw3dpyf39HCKJw_dKWFp2E4hJ2QhTCK9o94LJJAK9KLhJw_K8COhV2P9TRCWQQpNgntilh9dscOj6pSA4mCm-2G9CLLWKr0nRfpTd4bbCbMYFytYcYTZSjHWfWhp5q-3WNE_RYhIL6oLMyGC9B6yrrd_5eixH-YoPGH1WkMLse0xdpBt6BieroCS6T_IBW-oXzhI2kHQaSW8yAK1Rx6MS2sBN3MYGVSG9ZwJDXLsuH4OWygPq0I9LH4M6o096gRwsr4XwZosy6VehXepMIxy_CqukJdv6gRwsr4YpIdqaCRgqr&priceTId=215042f417350592405177324e1dc1&skuId=5317193564462&spm=a21n57.1.item.21.5489523cC6aCFu&utparam=%7B%22aplus_abtest%22%3A%22c4e67590849e836c4006d57cff768c85%22%7D&xxc=taobaoSearch


image-20241225011203347



2.2 灌溉电磁阀

image-20241225012008576





三、部署华为云物联网平台

当前项目使用的相关软件工具和模块代码已经上传到网盘

https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink


华为云官网: https://www.huaweicloud.com/

打开官网,搜索物联网,就能快速找到 设备接入IoTDA

image-20221204193824815


3.1 物联网平台介绍

华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助我们快速构筑物联网解决方案。

使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。

物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。

设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。

业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。

img



3.2 开通物联网服务

地址: https://www.huaweicloud.com/product/iothub.html

image-20241028135834377


开通免费单元。

image-20241028135935457


点击立即创建

image-20240117134653452


正在创建标准版实例,需要等待片刻。

image-20241028140048811




创建完成之后,点击详情。 可以看到标准版实例的设备接入端口和地址。

image-20241028140129102


下面框起来的就是端口号域名

image-20241028140229696



点击实例名称,可以查看当前免费单元的配置情况。

image-20241028140331523


image-20241028140428663


开通之后,点击接入信息,也能查看接入信息。 我们当前设备准备采用MQTT协议接入华为云平台,这里可以看到MQTT协议的地址和端口号等信息。

image-20241028140511105


总结:

端口号:   MQTT (1883)| MQTTS (8883)    
接入地址: dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com

根据域名地址得到IP地址信息:

打开Windows电脑的命令行控制台终端,使用ping 命令。ping一下即可。

Microsoft Windows [版本 10.0.19045.5011]
(c) Microsoft Corporation。保留所有权利。
​
C:\Users\Lenovo>ping dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com
​
正在 Ping dab1a1f2c6.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字节的数据:
来自 117.78.5.125 的回复: 字节=32 时间=37ms TTL=44
来自 117.78.5.125 的回复: 字节=32 时间=37ms TTL=44
来自 117.78.5.125 的回复: 字节=32 时间=37ms TTL=44
来自 117.78.5.125 的回复: 字节=32 时间=37ms TTL=44
​
117.78.5.125 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 37ms,最长 = 37ms,平均 = 37ms
​
C:\Users\Lenovo>
​

MQTT协议接入端口号有两个,1883是非加密端口,8883是证书加密端口,单片机无法加载证书,所以使用1883端口合适



3.3 创建产品

链接:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-dev/all-product?instanceId=03c5c68c-e588-458c-90c3-9e4c640be7af

(1)创建产品

image-20241028141601305


(2)填写产品信息

根据自己产品名字填写,下面的设备类型选择自定义类型。

image-20240612094809689


(3)产品创建成功

image-20240612095148945


创建完成之后点击查看详情。

image-20240612095134263


(4)添加自定义模型

产品创建完成之后,点击进入产品详情页面,翻到最下面可以看到模型定义。

模型简单来说: 就是存放设备上传到云平台的数据。

你可以根据自己的产品进行创建。

比如:

烟雾可以叫  MQ2
温度可以叫  Temperature
湿度可以叫  humidity
火焰可以叫  flame
其他的传感器自己用单词简写命名即可。 这就是你的单片机设备端上传到服务器的数据名字。



先点击自定义模型。

image-20240612095517900


再创建一个服务ID。

image-20240612095542749


接着点击新增属性。

image-20240612095648815


image-20240612095711898



3.4 添加设备

产品是属于上层的抽象模型,接下来在产品模型下添加实际的设备。添加的设备最终需要与真实的设备关联在一起,完成数据交互。

(1)注册设备

image-20240425181935561


(2)根据自己的设备填写

image-20240612100115167


(3)保存设备信息

创建完毕之后,点击保存并关闭,得到创建的设备密匙信息。该信息在后续生成MQTT三元组的时候需要使用。

image-20240612100128061



(4)设备创建完成

image-20240612100147232



(5)设备详情

image-20240612100202960



image-20240612100217236




3.5 MQTT协议主题订阅与发布

(1)MQTT协议介绍

当前的设备是采用MQTT协议与华为云平台进行通信。

MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。目前MQTT拥有各种平台和设备上的客户端,已经形成了初步的生态系统。

MQTT是一种消息队列协议,使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合,相对于其他协议,开发更简单;MQTT协议是工作在TCP/IP协议上;由TCP/IP协议提供稳定的网络连接;所以,只要具备TCP协议栈的网络设备都可以使用MQTT协议。 本次设备采用的ESP8266就具备TCP协议栈,能够建立TCP连接,所以,配合STM32代码里封装的MQTT协议,就可以与华为云平台完成通信。


华为云的MQTT协议接入帮助文档在这里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

img


业务流程:

img

(2)华为云平台MQTT协议使用限制

描述 限制
支持的MQTT协议版本 3.1.1
与标准MQTT协议的区别 支持Qos 0和Qos 1支持Topic自定义不支持QoS2不支持will、retain msg
MQTTS支持的安全等级 采用TCP通道基础 + TLS协议(最高TLSv1.3版本)
单帐号每秒最大MQTT连接请求数 无限制
单个设备每分钟支持的最大MQTT连接数 1
单个MQTT连接每秒的吞吐量,即带宽,包含直连设备和网关 3KB/s
MQTT单个发布消息最大长度,超过此大小的发布请求将被直接拒绝 1MB
MQTT连接心跳时间建议值 心跳时间限定为30至1200秒,推荐设置为120秒
产品是否支持自定义Topic 支持
消息发布与订阅 设备只能对自己的Topic进行消息发布与订阅
每个订阅请求的最大订阅数 无限制


(3)主题订阅格式

帮助文档地址:https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

image-20221207153310037

对于设备而言,一般会订阅平台下发消息给设备 这个主题。

设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。

如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。

以当前设备为例,最终订阅主题的格式如下:
$oc/devices/{device_id}/sys/messages/down
    
最终的格式:
$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down


(4)主题发布格式

对于设备来说,主题发布表示向云平台上传数据,将最新的传感器数据,设备状态上传到云平台。

这个操作称为:属性上报。


帮助文档地址:https://support.huaweicloud.com/usermanual-iothub/iot_06_v5_3010.html

image-20221207153637391


根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:

发布的主题格式:
$oc/devices/{device_id}/sys/properties/report
 
最终的格式:
$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report
发布主题时,需要上传数据,这个数据格式是JSON格式。
​
上传的JSON数据格式如下:
​
{
  "services": [
    {
      "service_id": <填服务ID>,
      "properties": {
        "<填属性名称1>": <填属性值>,
        "<填属性名称2>": <填属性值>,
        ..........
      }
    }
  ]
}
根据JSON格式,一次可以上传多个属性字段。 这个JSON格式里的,服务ID,属性字段名称,属性值类型,在前面创建产品的时候就已经介绍了,不记得可以翻到前面去查看。
​
根据这个格式,组合一次上传的属性数据:
{"services": [{"service_id": "stm32","properties":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}


3.6 MQTT三元组

MQTT协议登录需要填用户ID,设备ID,设备密码等信息,就像我们平时登录QQ,微信一样要输入账号密码才能登录。MQTT协议登录的这3个参数,一般称为MQTT三元组。

接下来介绍,华为云平台的MQTT三元组参数如何得到。


(1)MQTT服务器地址

要登录MQTT服务器,首先记得先知道服务器的地址是多少,端口是多少。

帮助文档地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home

image-20240509193207359


MQTT协议的端口支持1883和8883,它们的区别是:8883 是加密端口更加安全。但是单片机上使用比较困难,所以当前的设备是采用1883端口进连接的。

根据上面的域名和端口号,得到下面的IP地址和端口号信息: 如果设备支持填写域名可以直接填域名,不支持就直接填写IP地址。 (IP地址就是域名解析得到的)

华为云的MQTT服务器地址:117.78.5.125
华为云的MQTT端口号:1883


如何得到IP地址?如何域名转IP? 打开Windows的命令行输入以下命令。

ping  ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com

image-20240425182610048



(2)生成MQTT三元组

华为云提供了一个在线工具,用来生成MQTT鉴权三元组: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。

下面是打开的页面:

image-20240425183025893


填入设备的信息: (上面两行就是设备创建完成之后保存得到的)

直接得到三元组信息。

image-20240509193310020


得到三元组之后,设备端通过MQTT协议登录鉴权的时候,填入参数即可。

ClientId  663cb18871d845632a0912e7_dev1_0_0_2024050911
Username  663cb18871d845632a0912e7_dev1
Password  71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237



3.7 模拟设备登录测试

经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。

MQTT软件下载地址【免费】: https://download.csdn.net/download/xiaolong1126626497/89928772

(1)填入登录信息

打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。

image-20240509193457358



(2)打开网页查看

完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。

image-20240612100508790


点击详情页面,可以看到上传的数据:

image-20240612100529581


到此,云平台的部署已经完成,设备已经可以正常上传数据了。


(3)MQTT登录测试参数总结

MQTT服务器:  117.78.5.125
MQTT端口号:  183

//物联网服务器的设备信息
#define MQTT_ClientID "663cb18871d845632a0912e7_dev1_0_0_2024050911"
#define MQTT_UserName "663cb18871d845632a0912e7_dev1"
#define MQTT_PassWord "71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237"

//订阅与发布的主题
#define SET_TOPIC  "$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down"  //订阅
#define POST_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report"  //发布


发布的数据:
{"services": [{"service_id": "stm32","properties":{"你的字段名字1":30,"你的字段名字2":10,"你的字段名字3":1,"你的字段名字4":0}}]}


3.8 创建IAM账户

创建一个IAM账户,因为接下来开发上位机,需要使用云平台的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。

地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users


【1】获取项目凭证 点击左上角用户名,选择下拉菜单里的我的凭证

image-20240509193646253


image-20240509193701262


项目凭证:

28add376c01e4a61ac8b621c714bf459



【2】创建IAM用户

鼠标放在左上角头像上,在下拉菜单里选择统一身份认证

image-20240509193729078



点击左上角创建用户

image-20240509193744287



image-20240314153208692




image-20240314153228359

image-20240314153258229



创建成功:

image-20240314153315444



【3】创建完成

image-20240509193828289


用户信息如下:

主用户名  l19504562721
IAM用户  ds_abc
密码     DS12345678



3.9 获取影子数据

帮助文档:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html

设备影子介绍:

设备影子是一个用于存储和检索设备当前状态信息的JSON文档。
每个设备有且只有一个设备影子,由设备ID唯一标识
设备影子仅保存最近一次设备的上报数据和预期数据
无论该设备是否在线,都可以通过该影子获取和设置设备的属性

简单来说:设备影子就是保存,设备最新上传的一次数据。

我们设计的软件里,如果想要获取设备的最新状态信息,就采用设备影子接口。


如果对接口不熟悉,可以先进行在线调试:https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=IoTDA&api=ShowDeviceShadow


在线调试接口,可以请求影子接口,了解请求,与返回的数据格式。


调试完成看右下角的响应体,就是返回的影子数据。

image-20240509194152229



设备影子接口返回的数据如下:

{
 "device_id": "663cb18871d845632a0912e7_dev1",
 "shadow": [
  {
   "service_id": "stm32",
   "desired": {
    "properties": null,
    "event_time": null
   },
   "reported": {
    "properties": {
     "DHT11_T": 18,
     "DHT11_H": 90,
     "BH1750": 38,
     "MQ135": 70
    },
    "event_time": "20240509T113448Z"
   },
   "version": 3
  }
 ]
}



调试成功之后,可以得到访问影子数据的真实链接,接下来的代码开发中,就采用Qt写代码访问此链接,获取影子数据,完成上位机开发。

image-20240509194214716


链接如下:

https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow


3.10 访问接口的代码实现

(1)配置 Qt 项目

在 Qt 项目的 .pro 文件中,加入对 libcurl 的支持:

QT += core
CONFIG += console
CONFIG -= app_bundle

INCLUDEPATH += /usr/include/curl  # 根据你的系统设置 libcurl 的路径
LIBS += -lcurl  # 链接 libcurl 库

SOURCES += main.cpp

(2)代码实现

main.cpp 文件中实现代码如下:

#include <QCoreApplication>
#include <curl/curl.h>
#include <QDebug>
#include <QString>
#include <QByteArray>

// 回调函数,处理libcurl下载数据
size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t totalSize = size * nmemb;
    QByteArray *response = static_cast<QByteArray *>(userp);
    response->append(static_cast<char *>(contents), totalSize);
    return totalSize;
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 初始化libcurl
    CURL *curl;
    CURLcode res;
    QByteArray responseData;  // 用于存储响应数据

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (curl) {
        // 设置访问URL
        const QString url = "https://ad635970a1.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/28add376c01e4a61ac8b621c714bf459/devices/663cb18871d845632a0912e7_dev1/shadow";

        // 设置HTTP请求头
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Authorization: Bearer <Your_Access_Token>"); // 这里需要替换为你的实际 token

        curl_easy_setopt(curl, CURLOPT_URL, url.toStdString().c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);

        // 发起GET请求
        res = curl_easy_perform(curl);

        if (res != CURLE_OK) {
            qDebug() << "Curl request failed:" << curl_easy_strerror(res);
        } else {
            qDebug() << "Response data:" << responseData;
        }

        // 清理
        curl_easy_cleanup(curl);
        curl_slist_free_all(headers);
    }

    curl_global_cleanup();

    return a.exec();
}



3.11 数据解析代码

在 Qt 中使用 CJSON (一个用于解析 JSON 数据的轻量级 C 库) 来解析返回的 JSON 数据。

(1)配置 Qt 项目

在 Qt 项目的 .pro 文件中,确保包括了 CJSON 的头文件,并链接 CJSON 的源代码。

QT += core
CONFIG += console
CONFIG -= app_bundle

SOURCES += main.cpp \
           cJSON.c  # 将 cJSON.c 文件添加到你的项目中

INCLUDEPATH += path/to/cjson/  # 添加 CJSON 头文件的路径

LIBS += -lcurl  # 链接 libcurl 库

(2)解析 JSON 数据的完整代码

main.cpp 中,以下代码展示了如何解析你提供的 JSON 数据。

#include <QCoreApplication>
#include <curl/curl.h>
#include <QDebug>
#include <QString>
#include <QByteArray>
#include "cJSON.h"

// 回调函数,处理libcurl下载数据
size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t totalSize = size * nmemb;
    QByteArray *response = static_cast<QByteArray *>(userp);
    response->append(static_cast<char *>(contents), totalSize);
    return totalSize;
}

// 解析 JSON 数据
void parseJson(const QByteArray &data) {
    // 将 QByteArray 转换为 char*
    const char* jsonData = data.constData();

    // 解析 JSON
    cJSON *root = cJSON_Parse(jsonData);
    if (root == NULL) {
        qDebug() << "Error parsing JSON.";
        return;
    }

    // 解析 "device_id"
    cJSON *deviceId = cJSON_GetObjectItemCaseSensitive(root, "device_id");
    if (cJSON_IsString(deviceId) && (deviceId->valuestring != NULL)) {
        qDebug() << "Device ID:" << deviceId->valuestring;
    }

    // 解析 "shadow" 数组
    cJSON *shadow = cJSON_GetObjectItemCaseSensitive(root, "shadow");
    if (cJSON_IsArray(shadow)) {
        cJSON *shadowItem = NULL;
        cJSON_ArrayForEach(shadowItem, shadow) {
            // 解析每个 shadow 项目
            cJSON *serviceId = cJSON_GetObjectItemCaseSensitive(shadowItem, "service_id");
            if (cJSON_IsString(serviceId) && (serviceId->valuestring != NULL)) {
                qDebug() << "Service ID:" << serviceId->valuestring;
            }

            // 解析 "reported" 对象
            cJSON *reported = cJSON_GetObjectItemCaseSensitive(shadowItem, "reported");
            if (cJSON_IsObject(reported)) {
                // 解析 "properties" 对象
                cJSON *properties = cJSON_GetObjectItemCaseSensitive(reported, "properties");
                if (cJSON_IsObject(properties)) {
                    cJSON *data1 = cJSON_GetObjectItemCaseSensitive(properties, "data1");
                    if (cJSON_IsNumber(data1)) {
                        qDebug() << "data1:" << data1->valueint;
                    }
                    cJSON *data2 = cJSON_GetObjectItemCaseSensitive(properties, "data2");
                    if (cJSON_IsNumber(data2)) {
                        qDebug() << "data2:" << data2->valueint;
                    }
                    cJSON *data3 = cJSON_GetObjectItemCaseSensitive(properties, "data3");
                    if (cJSON_IsNumber(data3)) {
                        qDebug() << "data3:" << data3->valueint;
                    }
                    cJSON *data4 = cJSON_GetObjectItemCaseSensitive(properties, "data4");
                    if (cJSON_IsNumber(data4)) {
                        qDebug() << "data4:" << data4->valueint;
                    }
                }

                // 解析 "event_time"
                cJSON *eventTime = cJSON_GetObjectItemCaseSensitive(reported, "event_time");
                if (cJSON_IsString(eventTime) && (eventTime->valuestring != NULL)) {
                    qDebug() << "Event Time:" << eventTime->valuestring;
                }
            }

            // 解析 version
            cJSON *version = cJSON_GetObjectItemCaseSensitive(shadowItem, "version");
            if (cJSON_IsNumber(version)) {
                qDebug() << "Version:" << version->valueint;
            }
        }
    }

    // 释放 JSON 对象
    cJSON_Delete(root);
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 模拟获取到的 JSON 数据
    QByteArray jsonData = R"(
    {
        "device_id": "663cb18871d845632a0912e7_dev1",
        "shadow": [
            {
                "service_id": "stm32",
                "desired": {
                    "properties": null,
                    "event_time": null
                },
                "reported": {
                    "properties": {
                        "data1": 18,
                        "data2": 90,
                        "data3": 38,
                        "data4": 70
                    },
                    "event_time": "20240509T113448Z"
                },
                "version": 3
            }
        ]
    })";

    // 调用解析函数
    parseJson(jsonData);

    return a.exec();
}


四、STM32设备端代码设计

当前项目使用的相关软件工具和模块代码已经上传到网盘

https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink


下面是STM32代码的核心框架,展示了如何初始化硬件模块、采集数据、控制执行器以及通过4G模块上传数据到云服务器。

已完成的模块包括:

  • 温湿度传感器(SHT30)

  • 光照强度传感器(BH1750)

  • 土壤检测模块(RS485接口)

  • 电磁阀控制

  • 4G模块(Air724UG)上传数据

  • 显示屏显示

  • 继电器控制等

#include "stm32f1xx_hal.h"
#include "sht30.h"
#include "bh1750.h"
#include "soil_sensor.h"
#include "oled_display.h"
#include "relay_control.h"
#include "gsm_4g_module.h"
#include "mqtt_client.h"
#include "main.h"
​
// 定义全局变量
float temperature, humidity, soilMoisture, nitrogen, phosphorus, potassium;
uint16_t lightIntensity;
char payload[256];
​
// 初始化函数原型
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM3_Init(void);
​
// 主函数
int main(void)
{
    // HAL初始化
    HAL_Init();
​
    // 配置系统时钟
    SystemClock_Config();
​
    // 初始化各外设模块
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    MX_TIM3_Init();
​
    // 初始化传感器模块
    SHT30_Init();
    BH1750_Init();
    Soil_Sensor_Init();
    OLED_Init();
    Relay_Init();
    GSM_4G_Init();
    MQTT_Client_Init();
​
    // 系统状态指示
    OLED_Display_Message("System Initialized");
​
    while (1)
    {
        // 获取传感器数据
        SHT30_Read_Temperature_Humidity(&temperature, &humidity);
        BH1750_Read_Light_Intensity(&lightIntensity);
        Soil_Sensor_Read(&soilMoisture, &nitrogen, &phosphorus, &potassium);
​
        // 显示传感器数据到OLED
        OLED_Clear();
        OLED_Display_Temperature(temperature);
        OLED_Display_Humidity(humidity);
        OLED_Display_Light_Intensity(lightIntensity);
        OLED_Display_Soil_Moisture(soilMoisture);
​
        // 控制灌溉系统(根据土壤湿度自动启动)
        if (soilMoisture < 30.0)
        {
            Relay_Control(RELAY_ON);  // 启动灌溉
        }
        else
        {
            Relay_Control(RELAY_OFF); // 关闭灌溉
        }
​
        // 生成MQTT负载
        snprintf(payload, sizeof(payload),
                 "{\"temperature\": %.2f, \"humidity\": %.2f, \"soilMoisture\": %.2f, \"lightIntensity\": %d, \"nitrogen\": %.2f, \"phosphorus\": %.2f, \"potassium\": %.2f}",
                 temperature, humidity, soilMoisture, lightIntensity, nitrogen, phosphorus, potassium);
​
        // 上传数据到云端(华为云物联网平台)
        GSM_4G_Send_Data(payload);
​
    
    }
}
​
// 时钟配置函数
void SystemClock_Config(void)
{
    // 配置系统时钟为默认配置
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
​
    // 初始化HSE振荡器
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
​
    // 初始化时钟
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
}
​
// GPIO初始化函数
static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
​
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
​
    // 配置按键输入
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
​
// I2C1初始化函数
static void MX_I2C1_Init(void)
{
    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x10909A9B;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
        Error_Handler();
    }
}
​
// USART1初始化函数
static void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}
​
// 定时器3初始化函数
static void MX_TIM3_Init(void)
{
    __HAL_RCC_TIM3_CLK_ENABLE();
​
    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 7200 - 1;
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 10000 - 1; // 1s
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
    {
        Error_Handler();
    }
}
​
// 错误处理函数
void Error_Handler(void)
{
    // 用户可以添加错误处理代码
    while (1)
    {
        // 错误时,进入死循环
    }
}

说明:

  1. 初始化硬件模块:在 main 函数中,我们调用了初始化函数,设置了I2C、UART等外设,初始化了所有的传感器和执行器模块。

  2. 数据采集与控制:系统定期读取温湿度、光照、土壤数据,并通过OLED显示屏显示相关信息。同时,系统根据土壤湿度自动控制灌溉系统的开关。

  3. 上传数据到云端:将采集的数据打包成JSON格式,通过4G模块(Air724UG)发送至华为云物联网平台。


五、私有化部署物联网服务器:EMQX搭建方案

很多企业和个人也会选将物联网系统部署在自己的私有服务器上,以更好地掌控数据安全、隐私保护以及系统性能等方面的问题。相比公共云平台,私有化部署不仅能够节省运营成本,还能提高数据访问的灵活性和定制化服务的能力。因此,搭建自己的物联网服务器成为了许多物联网项目开发者的选择。

在本项目中,也同时选择了 EMQX 作为物联网服务器的搭建另一种方案。EMQX是一个高性能、开源的MQTT消息中间件,广泛应用于物联网、车联网、智慧家居等领域。它支持高并发、低延迟的消息传输,能够满足大规模设备的连接需求,并且支持与各种数据库和存储系统的集成,方便进行数据存储与分析。

通过自建物联网服务器,可以完全掌控服务器的配置与管理,实现更高的灵活性与定制化功能。此外,EMQX的开源特性使其成为一个非常适合个人和小型企业进行私有化部署的选择。接下来,我们将介绍如何使用EMQX搭建物联网服务器,并与设备端进行对接,确保系统能够顺利运行。

私有化部署能为企业提供更高的数据安全性和隐私控制。所有的数据存储、处理和传输均在本地完成,避免了将敏感数据上传到云平台的风险。开发者可以完全控制数据的流动和存储路径,实施更严格的安全措施,如加密存储和访问权限控制,从而确保数据的安全性和隐私性。

私有化部署为物联网系统提供了更高的定制化能力。云平台虽然提供了便捷的服务,但在很多情况下,用户对服务的定制需求较高,如通信协议、设备接入数量、消息路由等方面。私有化部署允许开发者自由配置服务器和系统,能够更好地满足特定应用场景的需求。此外,私有服务器还可以与企业内部的其他系统(如数据库、ERP系统等)进行深度集成,提高了系统的灵活性和效率。

私有化部署物联网服务器能够有效降低长期运营成本。公共云平台通常采用按需收费的模式,随着设备接入数量的增加和数据流量的积累,运营成本会持续上升。相反,私有化部署仅需承担一次性硬件投资和基础设施维护费用,避免了云服务费用的不断增长,从而使得系统运营成本更加可控,特别是对于大规模的物联网部署,私有化方案可以大大降低长期的投入。

私有化部署还为企业提供了完全的控制权。与云平台的标准化服务不同,私有化部署允许开发者全面掌握系统配置和管理权限。例如,开发者可以根据需要调整MQTT消息的处理规则、修改设备认证机制或改变数据存储方案。

对于某些行业,私有化部署也有助于符合数据合规性和法规要求。某些领域(如金融、医疗等)对数据存储和传输有着严格的规定,私有化部署能够确保企业在符合法规的前提下管理和存储数据,避免将敏感信息存储到公共云中而带来的合规风险。

在后续部分,将详细描述如何在本地服务器上安装和配置EMQX,如何通过MQTT协议连接设备端进行数据交互,如何使用数据库存储采集的数据,以及如何实现设备的远程控制和数据可视化。


5.1 Linux下安装EMQX

本章节将介绍如何在 Ubuntu 系统中下载安装并启动 EMQX。

支持的 Ubuntu 版本:

  • Ubuntu 22.04

  • Ubuntu 20.04

  • Ubuntu 18.04

5.1.1 官网地址

链接:https://www.emqx.io/docs/zh/v5.2/deploy/install-ubuntu.html

5.1.2 通过Apt源安装

EMQX 支持通过 Apt 源安装,免除了用户需要手动处理依赖关系和更新软件包等的困扰,具有更加方便、安全和易用等优点。

在命令行终端,复制下面的命令过去,按下回车键。

【1】通过以下命令配置 EMQX Apt 源:

curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash

【2】运行以下命令安装 EMQX:

sudo apt-get install emqx

【3】运行以下命令启动 EMQX:

sudo systemctl start emqx


过程如下:

image-20231108111924723


image-20231108112053540



5.1.3 EMQX常用的命令

sudo systemctl emqx start    启动
sudo systemctl emqx stop     停止
sudo systemctl emqx restart  重启 




5.2 配置EMQX服务器

5.2.1 登录EMQX内置管理控制台

EMQX 提供了一个内置的管理控制台,即 EMQX Dashboard。方便用户通过 Web 页面就能轻松管理和监控 EMQX 集群,并配置和使用所需的各项功能。

在浏览器里输入: http://122.112.225.194:18083 就可以访问EMQX的后台管理页面。可以管理以连接的客户端或检查运行状态。

这里面的IP地址,就是自己ECS云服务器的公网IP地址。


打开浏览器后,输入地址后打开的效果:

image-20231108112216658


默认用户名和密码:

用户名:admin
密码:public

第一次登录会提示你修改新密码,如果不想设置,也可以选择跳过(公网服务器部署,还是要修改密码安全些)。


下面修改新密码:

image-20231108112320173

登录成功的页面显示如下:

image-20231108112412396



5.2.2 MQTT配置

这里可以配置MQTT的一些参数,根据自己的需求进行配置。

image-20231108112603617



5.2.3 测试MQTT通信

新建一个客户端,点击连接。

image-20231108112632462


连接之后,然后点击订阅,和发布,如果下面消息能正常的接收。说明MQTT服务器通信是已经正常,没问题了。

并且在这个页面也可以看到主题发布主题订阅的格式。

image-20231108112651564



5.2.4 MQTT客户端登录服务器测试

接下来就打开我们自己的MQTT客户端登录MQTT服务器进行测试数据的通信。

端口选择: 1883

根据软件参数填入参数,登录,进行主题的发布和订阅。


image-20231108112828605


说明: 目前还没有配置客户端认证,现在只要IP和端口输入正确,MQTT三元组可以随便输入,都可以登录上服务器的,服务器没有对三元组做校验。

EMQ X 默认配置中启用了匿名认证,任何客户端都能接入 EMQX。没有启用认证插件或认证插件没有显式允许/拒绝(ignore)连接请求时,EMQX 将根据匿名认证启用情况决定是否允许客户端连接。


然后打开EMQX的管理后台,可以看到我们的设备已经登录服务器了,名字为test1

image-20231108112900540



在订阅主题的页面也可以看到我们客户端设备订阅的主题。

image-20231108112938585



5.2.5 客户端认证配置

EMQX 默认配置中启用了匿名认证,任何客户端都能接入 EMQX。没有启用认证插件或认证插件没有显式允许/拒绝(ignore)连接请求时,EMQX 将根据匿名认证启用情况决定是否允许客户端连接。

在正式产品里肯定是要启用认证的,不然任何设备都能接入。

下面就介绍如何配置 客户端认证。

【1】打开客户端认证页面

image-20231107160746380


【2】选择密码认证

image-20231107160844450


【3】选择内置数据库

image-20231107160916912


【4】设置认证方式(都可以默认,不用改),直接点击创建。

image-20231107161002220


【5】创建成功后,点击用户管理

image-20231107161043692


【6】添加用户

image-20231107161154596


image-20231107161254779


【7】添加成功

image-20231107161317252


【8】添加完毕之后,打开MQTT客户端可以进行测试。

登录的时候,MQTT用户名和密码必须输入正确,按照上一步添加的信息进行如实填写,否则是无法登录服务器的。

image-20231108113054185



5.2.6 客户端授权配置

客户端授权页面可以配置每个客户端(设备)的主题发布,订阅权限。限制它是否可以发布主题,订阅主题。 如果有需要就可以进行配置。


http://127.0.0.1:18083/#/authorization/detail/built_in_database?tab=users

【1】创建数据源

image-20231107153705954


【2】选择内置数据库

image-20231107153725972


【3】完成创建

image-20231107153746654


【4】点击权限管理

image-20231107153810651


【5】选择客户端ID,点击添加

image-20231107153902413


【6】配置权限

image-20231107161803875


5.2.7 数据转发(集成)

在集成选项里,可以对设备数据处理。 比如:转发到自己的HTTP服务器,转发到自己其他的MQTT服务器,创建规则,某些事件触发某些动作等等。

image-20231107225638965


选择数据桥接。

可以把数据发送端自己的HTTP服务器,或者发送到其他的MQTT服务器。

image-20231107225815739


选择HTTP服务 (如果自己有HTTP服务器,可以将数据转发给自己的HTTP服务器)。

image-20231107225942506




5.3 MQTT客户端消息互发测试

5.3.1 添加2个设备

为了方便测试设备间互相订阅主题,数据收发,在客户端认证页面至少添加2个设备。我这里分别添加了test1test2

image-20231107163706657


5.3.2 设备间测试

设备A订阅设备B的主题,设备B订阅设备A的主题,实现数据互发。

image-20231108113409036




设备A的MQTT信息:

MQTT服务器地址:122.112.225.194
MQTT服务器端口号:1883
MQTT客户端ID:AAA
MQTT用户名:test1
MQTT登录密码:12345678

订阅主题:BBB/#
发布主题:AAA/1
发布的消息:{ "msg": "我是AAA设备" }


设备B的MQTT信息:

MQTT服务器地址:122.112.225.194
MQTT服务器端口号:1883
MQTT客户端ID:BBB
MQTT用户名:test2
MQTT登录密码:12345678

订阅主题:AAA/#
发布主题:BBB/1
发布的消息:{ "msg": "我是BBB设备" }






六、总结

本项目设计并实现了基于物联网的智慧菜地种植系统,通过集成多种传感器和通信模块,实现了菜地环境的智能化监控与自动化管理。系统通过STM32F103RCT6主控芯片控制各个硬件模块,利用4G网络上传实时数据至华为云物联网平台,并通过Web界面和微信小程序提供远程监控和控制功能。

在硬件方面,项目结合了多种传感器,如SHT30温湿度传感器、BH1750光照强度传感器和RS485接口的土壤检测仪,确保了菜地环境的全面监测。系统能够实时采集温度、湿度、光照强度、土壤水分及养分含量等重要数据,帮助用户精准掌握菜地的生长环境,从而实现科学的种植管理。

在功能实现上,项目支持自动灌溉控制,能够根据土壤湿度自动启动或关闭灌溉系统,提高了水资源的利用效率;同时,通过4G模块与云平台的连接,确保了数据的实时上传和远程控制的便利性。此外,系统还支持视频监控,用户可随时通过手机或PC端查看菜地的实时视频,进一步提升了远程管理的便捷性和安全性。

通过本项目的开发与实现,证明了物联网技术在农业领域中的广泛应用潜力,特别是在智慧农业和精细化管理方面。未来,随着传感器技术和通信技术的进一步发展,本系统可以进一步扩展,加入更多的智能化功能,如作物生长预测、病虫害监测等,为现代农业提供更多的智能化解决方案。

本项目不仅为菜地的智能化管理提供了一种可行的方案,也为物联网技术在农业中的深入应用提供了实践基础。随着技术的不断进步,智慧农业将成为推动农业现代化的重要力量,促进资源的合理利用和农业生产效益的提升。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。