基于物联网设计的疫苗冷链物流监测系统
一、前言
1.1 项目开发背景
随着全球经济的发展和物流行业的不断创新,疫苗和生物制品的运输要求变得越来越高。尤其是疫苗的冷链物流,温度、湿度等环境因素的控制直接关系到疫苗的质量和效力,因此高效、可靠的冷链监控系统显得尤为重要。冷链物流系统通常用于保持药品、食品等易腐物品的稳定运输环境,对于疫苗的运输尤为关键,因为不当的温湿度变化可能导致疫苗失效,从而影响公众健康。
传统的冷链物流监测方法主要依赖人工记录和定期检查,这不仅增加了人工成本,还存在检测盲区和延时问题。为了应对这一挑战,物联网技术为冷链物流提供了更加精准、实时的数据监控手段。通过传感器技术和无线通信,物流过程中每一环节的环境数据都能够实时采集并上传至云平台,进行远程监控和控制。这种高效的信息化管理方式,不仅能够提高疫苗运输过程中的安全性,还能提升物流管理效率,减少人为疏忽和延误。
本项目设计一个基于物联网的疫苗冷链物流监测系统,采用温湿度传感器、震动传感器、GPS定位模块等硬件设备,结合STM32F103RCT6主控芯片、4G通信模块、云平台等技术,打造一个实时监测、自动控制和远程管理的系统。该系统能够自动监测和调节运输过程中的温度、湿度,并及时报警提醒驾驶员,确保疫苗在运输过程中的质量和安全。同时,系统支持通过手机APP和后端服务器进行数据查看和历史数据分析,进一步增强了系统的可靠性和智能化水平。
随着全球冷链物流需求的日益增加,尤其是在疫苗运输领域,创新的物联网冷链监测解决方案成为了保障公共健康的重要工具。通过将物联网技术与传统冷链物流管理相结合,可以实现实时数据采集、远程控制和智能化管理,为疫苗冷链物流提供全方位、无死角的保障。这对于提升疫苗运输的可靠性和效率,降低疫苗浪费和风险,具有重要的现实意义和广泛的应用前景。
1.2 设计实现的功能
(1)温度监测与控制
通过温度传感器实时采集运输环境中的温度数据。当检测到温度超过预设的安全阈值时,系统自动启动制冷风机进行降温,确保运输环境保持在疫苗所需的适宜温度范围内。
(2)湿度监测与控制
通过湿度传感器实时采集运输环境中的湿度数据。当湿度值低于设定的正常范围时,系统自动启用加湿器进行加湿,保证运输环境的湿度符合疫苗运输要求。
(3)震动监测与警报
系统集成震动传感器,实时监测运输过程中可能出现的震动情况。当震动强度超出设定值时,系统会通过蜂鸣器发出警报,提醒驾驶员注意行驶中的震动情况,并采取必要的减速或避免剧烈颠簸。
(4)温湿度值设置与调节
通过硬件按键,用户可以手动设置温度和湿度的安全阈值。当运输过程中温度或湿度变化超过设定范围时,系统会启动自动调节机制。
(5)环境数据实时显示
系统配备小尺寸的1.44寸显示屏,实时显示当前运输环境的温度、湿度和震动等重要数据。驾驶员可以直观地了解运输环境的当前状态。
(6)无线数据传输与远程监控
采用4G模块将传感器采集的实时数据无线传输到云平台,并通过手机APP进行远程监控。用户可以在APP端查看当前温湿度数据,及时获取运输环境的状态信息,确保运输过程中的数据透明和可控。
(7)历史数据存储与查询
通过云平台保存传感器采集的历史数据。用户可以通过手机APP或后端服务器查询历史数据,进行数据分析和趋势预测,从而优化运输过程中的环境管理。
(8)GPS定位与实时跟踪
系统集成GPS模块,实时跟踪运输车辆的位置,获取车辆的经纬度信息,并将位置数据上传至云平台。用户通过手机APP可以实时查看车辆的当前位置,确保运输过程的可追溯性。
(9)数据上云与平台管理
系统支持将采集的数据通过4G模块上传到华为云物联网平台,实现数据存储和管理。云平台可以展示实时数据,并支持历史数据分析与可视化展示,帮助管理人员全面监控冷链运输过程。
(10)后端服务器与可视化网页
系统搭建Python后端服务器,接收来自云平台的数据,并设计HTML前端页面进行展示。用户可以通过电脑或手机浏览器查看环境数据,进行实时控制和历史数据查询,支持局域网和公网访问。
(11)系统报警与异常处理
当温度、湿度或震动等环境指标异常时,系统会自动触发报警机制,通过蜂鸣器、APP通知等方式提醒驾驶员或管理人员采取适当的处理措施,防止疫苗运输过程中发生质量问题。
(12)自动化控制与人工干预
在正常运输过程中,系统会根据实时数据自动调节温湿度和震动状态。如果出现无法自动解决的问题,驾驶员或管理人员可通过APP手动控制设备(如风机、加湿器等)进行调整,确保运输环境始终符合要求。
1.3 项目硬件模块组成
(1)主控芯片(STM32F103RCT6)
STM32F103RCT6作为项目的核心控制单元,负责所有传感器数据的采集、处理和控制命令的执行。它通过与各个外部模块的通信,协调各个子系统的工作,确保整个系统的正常运行。
(2)温湿度传感器(SHT30)
SHT30传感器用于实时采集运输环境中的温度和湿度数据,并将其传输至主控芯片。该传感器具有高精度和稳定性,适用于需要精确环境监控的冷链物流系统。
(3)震动传感器
震动传感器用于监测运输过程中的震动情况,当震动超过设定阈值时,系统会发出警报,提醒驾驶员注意行驶状态。它能有效避免运输中的剧烈颠簸对疫苗质量造成影响。
(4)4G通信模块(Air724UG)
Air724UG 4G模块用于实现数据的无线传输,将传感器采集的数据上传至云平台。通过4G模块,系统能够随时进行远程监控和控制,确保冷链运输的实时数据不间断传输。
(5)GPS定位模块(中科微ATGM336H-GPS模块)
GPS模块用于实时获取运输车辆的位置数据,并将经纬度信息上传至云平台。通过GPS定位,用户可以随时查看车辆的实时位置,确保运输过程的可追溯性。
(6)显示屏(1.44寸显示屏)
1.44寸小尺寸显示屏用于实时显示运输环境的关键数据,如温度、湿度、震动状态等。它为驾驶员提供了一个直观的界面,便于在驾驶过程中随时查看运输环境的状态。
(7)蜂鸣器
蜂鸣器用于在发生异常情况时发出声音警报。通过蜂鸣器,系统能够在温度、湿度或震动等环境数据异常时及时提醒驾驶员采取措施,从而确保疫苗运输的安全性。
(8)加湿器
加湿器用于自动调节运输环境的湿度。当湿度值低于设定值时,加湿器会自动启用,确保运输环境始终维持在适宜的湿度范围,避免湿度过低影响疫苗质量。
(9)制冷风机
制冷风机用于自动调节运输环境的温度。当检测到温度超出设定的安全范围时,风机会自动启动进行降温,以确保运输过程中疫苗存储在适宜的低温环境中。
(10)按键模块
按键模块用于手动设置温度、湿度等环境参数的阈值。用户可以通过按键方便地调节和设定监控的标准值,以适应不同类型疫苗的运输需求。
(11)电源模块
电源模块为整个系统提供稳定的电力支持。它需要支持4G模块、传感器、蜂鸣器等各个硬件设备的功耗需求,并确保系统在运输过程中的持续稳定运行。
(12)传感器接口电路
传感器接口电路用于连接各类传感器(温湿度传感器、震动传感器等)与主控芯片。它们提供电气连接和数据传输通道,确保数据从传感器正确、及时地传送至主控芯片进行处理。
(13)云平台通信模块(MQTT协议)
云平台通信模块用于通过MQTT协议将数据上传到华为云物联网平台,实现实时监控、数据存储和历史数据分析。该模块支持与后端服务器的通信,确保数据的远程传输与访问。
1.4 设计思路
本项目的设计思路主要围绕如何实现疫苗运输过程中的环境监控与控制,确保疫苗在运输过程中的温湿度、震动等关键因素始终处于安全范围内,最大程度地保证疫苗的质量和效力。设计思路分为硬件选择、数据采集与处理、控制策略、无线通信与远程监控等几个主要部分。
在硬件选择上,本项目采用了STM32F103RCT6主控芯片作为核心控制单元,具备较强的处理能力和丰富的外设接口,能够高效地完成各类传感器的数据采集和控制指令的执行。为了精准监测运输环境中的温湿度情况,选择了SHT30温湿度传感器,该传感器具有高精度、低功耗、响应速度快等特点,适合用于对冷链物流过程中的环境进行精细监控。对于震动检测,选用了震动传感器,能够实时捕捉到运输中的震动状态,尤其在运输过程中发生剧烈震动时,系统将立即触发报警机制。此外,4G通信模块Air724UG用于实现数据的远程无线传输,而GPS模块则能够为系统提供实时的位置信息,便于追踪车辆的具体位置。
数据采集和处理是系统设计中的核心部分。通过各类传感器采集温度、湿度、震动等环境数据后,主控芯片STM32将负责对这些数据进行实时处理和分析。一旦发现环境数据超出设定的安全范围,系统会根据设定的控制策略做出响应。例如,当温度过高时,系统会自动启动制冷风机进行降温;当湿度过低时,加湿器会自动启用,补充环境湿度;当震动过于剧烈时,蜂鸣器会发出警报,提醒驾驶员注意行驶情况。通过这样的实时控制,系统可以确保疫苗运输过程中的环境始终处于安全状态。
为了实现远程监控和管理,系统采用了4G模块与华为云物联网平台进行数据交互。通过MQTT协议,系统将实时数据上传至云平台,确保用户可以通过手机APP或计算机终端远程查看运输环境的温湿度、震动等数据,并进行实时控制。用户还可以通过云平台查询历史数据,进行趋势分析和数据回溯,以便及时发现潜在的问题并进行调整。与此同时,云平台与本地服务器之间的通信,确保了数据的高效存储与展示。
系统还具备灵活的控制方式。驾驶员可以通过按键模块手动设置和调整温度、湿度等环境参数的阈值,适应不同类型疫苗的运输需求。在自动模式下,系统能够根据实时数据进行自动调节;而在人工干预模式下,驾驶员或管理人员可以通过APP或显示屏直接调整设备的工作状态。
整个系统的设计充分考虑了其稳定性、可靠性和易用性。所有的硬件模块和软件算法均经过优化,确保在复杂的运输环境下能够稳定运行。此外,系统支持在不同的网络环境下进行远程访问和控制,无论是在局域网还是公网环境下,都能够保证数据的准确传输和实时监控。
本项目的设计思路是在物联网技术和嵌入式硬件的支持下,通过高精度传感器和智能控制策略,实现对疫苗运输过程的全面监控与管理,确保疫苗冷链物流的安全、可靠与高效。
1.5 系统功能总结
功能模块 | 功能描述 |
---|---|
温度监测与控制 | 实时监测运输环境中的温度,当温度超过设定值时,自动启动制冷风机进行降温。 |
湿度监测与控制 | 实时监测运输环境中的湿度,当湿度低于设定值时,自动启动加湿器进行加湿,保证环境湿度适宜。 |
震动监测与报警 | 实时监测运输中的震动情况,当震动超出设定阈值时,通过蜂鸣器发出警报,提醒驾驶员减少震动。 |
温湿度设置功能 | 通过按键模块手动设置温度和湿度的安全阈值,允许用户根据不同需求进行调整。 |
环境数据实时显示 | 在显示屏上实时显示温度、湿度、震动等关键环境数据,供驾驶员查看当前运输环境的状态。 |
无线数据传输 | 通过4G模块将环境数据实时上传至云平台,支持手机APP和计算机端进行远程监控。 |
历史数据查询 | 支持通过云平台保存和查询历史数据,便于数据分析和运输过程中环境趋势的回溯。 |
GPS定位与追踪 | 实时获取车辆位置,显示车辆的经纬度信息,确保运输过程的可追溯性,并支持通过云平台实时查看车辆位置。 |
数据上云 | 将所有环境数据通过MQTT协议上传至华为云物联网平台,实现数据存储、展示和分析。 |
后台数据展示 | 通过Python后端服务器,设计HTML前端页面,将数据通过可视化网页展示,支持电脑和手机浏览器访问。 |
报警与异常处理 | 当温度、湿度、震动等环境参数异常时,系统会发出声音或APP通知报警,提醒驾驶员采取必要的处理措施。 |
手动与自动控制 | 系统支持自动控制模式,根据实时环境数据进行调整,也支持手动控制,允许驾驶员或管理人员进行干预调整。 |
1.6 开发工具的选择
STM32的编程语言选择C语言,C语言执行效率高,C语言编译出来的可执行文件最接近于机器码,汇编语言执行效率最高,但是汇编的移植性比较差,目前在一些操作系统内核里还有一些低配的单片机使用的较多,平常的单片机编程还是以C语言为主。C语言的执行效率仅次于汇编,语法理解简单、代码通用性强,也支持跨平台,在嵌入式底层、单片机编程里用的非常多,当前的设计就是采用C语言开发。
开发工具选择Keil,keil是一家世界领先的嵌入式微控制器软件开发商,在2015年,keil被ARM公司收购。因为当前芯片选择的是STM32F103系列,STMF103是属于ARM公司的芯片构架、Cortex-M3内核系列的芯片,所以使用Kile来开发STM32是有先天优势的,而keil在各大高校使用的也非常多,很多教科书里都是以keil来教学,开发51单片机、STM32单片机等等。目前作为MCU芯片开发的软件也不只是keil一家独大,IAR在MCU微处理器开发领域里也使用的非常多,IAR扩展性更强,也支持STM32开发,也支持其他芯片,比如:CC2530,51单片机的开发。从软件的使用上来讲,IAR比keil更加简洁,功能相对少一些。如果之前使用过keil,而且使用频率较多,已经习惯再使用IAR是有点不适应界面的。
1.7 参考文献
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】中科微ATGM336H-GPS模块
中科微ATGM336H-GPS模块是一款高性能、低功耗的全球定位模块,专为卫星定位导航应用设计。该模块集成了GNSS基带处理器和RF接收器,支持GPS、GLONASS、BDS(北斗)等多种卫星系统的定位信号,能够实现快速精准的定位,并提供稳定可靠的位置、速度和时间数据。ATGM336H模块广泛应用于车辆定位、物流跟踪、无人机导航、智能穿戴设备、户外运动设备和物联网等领域。
ATGM336H模块采用小巧的LCC封装,尺寸为16mm x 12.2mm x 2.3mm,便于集成到各种紧凑型设备中。模块内置高灵敏度接收芯片,具有-165dBm的高灵敏度,即使在复杂环境下也能快速捕获和跟踪卫星信号。其冷启动时间在开阔地带一般小于30秒,热启动时间约为1秒,重捕获时间小于1秒,使其在车辆移动和各种快速切换的场景下表现出色,定位精度可达2.5米。
该模块支持多种工作模式,以满足不同应用的功耗要求。它不仅可以在普通模式下连续定位,还支持周期性模式和节电模式,通过关闭部分功能或降低数据输出频率来减少功耗,适合电池供电的便携式设备。其最低功耗在微安级别,能够显著延长电池续航时间,使其成为移动设备的理想选择。
ATGM336H-GPS模块的接口丰富,支持UART、I2C、SPI等多种通信接口,方便与主控MCU进行数据交换。模块提供的标准NMEA协议输出和二进制格式数据能够直接对接多种导航应用程序。此外,模块还具有内置的天线检测功能和动态干扰抑制技术,有助于在有较强电磁干扰的环境中保持定位精度,并能实时检测和报告天线状态,进一步提高定位可靠性。
为了提高用户体验和简化开发过程,中科微为ATGM336H模块提供了完善的开发手册和技术支持,便于开发者快速上手并将其应用到多种设备中。此外,模块还支持多卫星系统协同定位的功能,通过融合GPS、BDS、GLONASS等卫星数据,提高在市区、高山、森林等卫星信号受限环境下的定位精度和稳定性,使其适用于复杂环境的高精度定位需求。
二、硬件选型(搭建模型参考)
如果大家想自己搭建模型,完成这个项目的功能测试。
那么可以看参考下面的部分硬件模块选型。
在本项目中,硬件选型是确保疫苗冷链物流监测系统稳定运行的关键。该系统的硬件组成包括主控芯片、传感器模块、通信模块、显示模块、控制模块以及电源模块等,下面是各个硬件模块的详细选型和描述:
1. 主控芯片(STM32F103RCT6)
STM32F103RCT6是本系统的核心控制单元,基于ARM Cortex-M3架构,提供强大的运算能力和丰富的外设接口,能够支持温湿度传感器、震动传感器、显示屏、4G模块等多个设备的并行工作。其高效的处理能力能够实时处理传感器数据并进行控制输出,适用于嵌入式物联网应用。
2. 温湿度传感器(SHT30)
SHT30温湿度传感器用于实时采集运输环境中的温度和湿度数据。该传感器具有较高的测量精度,响应速度快,适合精确监测冷链运输环境的温湿度,确保疫苗运输过程中环境条件符合标准。
3. 震动传感器
震动传感器用于监测运输过程中的震动情况,尤其是当运输环境发生剧烈震动时,系统能够及时触发警报,提醒驾驶员注意行驶状态。这是冷链物流监控系统中的一个关键安全功能,避免因过度震动影响疫苗的质量。
4. 4G通信模块(Air724UG)
Air724UG 4G模块用于数据的无线传输,支持将采集的温湿度、震动等数据通过4G网络上传至云平台。该模块支持高速数据传输,能够确保系统在任何时间和地点都能实时上传数据,并通过APP进行远程监控和控制。
5. GPS定位模块(中科微ATGM336H-GPS模块)
GPS模块提供实时的车辆位置数据,能够精确地获取车辆的经纬度信息,并上传到云平台。通过GPS定位,系统能够在地图上实时显示运输车辆的位置,确保运输过程的可追溯性和监控。
6. 显示屏(1.44寸OLED显示屏)
1.44寸OLED显示屏用于在驾驶室内实时显示环境数据,包括温度、湿度、震动等关键监控数据。OLED屏具有高亮度和低功耗的优点,适合在车载环境中使用,且显示清晰,驾驶员可以直观地查看运输环境状态。
7. 蜂鸣器
蜂鸣器用于在系统检测到异常情况时发出警报。当温度、湿度或震动等数据超出预设的安全范围时,蜂鸣器将发出声音提醒,警告驾驶员或工作人员采取必要的纠正措施。蜂鸣器是系统的重要警报元件。
8. 加湿器
加湿器用于当运输环境湿度低于设定值时,自动增加环境湿度。它确保冷链运输过程中,尤其是需要特定湿度条件的疫苗能够得到良好的存储环境,从而避免疫苗质量受湿度过低的影响。
9. 制冷风机
制冷风机用于当温度超出设定的安全范围时,自动启动进行降温,确保运输过程中疫苗始终处于适宜的温度环境。制冷风机的选择需要根据实际需求,保证能够在运输过程中快速降低温度,以适应不同环境的要求。
10. 按键模块
按键模块用于手动设置和调整温湿度阈值,允许驾驶员或操作员根据不同的运输需求,快速修改系统的温湿度标准。它为系统提供了人工干预的接口,增加了操作灵活性。
11. 电源模块
电源模块为整个系统提供稳定的电力供应,确保系统在运输过程中持续可靠地工作。电源模块需要支持4G模块、传感器、蜂鸣器等硬件的功耗需求,并具有良好的电源管理能力。
12. 数据存储模块(可选)
为了实现历史数据查询和分析,本系统可以配备数据存储模块,如SD卡模块或EEPROM。数据存储模块用于存储重要的环境数据,便于后期的查阅和分析,尤其是在网络不稳定或无信号的情况下,仍能保证数据的本地记录。
13. 无线通信模块(MQTT协议)
为实现数据上传和远程控制,系统采用了MQTT协议进行无线通信。通过4G模块与华为云物联网平台进行数据交换,确保监控数据能够及时上传至云端,且通过APP实现远程控制和监控。
14. 后端服务器与可视化模块
后端服务器用于接收来自4G模块上传的数据,并将其通过API接口与前端网页进行交互。前端网页采用HTML、CSS和JavaScript等技术进行可视化展示,支持电脑和手机浏览器访问,用户可以在网页上查看实时数据、历史数据以及控制设备。
三、部署华为云物联网平台
华为云官网: https://www.huaweicloud.com/
打开官网,搜索物联网,就能快速找到 设备接入IoTDA
。
3.1 物联网平台介绍
华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助快速构筑物联网解决方案。
使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。
物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。
设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。
业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。
3.2 开通物联网服务
地址: https://www.huaweicloud.com/product/iothub.html
开通免费单元。
点击立即创建
。
正在创建标准版实例,需要等待片刻。
创建完成之后,点击详情。 可以看到标准版实例的设备接入端口和地址。
下面框起来的就是端口号
和域名
点击实例名称,可以查看当前免费单元
的配置情况。
开通之后,点击接入信息
,也能查看接入信息。 当前设备准备采用MQTT协议接入华为云平台,这里可以看到MQTT协议的地址和端口号等信息。
总结:
端口号: 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=44117.78.5.125 的 Ping 统计信息:数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):最短 = 37ms,最长 = 37ms,平均 = 37msC:\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)创建产品
(2)填写产品信息
根据自己产品名字填写,下面的设备类型选择自定义类型。
(3)产品创建成功
创建完成之后点击查看详情。
(4)添加自定义模型
产品创建完成之后,点击进入产品详情页面,翻到最下面可以看到模型定义。
模型简单来说: 就是存放设备上传到云平台的数据。
你可以根据自己的产品进行创建。
比如:
烟雾可以叫 MQ2
温度可以叫 Temperature
湿度可以叫 humidity
火焰可以叫 flame
其他的传感器自己用单词简写命名即可。 这就是你的单片机设备端上传到服务器的数据名字。
先点击自定义模型。
再创建一个服务ID。
接着点击新增属性。
3.4 添加设备
产品是属于上层的抽象模型,接下来在产品模型下添加实际的设备。添加的设备最终需要与真实的设备关联在一起,完成数据交互。
(1)注册设备
(2)根据自己的设备填写
(3)保存设备信息
创建完毕之后,点击保存并关闭,得到创建的设备密匙信息。该信息在后续生成MQTT三元组的时候需要使用。
(4)设备创建完成
(5)设备详情
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
业务流程:
(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
对于设备而言,一般会订阅平台下发消息给设备 这个主题。
设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。
如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。
以当前设备为例,最终订阅主题的格式如下:
$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
根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:
发布的主题格式:
$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
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
(2)生成MQTT三元组
华为云提供了一个在线工具,用来生成MQTT鉴权三元组: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。
下面是打开的页面:
填入设备的信息: (上面两行就是设备创建完成之后保存得到的)
直接得到三元组信息。
得到三元组之后,设备端通过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客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。
(2)打开网页查看
完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。
点击详情页面,可以看到上传的数据:
到此,云平台的部署已经完成,设备已经可以正常上传数据了。
(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】获取项目凭证 ** 点击左上角用户名,选择下拉菜单里的我的凭证
项目凭证:
28add376c01e4a61ac8b621c714bf459
【2】创建IAM用户
鼠标放在左上角头像上,在下拉菜单里选择统一身份认证
。
点击左上角创建用户
。
创建成功:
【3】创建完成
用户信息如下:
主用户名 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
在线调试接口,可以请求影子接口,了解请求,与返回的数据格式。
调试完成看右下角的响应体,就是返回的影子数据。
设备影子接口返回的数据如下:
{"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写代码访问此链接,获取影子数据,完成上位机开发。
链接如下:
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_bundleINCLUDEPATH += /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);// 初始化libcurlCURL *curl;CURLcode res;QByteArray responseData; // 用于存储响应数据curl_global_init(CURL_GLOBAL_DEFAULT);curl = curl_easy_init();if (curl) {// 设置访问URLconst 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>"); // 这里需要替换为你的实际 tokencurl_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_bundleSOURCES += 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();// 解析 JSONcJSON *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;}}// 解析 versioncJSON *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设备端代码设计
以下是一个示例的 main.c
代码,将通过 4G 模块与华为云物联网平台进行通信,实现温湿度、震动、GPS 数据的采集与上传。
- 使用 STM32F103RCT6 作为主控芯片。
- 温湿度传感器使用 SHT30。
- GPS 模块使用中科微 ATGM336H-GPS 模块。
- 震动传感器是一个简单的数字输入传感器。
- 4G 模块(Air724UG)通过 UART 进行通信。
- 使用 MQTT 协议将数据上传至华为云物联网平台。
以下是 main.c
代码示例: 这是框架代码-伪代码。
#include "stm32f1xx_hal.h"
#include "mqtt_client.h"
#include "sht30.h"
#include "gps.h"
#include "vibration_sensor.h"
#include "air724ug.h"
#include "wifi_module.h"// 定义数据结构
typedef struct {float temperature;float humidity;char gps_latitude[20];char gps_longitude[20];char vibration_status[20];
} sensor_data_t;// 全局变量
sensor_data_t current_data;
MQTT_Client mqtt_client;
UART_HandleTypeDef huart1; // 4G模块的串口配置
UART_HandleTypeDef huart2; // GPS模块的串口配置
I2C_HandleTypeDef hi2c1; // SHT30温湿度传感器的I2C配置// 定义函数原型
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_I2C1_Init(void);
void MX_UART1_Init(void);
void MX_UART2_Init(void);
void MX_WiFi_Init(void);
void MX_MQTT_Init(void);
void get_sensor_data(void);
void send_data_to_cloud(void);// 主函数
int main(void)
{// 初始化硬件抽象层(HAL)HAL_Init();SystemClock_Config();// 初始化外设MX_GPIO_Init();MX_I2C1_Init();MX_UART1_Init();MX_UART2_Init();MX_WiFi_Init();MX_MQTT_Init();// 初始化传感器SHT30_Init(&hi2c1);GPS_Init(&huart2);Vibration_Sensor_Init();// 连接到WiFiWiFi_Connect();// MQTT连接到云平台if (MQTT_Connect(&mqtt_client) != MQTT_SUCCESS) {// 连接失败,进入错误处理流程while (1);}// 主循环while (1){// 获取传感器数据get_sensor_data();// 将数据发送到云平台send_data_to_cloud();}
}// 获取传感器数据
void get_sensor_data(void)
{// 获取温湿度数据if (SHT30_ReadData(&hi2c1, ¤t_data.temperature, ¤t_data.humidity) != HAL_OK) {// 如果读取失败,给默认值current_data.temperature = 25.0f;current_data.humidity = 50.0f;}// 获取GPS数据GPS_ReadData(&huart2, current_data.gps_latitude, current_data.gps_longitude);// 获取震动数据if (Vibration_Sensor_Read() == 1) {strcpy(current_data.vibration_status, "High");} else {strcpy(current_data.vibration_status, "Normal");}
}// 发送数据到云平台
void send_data_to_cloud(void)
{// 构造上传的数据包char payload[256];sprintf(payload, "{\"temperature\":%.2f, \"humidity\":%.2f, \"vibration_status\":\"%s\", \"gps_latitude\":\"%s\", \"gps_longitude\":\"%s\"}",current_data.temperature, current_data.humidity, current_data.vibration_status, current_data.gps_latitude, current_data.gps_longitude);// 使用MQTT协议发送数据if (MQTT_Publish(&mqtt_client, "device/data", payload) != MQTT_SUCCESS) {// 发送失败,进行错误处理}
}// 系统时钟配置
void SystemClock_Config(void)
{// 配置系统时钟为 72 MHzRCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {// 如果配置失败,进入错误处理流程while (1);}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {// 如果配置失败,进入错误处理流程while (1);}
}// GPIO初始化
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配置
}// I2C1初始化
void MX_I2C1_Init(void)
{hi2c1.Instance = I2C1;hi2c1.Init.ClockSpeed = 100000;hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;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) {// 初始化失败,进入错误处理流程while (1);}
}// UART1初始化 (用于4G模块)
void MX_UART1_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.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.Mode = UART_MODE_TX_RX;if (HAL_UART_Init(&huart1) != HAL_OK) {// 初始化失败,进入错误处理流程while (1);}
}// UART2初始化 (用于GPS模块)
void MX_UART2_Init(void)
{huart2.Instance = USART2;huart2.Init.BaudRate = 9600;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart2.Init.Mode = UART_MODE_TX_RX;if (HAL_UART_Init(&huart2) != HAL_OK) {// 初始化失败,进入错误处理流程while (1);}
}// WiFi模块初始化
void MX_WiFi_Init(void)
{}// MQTT初始化
void MX_MQTT_Init(void)
{// 配置MQTT客户端mqtt_client.broker = "mqtt://broker.huawei.com";mqtt_client.port = 1883;mqtt_client.client_id = "device_client_id";mqtt_client.username = "device_username";mqtt_client.password = "device_password";mqtt_client.connect_timeout = 10; // 超时时间mqtt_client.keep_alive_interval = 60; // 保持连接时间MQTT_Init(&mqtt_client);
}
代码说明:
初始化外设:MX_I2C1_Init()
:初始化用于与 SHT30 温湿度传感器通信的 I2C 接口。
MX_UART1_Init()
和MX_UART2_Init()
:初始化 UART 接口,用于与 4G 模块和 GPS 模块通信。MX_GPIO_Init()
:初始化 GPIO,配置其他硬件接口。MX_WiFi_Init()
:初始化 WiFi 模块,连接到网络。MX_MQTT_Init()
:初始化 MQTT 客户端,配置连接到云平台。
传感器数据获取:get_sensor_data()
函数获取温湿度、GPS 坐标和震动状态数据。
数据上传:send_data_to_cloud()
函数将传感器数据格式化为 JSON 格式,并通过 MQTT 协议上传到云平台。
MQTT通信:通过配置好的 MQTT 客户端与云平台进行通信,发送实时的传感器数据。
五、前端页面设计
这段代码是一个基于 HTML、CSS 和 JavaScript 的智慧大屏页面,用于展示疫苗冷链物流监测的数据。页面的设计目标是通过展示环境数据(如温度、湿度、震动)和 GPS 定位信息,实时监控运输过程中环境状况。
下面是静态页面,模拟数据刷新显示。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>智慧大屏 - 疫苗冷链物流监测</title><link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet"><style>/* 设置全局字体和背景 */body {font-family: 'Roboto', sans-serif;background: linear-gradient(45deg, #121212, #1c1c1c); /* 深色渐变背景 */margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;overflow: hidden;}/* 中心容器 */.container {width: 100%;height: 100%;max-width: 1920px; /* 限制最大宽度为 1920px */display: flex;justify-content: space-between;padding: 20px;box-sizing: border-box;flex-wrap: wrap;}/* 左侧卡片区域 */.left-panel {display: flex;flex-direction: column;width: 48%;justify-content: flex-start;gap: 20px;}/* 右侧地图区域 */.right-panel {width: 48%;height: 100%;display: flex;flex-direction: column;justify-content: flex-start;}/* 卡片样式 */.card {background-color: #232323;color: #fff;width: 100%;margin: 10px 0;padding: 20px;border-radius: 10px;box-shadow: 0 0 15px rgba(0, 255, 255, 0.2);text-align: center;transition: transform 0.3s ease, box-shadow 0.3s ease;height: 220px;}.card:hover {transform: scale(1.05);box-shadow: 0 0 25px rgba(0, 255, 255, 0.4);}.card h3 {font-size: 26px;margin-bottom: 10px;color: #00FFFF; /* 科技蓝 */}.card p {font-size: 18px;margin-bottom: 20px;color: #ccc;}.card .value {font-size: 32px;font-weight: bold;color: #00FF99; /* 科技绿 */}/* GPS定位样式 */.gps-map {background-color: #232323;color: white;width: 100%;margin: 10px 0;padding: 20px;border-radius: 10px;display: flex;justify-content: center;align-items: center;height: 100%;position: relative;box-shadow: 0 0 15px rgba(0, 255, 255, 0.2);}.map-overlay {background: rgba(0, 0, 0, 0.7);position: absolute;width: 100%;height: 100%;top: 0;left: 0;text-align: center;padding: 50px;border-radius: 10px;}.gps-coordinates {font-size: 24px;font-weight: 600;position: absolute;bottom: 10px;width: 100%;color: #00FFFF;}/* 页眉样式 */.header {text-align: center;margin-bottom: 30px;width: 100%;}.header h1 {color: #00FFFF;font-size: 40px;margin-bottom: 20px;}.header p {color: #ddd;font-size: 18px;}/* 页脚样式 */.footer {text-align: center;margin-top: 20px;color: #aaa;}/* 控制页面响应式布局 */@media screen and (max-width: 768px) {.container {flex-direction: column;align-items: center;}.left-panel, .right-panel {width: 100%;}.card {width: 100%;}}</style>
</head>
<body><div class="container"><div class="header"><h1>智慧大屏 - 疫苗冷链物流监测</h1><p>实时监控运输过程中的环境数据,确保疫苗运输过程符合标准</p></div><div class="left-panel"><!-- 温湿度监控卡片 --><div class="card" id="temp-card"><h3>环境温度</h3><p>当前温度</p><div class="value" id="temperature">23°C</div></div><div class="card" id="humidity-card"><h3>环境湿度</h3><p>当前湿度</p><div class="value" id="humidity">55%</div></div><div class="card" id="vibration-card"><h3>震动监测</h3><p>当前震动强度</p><div class="value" id="vibration">正常</div></div></div><div class="right-panel"><!-- GPS定位卡片 --><div class="gps-map"><div class="map-overlay"><h3>车辆当前位置</h3><p>正在运输疫苗至目标地点</p><div class="gps-coordinates" id="gps-coordinates">经度: 116.38° | 纬度: 39.90°</div></div></div></div><div class="footer"><p>© 2024 疫苗冷链监控系统 - 所有权归公司所有</p></div></div><script>// 模拟数据更新let temperatureElement = document.getElementById("temperature");let humidityElement = document.getElementById("humidity");let vibrationElement = document.getElementById("vibration");let gpsCoordinatesElement = document.getElementById("gps-coordinates");function updateData() {// 模拟温度变化let temperature = Math.random() * 10 + 20;temperatureElement.innerText = temperature.toFixed(1) + "°C";// 模拟湿度变化let humidity = Math.random() * 20 + 50;humidityElement.innerText = humidity.toFixed(1) + "%";// 模拟震动强度变化let vibrationLevels = ["正常", "轻微震动", "剧烈震动"];vibrationElement.innerText = vibrationLevels[Math.floor(Math.random() * vibrationLevels.length)];// 模拟GPS坐标变化let longitude = (Math.random() * 10 + 116).toFixed(2);let latitude = (Math.random() * 10 + 39).toFixed(2);gpsCoordinatesElement.innerText = `经度: ${longitude}° | 纬度: ${latitude}°`;}setInterval(updateData, 3000); // 每3秒更新一次数据</script></body>
</html>
以下是详细的功能说明:
1. HTML 结构
<div class="container">
- 作用:是页面的主要容器,内部包含了所有内容。使用
flex
布局将页面内容分为左右两个部分(左侧为环境数据卡片,右侧为 GPS 地图卡片)。
<div class="header">
- 作用:页面顶部的标题区域,显示页面的标题 “智慧大屏 - 疫苗冷链物流监测” 以及副标题,简要描述该页面的功能。
<div class="left-panel">
-
作用
:该区域展示环境数据卡片,包含温度、湿度和震动数据,使用
flex
布局从上到下排列。
- 温度卡片:显示当前温度。
- 湿度卡片:显示当前湿度。
- 震动卡片:显示当前震动监测状态。
<div class="right-panel">
- 作用:该区域用于显示 GPS 定位地图,展示当前疫苗运输的经纬度信息。地图下方显示当前的 GPS 坐标(经度和纬度)。
<div class="footer">
- 作用:页脚部分,提供版权信息或系统归属等简短说明。
2. CSS 样式
**全局样式 **body:
- 设置了
background
为深色渐变背景,创造出科技感的氛围。 font-family
设置为Roboto
字体,保证页面的简洁和现代感。- 使用
display: flex
和justify-content: center
来使页面内容居中显示。
容器与布局
.container:
- 设置了最大宽度
max-width: 1920px
,确保页面宽度适应大多数显示器,保证在 1080p 屏幕分辨率下全屏显示。 flex-wrap: wrap
使得页面在小屏幕下可以自动换行,适应不同尺寸的设备。
左侧卡片样式
.left-panel:
- 使用
flex-direction: column
使得环境数据卡片垂直排列。 - 设置了
gap: 20px
来使卡片之间有一定的间距。
右侧地图样式
.right-panel:
- 通过
flex-direction: column
保持地图区域的整体布局,确保右侧的地图区域与左侧数据区域并排显示。 position: relative
为了定位地图区域上的叠加内容(如 GPS 坐标)。
卡片样式
.card:
- 设置了卡片的背景色、内边距、圆角和阴影,使其看起来更为现代化和有层次感。
transition
用于设置卡片的动画效果,卡片在鼠标悬停时会放大并且增加阴影,增强交互感。- 卡片内容的标题、数值和描述有不同的字体大小和颜色,增强信息的可读性和视觉层次感。
地图样式
.gps-map和 .map-overlay:
- 地图区域使用
flex
居中显示地图内容,并使用半透明的map-overlay
覆盖在地图上方,显示 GPS 坐标等信息。
响应式设计
- 在小屏幕设备(如手机、平板)上,通过设置
@media screen and (max-width: 768px)
,容器变为竖向布局,左右区域都占满整个屏幕宽度。卡片和地图则会依次垂直排列,适配不同尺寸的设备。
3. JavaScript 动态数据更新
模拟数据更新
updateData() 函数:
- 模拟实时更新环境数据和 GPS 坐标。
- 温度:通过
Math.random()
随机生成 20°C 到 30°C 之间的温度值。 - 湿度:随机生成 50% 到 70% 之间的湿度值。
- 震动:从 [“正常”, “轻微震动”, “剧烈震动”] 随机选取一个震动状态。
- GPS 坐标:模拟生成经度和纬度,范围在 116° 到 116.5° 之间,39° 到 39.5° 之间。
数据更新间隔
setInterval(updateData, 3000);
- 每 3 秒钟调用一次
updateData
函数,动态更新温度、湿度、震动和 GPS 坐标,模拟实时监测数据。
总结
- 页面布局:
- 页面通过
flex
布局实现了左侧环境监测数据区域和右侧 GPS 地图区域的并排展示。 - 使用响应式设计,确保页面能够自适应不同设备和屏幕分辨率,特别是在 1080p 屏幕分辨率下能够全屏显示。
- 页面通过
- 动态数据展示:
- 使用 JavaScript 定时更新数据,模拟温湿度、震动监测和 GPS 坐标的实时变化。
- 科技感设计:
- 通过深色背景、渐变效果、现代化卡片样式和动态交互设计,提升了页面的科技感和现代感,适合展示智慧监控、物联网等科技类内容。
- 可扩展性:
- 页面结构和样式简单清晰,易于扩展和定制,未来可以加入更多的监控数据、功能和优化
六、总结
本项目设计并实现了一套基于物联网技术的疫苗冷链物流监测系统,保障疫苗在运输过程中的安全性和有效性。通过结合温度、湿度、震动等环境监测数据的实时采集与反馈,本系统能够及时发现并响应运输过程中可能出现的异常情况,如温湿度波动、剧烈震动等,从而采取相应的措施,例如开启制冷风机、加湿器或蜂鸣器警报,确保疫苗始终处于适宜的环境条件下。
在硬件选型方面,系统采用了STM32F103RCT6作为主控芯片,结合了SHT30温湿度传感器、GPS模块、震动传感器以及4G模块等多种外设,以实现多维度的数据采集和远程监控。4G模块与华为云物联网平台的结合,使得运输过程中的数据能够实时上传至云端,提供了更加可靠的数据存储与管理手段。
在软件部分,系统通过移动端APP和可视化网页平台进行数据展示和远程控制,用户可以随时查看运输环境的温湿度、震动状态和车辆位置,并获取历史数据进行分析。通过精准的GPS定位与实时数据更新,系统能够有效避免运输过程中可能出现的各类问题,确保疫苗冷链物流的稳定性和安全性。
通过本项目的实现,我们不仅增强了物联网在医疗物流领域中的应用,还为疫苗冷链运输提供了智能化、自动化的管理工具。未来,随着技术的发展和系统功能的不断完善,该系统将能够支持更复杂的监控需求,进一步提升疫苗运输过程中的安全性和效率,为全球疫苗供应链的稳定运行提供有力保障。
相关文章:
基于物联网设计的疫苗冷链物流监测系统
一、前言 1.1 项目开发背景 随着全球经济的发展和物流行业的不断创新,疫苗和生物制品的运输要求变得越来越高。尤其是疫苗的冷链物流,温度、湿度等环境因素的控制直接关系到疫苗的质量和效力,因此高效、可靠的冷链监控系统显得尤为重要。冷…...
RabbitMQ 多种安装模式
文章目录 前言一、Windows 安装 RabbitMq1、版本关系2、Erlang2.1、下载安装 Erlang 23.12.2、配置 Erlang 环境变量 3、RabbitMQ3.1、下载安装 RabbitMQ 3.8.93.2、环境变量3.3、启动RabbitMQ 管理插件3.3、RabbitMQ3.4、注意事项 二、安装docker1、更新系统包:2、…...
视频拼接,拼接时长版本
目录 视频较长,分辨率较大,这个效果很好,不耗用内存 ffmpeg imageio,适合视频较短 视频较长,分辨率较大,这个效果很好,不耗用内存 ffmpeg import subprocess import glob import os from nats…...
【Linux探索学习】第二十七弹——信号(一):Linux 信号基础详解
Linux学习笔记: https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言: 前面我们已经将进程通信部分讲完了,现在我们来讲一个进程部分也非常重要的知识点——信号,信号也是进程间通信的一…...
有限元分析学习——Anasys Workbanch第一阶段笔记梳理
第一阶段笔记主要源自于哔哩哔哩《ANSYS-workbench 有限元分析应用基础教程》 张晔 主要内容导图: 笔记导航如下: Anasys Workbanch第一阶段笔记(1)基本信息与结果解读_有限元分析变形比例-CSDN博客 Anasys Workbanch第一阶段笔记(2)网格单元与应力奇…...
【YOLOv11改进- 注意力机制】YOLOv11+SCSA注意力机制(2024): 最新空间和通道协同注意力,助力YOLOv11有效涨点;包含二次创新
YOLOV11目标检测改进实例与创新改进专栏 专栏地址:YOLOv11目标检测改进专栏,包括backbone、neck、loss、分配策略、组合改进、原创改进等; 本文介绍 本文给大家带来的改进内容是在YOLOv11中添加SCSA注意力机制,助力有效涨点。作者提出了一种新的空间与通道协同注意模块(S…...
科技快讯 | 理想官宣:正式收费!WeChat 港币钱包拓宽商户网络;百川智能发布深度思考模型Baichuan-M1-preview
理想官宣:正式收费! 1月23日,理想汽车宣布,理想超充站超时占用费正式运营。触发超时占用费的条件为充电结束后15分钟内未将充电枪插回充电桩,收费标准为2元/分钟,单次封顶200元。理想汽车将在充电结束的四个…...
LLM架构与优化:从理论到实践的关键技术
标题:“LLM架构与优化:从理论到实践的关键技术” 文章信息摘要: 文章探讨了大型语言模型(LLM)开发与应用中的关键技术,包括Transformer架构、注意力机制、采样技术、Tokenization等基础理论,以…...
深入理解Pytest中的Setup和Teardown
关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 对于简单程序而言,使用 Pytest 运行测试直截了当。然而,当你…...
PostgreSQL 约束
PostgreSQL 约束 引言 在数据库设计中,约束是确保数据完整性和一致性的关键工具。PostgreSQL,作为一款功能强大的开源关系型数据库管理系统,提供了丰富的约束类型来满足不同的数据库设计需求。本文将详细介绍PostgreSQL中的各种约束,包括其定义、用途和实现方法。 一、约…...
JAVA 接口、抽象类的关系和用处 详细解析
接口 - Java教程 - 廖雪峰的官方网站 一个 抽象类 如果实现了一个接口,可以只选择实现接口中的 部分方法(所有的方法都要有,可以一部分已经写具体,另一部分继续保留抽象),原因在于: 抽象类本身…...
【微服务与分布式实践】探索 Dubbo
核心组件 服务注册与发现原理 服务提供者启动时,会将其服务信息(如服务名、版本、所在节点的网络地址等)注册到注册中心。服务消费者则可以从注册中心发现可用的服务提供者列表,并与之通信。注册中心会存储服务的信息,…...
lightweight-charts-python 包 更新 lightweight-charts.js 的方法
lightweight-charts-python 是 lightweight-charts.js 的 python 包装,非常好用 lightweight-charts 更新比较频繁,导致 lightweight-charts-python 内置的 lightweight-charts 经常不是最新的。 新的 lightweight-charts 通常可以获得性能改进和bug修复…...
作業系統:設計與實現-母本
2023 南京大學《作業系統:設計與實現》 課程主頁(含講義):https://jyywiki.cn/OS/2023/ 【Python 实现操作系统模型 [南京大学2023操作系统-P4] (蒋炎岩)-哔哩哔哩】 https://b23.tv/jakxDbh 用Python实现操作系统模型讲义 一、操作系统基础概念 1.1 定义 操作系统(Oper…...
穿心莲内酯(andrographolide)生物合成CYP72-文献精读106
Two CYP72 enzymes function as Ent-labdane hydroxylases in the biosynthesis of andrographolide in Andrographis paniculata 两种CYP72酶在穿心莲(Andrographis paniculata)中作为Ent-labdane羟化酶,在穿心莲内酯(andrograp…...
IDM-VTON本地部署教程:双重编码 + 文字提示,解锁真实野外试穿
一、介绍 IDM-VTON:改进扩散模型,实现真实的野外虚拟试穿。 技术原理:改进扩散模型,利用视觉编码器提取服装高级语义信息并与交叉注意力层融合,通过并行 UNet 结构的 GarmentNet 捕捉服装低级特征并与自注意力层结合&…...
【微服务与分布式实践】探索 Sentinel
参数设置 熔断时长 、最小请求数、最大RT ms、比例阈值、异常数 熔断策略 慢调⽤⽐例 当单位统计时⻓内请求数⽬⼤于设置的最⼩请求数⽬,并且慢调⽤的⽐例⼤于阈值,则接下来的熔断时⻓内请求会⾃动被熔断 异常⽐例 当单位统计时⻓内请求数⽬⼤于设置…...
云计算与虚拟化技术讲解视频分享
互联网各领域资料分享专区(不定期更新): Sheet 前言 由于内容较多,且不便于排版,为避免资源失效,请用手机点击链接进行保存,若链接生效请及时反馈,谢谢~ 正文 链接如下(为避免资源失效&#x…...
[c语言日寄]越界访问:意外的死循环
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
数据结构---哈希表
基本概念 哈希函数(Hash Function)是一种将输入的数据(通常是任意大小的)映射到固定大小的输出(通常是一个固定长度的值)的函数。这个输出值通常称为“哈希值”(Hash Value)或“哈希…...
【C语言----数组详解】
目录 ---------------------------------------begin--------------------------------------- 一、什么是数组 二、数组的声明和初始化 1. 数组的声明 2. 数组的初始化 三、数组元素的访问 四、数组的遍历 五、数组的应用 六、多维数组 七、总结 --------------------…...
C语言字符串详解
1. C语言中的字符串基础 C语言中的字符串是程序设计中不可忽视的部分。与现代高级编程语言不同,C语言对字符串的处理方式直接、灵活,并且强大。在C语言中,字符串并不是一种特殊的数据类型,而是字符数组的一种表现形式。字符串通常…...
基础IO(2)
基础IO(2) 理解“⼀切皆⽂件” ⾸先,在windows中是⽂件的东西,它们在linux中也是⽂件;其次⼀些在windows中不是⽂件的东西,⽐如进程、磁盘、显⽰器、键盘这样硬件设备也被抽象成了⽂件,你可以使…...
深入理解 Python 中的 `__all__`:控制模块的公共接口
在 Python 编程中,模块化设计是构建可维护和可扩展代码的关键。模块不仅帮助我们组织代码,还能通过隐藏实现细节来提高代码的可读性和安全性。Python 提供了多种机制来控制模块的可见性,其中 __all__ 是一个非常重要但常被忽视的特性。本文将…...
Python面试宝典7 | 正则表达式的match()与search(),精准匹配与全局搜索
今天,我们来聊聊Python正则表达式中两个常用的方法:match()和search()。它们都用于在字符串中查找匹配的模式,但有着重要的区别。 理论篇:匹配的起始位置 match()和search()最主要的区别在于它们匹配的起始位置: ma…...
代码随想录算法训练营第三十八天-动态规划-完全背包-279.完全平方数
把目标值当作背包容量,每个平方数当作物品,题目变更为装满指定容量的背包,最小用几个物品会不会出现拼凑不出来的情况?不会,因为有数字1,对任意正整数百分百能拼凑出来因此此题目与上一道题就变得一模一样了…...
996引擎 - NPC-添加NPC引擎自带形象
996引擎 - NPC-添加NPC引擎自带形象 截图参考添加NPC参考资料截图参考 添加NPC 编辑NPC表:Envir\DATA\cfg_npclist.xls 1.1. 需要临时隐藏NPC时可以在id前加 // 1.2. 如果NPC朝向不对,可以调整dir 列。(按8方向,上是0顺时针数。我这里给的4) 1.3. 形象代码:NPC代码、怪物…...
基于 NodeJs 一个后端接口的创建过程及其规范 -- 【elpis全栈项目】
基于 NodeJs 一个后端接口的创建过程及其规范 一个接口的诞生: #mermaid-svg-46HXZKI3fdnO0rKV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-46HXZKI3fdnO0rKV .error-icon{fill:#552222;}#mermaid-sv…...
笔记本跑大模型尝试
1,笔记本电脑资源 我是一台联想笔记本电脑,基本配置如下: CPU:12th Gen Intel(R) Core(TM) i7-1255U 1.70 GHz (12核心,2个P核和8个E核,共计10个核心) 显卡:NVIDIA GeForce MX550 内存&am…...
[论文阅读] (37)CCS21 DeepAID:基于深度学习的异常检测(解释)
祝大家新春快乐,蛇年吉祥! 《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座,并分享给大家,希望您喜欢。由于作者的英文水平和学术能力不高,需要不断提升,所以还请大家批评指正࿰…...
常见端口的攻击思路
端口号端口说明攻击方向21/22/69FTP/TFTP文件传输协议匿名上传/下载、嗅探、爆破2049NFS服务配置不当139Sanba服务爆破、远程代码执行389Ldap目录访问协议注入、匿名访问、弱口令22SSH远程连接爆破、SSH映射隧道搭建、文件传输23Telnet远程连接爆破、嗅探、弱口令3389RDP远程桌…...
复古壁纸中棕色系和米色系哪个更受欢迎?
根据最新的搜索结果,我们可以看到棕色系和米色系在复古壁纸设计中都非常受欢迎。以下是对这两种颜色系受欢迎程度的分析: 棕色系 受欢迎程度:棕色系在复古壁纸中非常受欢迎,因为它能够营造出温暖、质朴和自然的氛围。棕色系的壁纸…...
RocketMQ消息是如何存储的?
大家好,我是锋哥。今天分享关于【RocketMQ消息是如何存储的?】面试题。希望对大家有帮助; RocketMQ消息是如何存储的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RocketMQ 使用了一个高性能、分布式的消息存储架构…...
在FreeBSD下安装Ollama并体验DeepSeek r1大模型
在FreeBSD下安装Ollama并体验DeepSeek r1大模型 在FreeBSD下安装Ollama 直接使用pkg安装即可: sudo pkg install ollama 安装完成后,提示: You installed ollama: the AI model runner. To run ollama, plese open 2 terminals. 1. In t…...
[250128] Apache HTTP Server 2.4.63 发布 | Arm 发布首个芯片系统架构的公开规范
目录 Apache HTTP Server 2.4.63 发布,十五年创新成果!Arm 发布首个芯片系统架构的公开规范 Apache HTTP Server 2.4.63 发布,十五年创新成果! Apache 软件基金会和 Apache HTTP Server 项目组自豪地宣布 Apache HTTP Server 2.4…...
为什么要学习rust
内存管理:对于我来说,我就喜欢它的内存管理。我做了一个webapi,取100万行数据,导出到xlsx,再把这个xlsx文件发送给前端。分别用了java、c#、go和rust进行了相同的操作。只有rust做到了,启动时8MB内存&#…...
Linux进程调度与等待:背后的机制与实现
个人主页:chian-ocean 文章专栏-Linux 前言: 当一个进程发起某种操作(如I/O请求、信号、锁的获取等),但该操作需要的资源暂时不可用时,进程会被操作系统挂起,进入“等待队列”或“阻塞状态”。…...
Linux任务管理与守护进程
文章目录 🍅任务管理进程组概念作业概念会话概念相关操作前台进程&后台进程jobsfgbgps命令查看指定的选项 🫒守护进程守护进程的概念作用守护进程的查看守护进程的创建原生创建守护进程调用daemon函数创建守护进程模拟实现daemon函数 🍅任…...
《Trustzone/TEE/安全从入门到精通-标准版》
CSDN学院课程连接:https://edu.csdn.net/course/detail/39573 讲师介绍 拥有 12 年手机安全、汽车安全、芯片安全开发经验,擅长 Trustzone/TEE/ 安全的设计与开发,对 ARM 架构的安全领域有着深入的研究和丰富的实践经验,能够将复杂的安全知识和处理器架构知识进行系统整…...
java 字符串日期字段格式化前端显示
在 Java 应用程序中,如果你有一个字符串类型的日期字段,并希望将其格式化后显示在前端,可以通过多种方式实现。这通常涉及到在后端将字符串转换为 Date 或 LocalDateTime 等对象,然后使用适当的注解或配置来确保它们以正确的格式序…...
LabVIEW橡胶动态特性测试系统
本文介绍了一个利用LabVIEW软件和NI高速数据采集设备构建的橡胶动态特性测试系统。该系统实现了橡胶材料动态性能的精确测量,并通过虚拟仪器技术,提高了测试数据的处理效率和准确性。系统支持实时数据处理和多种信号的动态分析,适用于工业和科…...
deepseek-r1 本地部署
deepseek 最近太火了 1:环境 win10 cpu 6c 内存 16G 2: 部署 1>首先下载ollama 官网:https://ollama.com ollama 安装在c盘 模型可以配置下载到其他盘 OLLAMA_MODELS D:\Ollama 2>下载模型并运行 ollama run deepseek-r1:<标签> 1.5b 7b 8…...
28. 【.NET 8 实战--孢子记账--从单体到微服务】--简易报表--报表定时器与报表数据修正
这篇文章是《.NET 8 实战–孢子记账–从单体到微服务》系列专栏的《单体应用》专栏的最后一片和开发有关的文章。在这片文章中我们一起来实现一个数据统计的功能:报表数据汇总。这个功能为用户查看月度、年度、季度报表提供数据支持。 一、需求 数据统计方面&…...
具身智能技术趋势
参考: 【北京大学-董豪】具身智能技术趋势分析 2024.8 回答了具身智能技术G3、G4的必要性,以及真实数据、仿真数据、互联网数据之间的关系 具身智能趋势 趋势:寻求一个通用路径实现所有的上肢操作 要求:① 低成本 ② 拓展到所有…...
JavaScript逆向高阶指南:突破基础,掌握核心逆向技术
JavaScript逆向高阶指南:突破基础,掌握核心逆向技术 JavaScript逆向工程是Web开发者和安全分析师的核心竞争力。无论是解析混淆代码、分析压缩脚本,还是逆向Web应用架构,掌握高阶逆向技术都将助您深入理解复杂JavaScript逻辑。本…...
C#面试常考随笔6:ArrayList和 List的主要区别?
在 C# 中,ArrayList和List<T>(泛型列表)都可用于存储一组对象。推荐优先使用List<T>,因为它具有更好的类型安全性、性能和语法简洁性,并且提供了更丰富的功能。只有在需要与旧代码兼容或存储不同类型对象的…...
【数据结构】 并查集 + 路径压缩与按秩合并 python
目录 前言模板朴素实现路径压缩按秩合并按树高为秩按节点数为秩 总结 前言 并查集的基本实现通常使用森林来表示不同的集合,每个集合用一棵树表示,树的每个节点有一个指向其父节点的指针。 如果一个节点是它自己的父节点,那么它就是该集合的代…...
使用 Redis List 和 Pub/Sub 实现简单的消息队列
使用 Redis List 和 Pub/Sub 实现简单的消息队列 Redis 本身不是专门的消息队列系统,但它提供了多种数据结构(如 List、Pub/Sub、Stream)来实现消息队列功能。根据不同的业务需求,可以选择不同的方式: 在 Redis 中&a…...
aerodrome交易所读合约分析
池地址 0xb2cc224c1c9fee385f8ad6a55b4d94e92359dc59token0 0x4200000000000000000000000000000000000006token1 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913tickSpacing 100stakedLiquidity 4579376109215388530 snapshotCumulativesInside tickLower tickUpperslot0 …...
mybatis(112/134)
多对一 第一种方法: 一的表参数设置: <association property"clazz" javaType"Clazz"> <id property"cid" column"cid"/> <result property"cname" column"cname"/> <…...