• [技术干货] 基于STM32设计的粮食仓库(粮仓)环境监测系统
    一、前言1.1 项目开发背景随着现代农业的发展和粮食储存规模的扩大,粮仓环境的智能化监控需求日益增长。传统的粮仓管理方式通常依赖人工检测和定期巡查,效率低下且容易出现疏漏,无法及时发现潜在问题,可能导致粮食受潮、霉变、虫害等损失。尤其在粮仓中,温度、湿度、气体浓度等环境参数对粮食的保存至关重要,科学管理这些参数能够显著提升粮食储存的质量和安全性。在粮仓的实际运行中,环境温度和湿度的异常变化可能导致粮食发霉或者干燥不足,而二氧化碳和一氧化碳等气体浓度的超标可能暗示粮仓内存在发酵、氧化或其他潜在的危害因素。此外,墙壁和角落的水汽问题,往往是粮仓受潮的主要原因之一,长期积水可能引发霉菌滋生,威胁储粮安全。因此,开发一套集成环境参数监测、智能预警和数据可视化的系统,能够实现粮仓环境的实时监控和远程管理,变得尤为重要。本项目基于STM32微控制器设计,结合温湿度传感器、气体检测模块、雨滴传感器以及WiFi通信技术,不仅实现对粮仓环境的全面监测,还支持数据上传至云端,通过网页端可视化大屏直观展示关键数据,为管理者提供决策依据。同时,系统具有异常报警功能和风扇控制功能,可以在检测到参数异常时,及时采取通风措施并发出警报,从而降低风险。这种高度集成的监测系统,不仅能够减少人工巡查的工作量,还能大幅提升粮仓管理的智能化水平,为粮食安全储存提供有力保障。当前项目使用的相关软件工具、传感器源代码工程已经上传到网盘(实时更新项目内容):cid:link_01.2 设计实现的功能(1) 环境温湿度检测 通过SHT30温湿度传感器,实时采集粮仓内的环境温度和湿度数据,并上传至服务器进行监控。(2) 二氧化碳浓度检测 系统集成二氧化碳检测功能,可持续监测粮仓内的二氧化碳浓度,及时发现异常情况。(3) 墙壁水汽检测 使用雨滴传感器安装在粮仓墙壁或角落区域,检测是否存在水汽积聚,防止潮湿导致的霉变风险。(4) 通风风扇控制 通过继电器控制通风风扇,根据环境参数的变化,自动开启或关闭通风设备,实现有效的空气循环。(5) 一氧化碳可燃气体检测 采用MQ9气体传感器监测粮仓内的一氧化碳等可燃气体浓度,降低潜在的安全隐患。(6) 数据上云及可视化大屏显示 通过ESP8266 WiFi模块实现数据上传至服务器,服务器以Python作为后端,将设备端采集的数据传输到网页前端,用户可通过可视化大屏查看所有环境参数。(7) 异常报警 当检测到环境参数超出预设范围,系统会触发有源蜂鸣器报警,同时在可视化网页上显示警示信息,提醒管理者及时采取措施。(8) 远程监控与数据管理 支持远程访问功能,管理者可通过网页实时监控粮仓环境数据,历史数据也可追溯查看,便于科学管理和问题分析。1.3 项目硬件模块组成(1) 主控模块 STM32F103RCT6作为核心控制器,用于采集传感器数据、执行逻辑控制和数据传输。(2) 温湿度检测模块 SHT30温湿度传感器,用于监测粮仓内部环境的温度和湿度。(3) 二氧化碳检测模块 用于检测粮仓内二氧化碳浓度,确保空气质量符合储粮要求。(4) 水汽检测模块 雨滴传感器安装在墙壁或角落,用于检测是否有水汽或潮湿情况。(5) 可燃气体检测模块 MQ9传感器用于监测一氧化碳及其他可燃气体浓度,保障粮仓安全。(6) 通风风扇控制模块 继电器驱动模块控制通风风扇的启停,根据环境监测数据进行智能化通风操作。(7) WiFi通信模块 ESP8266-WIFI模块实现设备与服务器的无线通信,完成数据上传至云端。(8) 显示屏模块 采用SPI接口的LCD显示屏,用于本地实时显示粮仓环境参数和状态信息。(9) 蜂鸣器报警模块 高电平触发的有源蜂鸣器,用于当环境参数异常时发出声响报警。(10) 电源模块 为各个模块提供稳定的供电,确保系统的持续可靠运行。1.4 设计思路本项目设计一套基于STM32的粮仓环境监测系统,通过多种传感器采集粮仓环境的关键参数,实现数据实时监测、异常报警和智能化管理。整个设计思路围绕硬件搭建、数据处理与传输以及用户交互展开。硬件方面,选用STM32F103RCT6作为主控芯片,借助其丰富的外设接口和较强的处理能力,与SHT30温湿度传感器、MQ9可燃气体传感器、雨滴传感器等模块协同工作,实现粮仓环境温湿度、气体浓度、水汽状态的多维度数据采集。同时,通过继电器模块控制通风风扇,结合蜂鸣器实现环境调节和异常报警的功能。ESP8266 WiFi模块提供无线通信能力,将采集的数据上传至服务器,完成云端数据传输和管理。显示屏模块则用于本地显示关键数据,为管理者提供直观的信息反馈。数据处理和逻辑控制是设计的核心。在STM32控制器中,通过定时采集传感器数据并执行数据校验,将采集到的环境参数与预设的阈值进行比对。当检测到异常(如温湿度超标、气体浓度超限或水汽检测到问题)时,系统触发蜂鸣器报警,并通过继电器自动启动通风风扇。同时,将报警信息和实时参数通过WiFi模块上传到云端,便于远程管理。在数据传输与用户交互方面,服务器端采用Python开发后端,接收STM32上传的数据并存储。前端通过网页展示可视化大屏,实时呈现粮仓环境的温湿度、气体浓度及设备状态。当出现异常时,网页上以醒目的警告提示辅助蜂鸣器报警,使管理者能够快速定位问题。整个设计强调系统的可靠性与扩展性。模块化的硬件设计和合理的软件架构,不仅使系统在粮仓环境监测中具有实用性,还可以根据需求扩展其他监测功能,如虫害监控或视频监控,从而进一步提升粮仓管理的智能化水平。1.5 系统功能总结功能类别具体功能描述环境监测功能环境温度检测使用SHT30传感器实时监测粮仓内部温度。环境湿度检测使用SHT30传感器实时监测粮仓内部湿度。二氧化碳浓度检测检测粮仓内二氧化碳浓度,保证空气质量。一氧化碳及可燃气体检测通过MQ9传感器监测一氧化碳及其他可燃气体浓度,防范安全风险。水汽检测使用雨滴传感器监测墙壁或角落是否存在水汽积聚,防止潮湿问题。控制功能通风风扇控制通过继电器模块控制风扇启停,自动调节粮仓空气流通。报警功能蜂鸣器报警当检测到异常环境参数时,蜂鸣器发出声响警报。可视化报警数据上传至云端,在网页可视化大屏上显示警告信息。通信功能数据上云通过ESP8266 WiFi模块将环境参数上传至服务器,支持远程管理。显示功能本地数据显示使用SPI接口LCD屏显示实时的温湿度、气体浓度及设备状态信息。远程监控功能数据可视化在网页端以图表形式展示实时数据,用户可随时查看环境参数及设备状态。异常处理功能自动调节环境参数超标时,系统自动启动风扇等调节设备,并上传异常数据供管理者参考。历史数据管理数据存储与回溯服务器存储历史数据,用户可回溯查看,分析环境变化趋势并优化管理策略。1.8 模块的技术详情介绍【1】ESP8266模块ESP8266是一款低功耗、低成本的WiFi模块,广泛应用于物联网(IoT)项目中。它集成了WiFi无线通信功能,可以实现设备与互联网的无线连接,具有非常高的性价比。ESP8266模块的设计旨在简化无线网络的配置和连接过程,特别适合嵌入式系统和智能硬件应用。ESP8266模块基于Tensilica Xtensa架构的32位微处理器,并集成了WiFi协议栈、网络功能以及各种控制和通信接口,能够支持WiFi标准的IEEE 802.11 b/g/n协议。它内置有处理器、存储器、WiFi射频模块以及网络协议栈,支持通过AT命令或通过编程来控制和操作。用户可以通过编程将其嵌入到各种应用中,作为通信桥梁在微控制器和互联网之间进行数据传输。该模块通常包括多个版本,常见的有ESP-01、ESP-12E等,它们的差异主要体现在引脚数目、外部存储、天线设计等方面。ESP8266具有较强的处理能力,能够支持复杂的通信协议,并能够独立执行部分任务,无需外部微处理器的支持。它的主要功能是将嵌入式设备连接到WiFi网络,通过HTTP、MQTT、WebSocket等协议与云端进行数据交互和控制。在实际应用中,ESP8266模块通过串口(UART)与其他硬件设备进行通信,且其支持AT命令集,通过这些命令可以配置WiFi参数、控制网络连接、发送和接收数据。对于开发者来说,它的开发环境支持Arduino IDE、NodeMCU、PlatformIO等,极大地简化了开发流程。使用这些开发环境,开发者可以通过编程实现更复杂的功能,如数据采集、远程控制、智能家居应用等。ESP8266的低功耗特点使得它特别适合于物联网设备的应用。模块的工作电压范围为3.3V,虽然其本身的功耗较低,但在深度休眠模式下,功耗可以进一步降低到微安级别,从而延长电池寿命。这使得ESP8266在需要长期运行的无线传感器网络和便携式设备中具有广泛的应用。在物联网应用中,ESP8266常常用于实现设备与互联网的互联互通,能够通过WiFi协议将数据上传到云平台,如华为云、AWS、ThingSpeak等,实现数据存储、远程监控、控制和分析。在智能家居、智能农业、环境监控等领域,ESP8266作为通信模块发挥着至关重要的作用。ESP8266凭借其低成本、高集成度、强大的WiFi连接功能以及良好的开发支持,成为了物联网领域中最受欢迎的无线通信模块之一,尤其适用于需要无线连接的嵌入式设备和智能硬件项目。二、安装Python环境2.1 环境介绍操作系统: win10 64位python版本: 3.8IDE: 采用vscode用到的相关安装包下载地址: cid:link_02.2 Python版本介绍因为Python是跨平台的,它可以运行在Windows、Mac和各种Linux/Unix系统上。在Windows上写Python程序,放到Linux上也是能够运行的。要开始学习Python编程,首先就得把Python安装到你的电脑里。安装后,你会得到Python解释器(就是负责运行Python程序的),一个命令行交互环境,还有一个简单的集成开发环境。目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的。由于3.x版越来越普及,后面就选择 3.x版本进行安装。三、设计后端服务器与前端页面编写一个后端服务器,使用Python的Flask框架来接受设备通过TCP协议上传的数据,并编写一个HTML网页来展示这些数据。3.1 编写后端服务器使用Python的socket模块来创建一个TCP服务器,用于接收设备上传的数据。使用Flask框架来创建一个Web应用,用于展示数据。import socket from flask import Flask, render_template, jsonify ​ # 初始化Flask应用 app = Flask(__name__) ​ # 全局变量保存最新上传的数据 data = { "temperature": None, "humidity": None, "co2": None, "water_vapor": None, "fan_status": None, "co_gas": None, "alert": None } ​ # TCP服务器处理设备端数据上传 def start_tcp_server(): host = '0.0.0.0' port = 5005 ​ server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(5) print(f"Listening on {host}:{port}") while True: client_socket, addr = server_socket.accept() print(f"Connection from {addr}") try: while True: received_data = client_socket.recv(1024).decode("utf-8").strip() if not received_data: break # 如果没有数据,退出循环 print(f"Raw Data received: {received_data}") # 解析数据 try: values = received_data.split(',') if len(values) == 7: global data data["temperature"] = float(values[0]) data["humidity"] = float(values[1]) data["co2"] = float(values[2]) data["water_vapor"] = "Detected" if int(values[3]) == 1 else "Not Detected" data["fan_status"] = "ON" if int(values[4]) == 1 else "OFF" data["co_gas"] = float(values[5]) data["alert"] = "Triggered" if int(values[6]) == 1 else "Normal" # 打印解析后的数据 print(f"Parsed Data:") print(f" Temperature: {data['temperature']} °C") print(f" Humidity: {data['humidity']} %") print(f" CO2 Level: {data['co2']} ppm") print(f" Water Vapor: {data['water_vapor']}") print(f" Fan Status: {data['fan_status']}") print(f" CO Gas: {data['co_gas']} ppm") print(f" Alert: {data['alert']}") except Exception as e: print(f"Error parsing data: {e}") except Exception as e: print(f"Error handling client connection: {e}") finally: client_socket.close() ​ ​ # 启动TCP服务器线程 import threading threading.Thread(target=start_tcp_server, daemon=True).start() ​ # Web路由 @app.route('/') def index(): return render_template("index.html") ​ @app.route('/api/data') def get_data(): return jsonify(data) ​ if __name__ == "__main__": app.run(host="0.0.0.0", port=8080, debug=True)3.2 编写HTML网页使用Bootstrap框架来创建一个网页,用于展示设备上传的数据。网页命名为: index.html。 放在 templates目录下。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>粮仓环境监测系统</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> <style> body { background-color: #121212; color: #fff; } .card { margin-top: 20px; background-color: #222; border: 1px solid #444; } .card-header { background-color: #007BFF; color: #fff; } .card-body { background-color: #fff; color: #000; } .table { margin-bottom: 0; } .table-bordered td, .table-bordered th { border: 1px solid #444; } .table th { background-color: #007BFF; color: #fff; } </style> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 offset-md-3"> <div class="card"> <div class="card-header"> <h3 class="text-center">粮仓环境监测数据</h3> </div> <div class="card-body"> <table class="table table-bordered"> <tbody> <tr> <td>温度</td> <td id="temperature"></td> </tr> <tr> <td>湿度</td> <td id="humidity"></td> </tr> <tr> <td>二氧化碳浓度</td> <td id="co2"></td> </tr> <tr> <td>水汽检测</td> <td id="water_vapor"></td> </tr> <tr> <td>风扇状态</td> <td id="fan_status"></td> </tr> <tr> <td>一氧化碳浓度</td> <td id="co_gas"></td> </tr> <tr> <td>报警状态</td> <td id="alert"></td> </tr> </tbody> </table> </div> </div> </div> </div> </div> <script> // 使用JavaScript获取数据并更新页面 function updateData() { $.getJSON('/api/data', function(data) { $('#temperature').text(data.temperature + ' °C'); $('#humidity').text(data.humidity + ' %'); $('#co2').text(data.co2 + ' ppm'); $('#water_vapor').text(data.water_vapor); $('#fan_status').text(data.fan_status); $('#co_gas').text(data.co_gas + ' ppm'); $('#alert').text(data.alert); }); } ​ // 每秒更新一次数据 setInterval(updateData, 1000); </script> </body> </html> ​3.3 文件摆放目录层次3.4 运行效果在VSCODE里调用Python运行服务器代码。网页运行效果:四、STM32代码设计4.1 框架概述初始化:初始化所有的硬件和软件组件数据采集:从各种传感器(如SHT30、MQ9等)读取数据。数据处理:处理采集到的数据,例如转换单位、计算平均值等。数据上传:通过WiFi模块(ESP8266)将数据上传到服务器。控制逻辑:根据采集到的数据执行相应的控制逻辑,控制风扇、蜂鸣器。4.2 关键代码1. 初始化#include "stm32f10x.h" #include "sht30.h" #include "mq9.h" #include "wifi.h" #include "buzzer.h" #include "fan.h" #include "rain_sensor.h" ​ int main(void) { // 初始化所有模块 GPIO_Init(); UART_Init(); SPI_Init(); I2C_Init(); SHT30_Init(); MQ9_Init(); WIFI_Init(); Buzzer_Init(); Fan_Init(); RainSensor_Init(); ​ // 主循环 while (1) { // 数据采集 float temperature = SHT30_GetTemperature(); float humidity = SHT30_GetHumidity(); float co2 = MQ9_GetCO2(); int water_vapor = RainSensor_GetStatus(); int fan_status = Fan_GetStatus(); float co_gas = MQ9_GetCO(); int alert = GetAlertStatus(temperature, humidity, co2, water_vapor, fan_status, co_gas); ​ // 数据处理 // ... ​ // 数据上传 char data_str[100]; sprintf(data_str, "%.2f,%.2f,%.2f,%d,%d,%.2f,%d", temperature, humidity, co2, water_vapor, fan_status, co_gas, alert); WIFI_SendData(data_str); ​ // 控制逻辑 // ... ​ } }2. 数据采集// 从SHT30读取温度和湿度 float SHT30_GetTemperature() { // 发送测量命令 SHT30_SendCommand(SHT30_MEASURE_HIGHREP); ​ // 等待测量完成 Delay_ms(50); ​ // 读取数据 uint16_t raw_data = SHT30_ReadData(); ​ // 转换为温度值 float temperature = SHT30_CalculateTemperature(raw_data); ​ return temperature; } ​ float SHT30_GetHumidity() { // 发送测量命令 SHT30_SendCommand(SHT30_MEASURE_HIGHREP); ​ // 等待测量完成 Delay_ms(50); ​ // 读取数据 uint16_t raw_data = SHT30_ReadData(); ​ // 转换为湿度值 float humidity = SHT30_CalculateHumidity(raw_data); ​ return humidity; } ​ // 从MQ9读取CO2浓度 float MQ9_GetCO2() { // 读取ADC值 uint16_t adc_value = ADC_GetValue(MQ9_CHANNEL); ​ // 转换为CO2浓度 float co2 = MQ9_CalculateCO2(adc_value); ​ return co2; } ​ // 从雨滴传感器读取状态 int RainSensor_GetStatus() { // 读取GPIO状态 int status = GPIO_ReadInputDataBit(RAIN_SENSOR_PIN); ​ return status; }3. 数据处理// 根据采集到的数据计算报警状态 int GetAlertStatus(float temperature, float humidity, float co2, int water_vapor, int fan_status, float co_gas) { // 报警条件 if (temperature > 30 || humidity > 70 || co2 > 1000 || water_vapor == 1 || fan_status == 0 || co_gas > 50) { return 1; // 报警 } else { return 0; // 正常 } }4. 数据上传// 通过WiFi模块发送数据 void WIFI_SendData(char *data) { // 发送数据 // ... }5. 控制逻辑// 根据报警状态控制蜂鸣器 void ControlBuzzer(int alert) { if (alert) { Buzzer_On(); } else { Buzzer_Off(); } } ​ // 根据报警状态控制风扇 void ControlFan(int alert) { if (alert) { Fan_Off(); } else { Fan_On(); } }五、总结本项目设计一个基于STM32的粮食仓库环境监测系统,以实现对仓库内环境参数的实时监测和控制。通过多种传感器(如SHT30、MQ9等)采集环境数据,并通过WiFi模块将数据上传至服务器,最终在可视化网页上展示数据。系统支持多种功能,包括环境温度、湿度检测,二氧化碳浓度检测,墙壁水汽检测,通风风扇控制,一氧化碳可燃气体检测,数据上云以及可视化大屏显示等。主要功能环境监测:实时监测环境温度、湿度、二氧化碳浓度、水汽检测、一氧化碳浓度等参数。通过SHT30传感器获取温度和湿度数据。通过MQ9传感器检测二氧化碳和一氧化碳浓度。通过雨滴传感器检测墙壁水汽。数据上传:设备端的数据通过WiFi连接服务器上传数据。使用ESP8266-WIFI模块实现数据传输。可视化展示:通过网页可视化大屏进行展示数据。使用Flask作为后端服务器,接收设备端上传的数据,并在网页上展示。控制逻辑:根据采集到的数据执行相应的控制逻辑,例如控制风扇、蜂鸣器等。当环境参数不符合要求时,通过蜂鸣器报警,并在可视化页面上展示提示。硬件选型主控芯片:STM32F103RCT6温湿度传感器:SHT30可燃气体检测模块:MQ9通风风扇控制:继电器WiFi模块:ESP8266-WIFI模块显示屏:SPI接口的LCD显示屏水汽检测:雨滴传感器蜂鸣器:高电平触发的有源蜂鸣器软件设计使用C语言编写STM32代码,实现数据采集、处理和上传。使用Python编写服务器端代码,接收设备端上传的数据,并在网页上展示。使用Flask框架搭建Web服务器,提供HTTP接口供前端页面访问。
  • [技术干货] 基于STM32设计的工地扬尘与噪音实时监测系统(网页)
    一、前言当前项目使用的相关软件工具、传感器源代码工程已经上传到网盘(实时更新项目内容):cid:link_01.1 项目开发背景近年来,随着城市化进程的加快和工业活动的增加,工地扬尘和噪声污染问题日益严重。扬尘不仅会对大气质量造成影响,进而危害人类健康,还可能加剧区域性的环境问题。而施工过程中产生的噪声污染,则直接影响周边居民的生活质量,甚至对工人自身的身体健康造成危害。加强对工地扬尘与噪声的实时监测与控制,成为了环保治理和施工管理的重要方向。传统的监测方式主要依赖于定点采样和手动记录,效率低下,且难以实现实时性和广覆盖。而基于现代物联网技术的智能监测方案,不仅能够提高监测效率,还能实现远程数据访问和动态控制,极大地提升了治理效果。因此,设计一套基于STM32的工地扬尘与噪音实时监测系统,具有重要的实际应用价值。本项目开发一套能够实时监测PM2.5浓度和环境噪声的系统,并通过集成显示、网络传输和自动控制功能,为工地的环保治理提供智能化的解决方案。利用夏普PM2.5传感器和噪声检测模块实现对空气质量和噪声的采集,通过STM32F103RCT6主控芯片进行数据处理,并通过ESP8266模块将监测数据上传到服务器,为远程管理提供支持。同时,系统集成了加湿器控制功能,当检测到粉尘浓度超标时,自动启动加湿器喷洒水雾,降低粉尘浓度,从而对环境污染进行有效控制。本系统不仅支持在LCD显示屏上实时显示监测数据,还支持通过TCP协议上传数据,并借助Flask框架开发的网页应用实现可视化展示,方便用户随时随地查看和分析数据。整体设计以高效、便捷、低成本为目标,为施工环境的实时监测和治理提供了可靠的技术支持。1.2 设计实现的功能(1) PM2.5含量检测:系统通过夏普PM2.5检测传感器实时监测空气中的PM2.5含量,并将数据传输给主控芯片STM32F103RCT6进行处理。(2) 噪声检测:使用模拟量输出的噪声检测传感器,通过电压输出反映环境噪声的大小,STM32F103RCT6对噪声信号进行采集和处理。(3) LCD显示屏实时数据显示:系统配备1.44寸的LCD显示屏,本地实时显示检测到的PM2.5、噪声、温湿度等环境数据。(4) Web应用数据可视化:通过Python的socket模块创建TCP服务器,接收设备上传的数据,使用Flask框架开发Web应用,展示实时监测数据。用户可以通过浏览器访问系统,查看各项环境指标。(5) WIFI+TCP协议数据传输:设备端通过ESP8266模块实现WIFI连接,采用TCP协议将监测数据传输到服务器,确保数据实时传递和远程监控。(6) 加湿系统控制:当PM2.5含量超出预定范围时,系统会自动启用继电器控制的加湿器,通过喷洒水雾降低空气中灰尘的含量,从而改善空气质量。(7) 温湿度检测:使用SHT30温湿度传感器检测环境的温度和湿度信息,主控芯片STM32F103RCT6处理后显示在LCD屏幕上,并上传到Web应用进行展示。1.3 项目硬件模块组成(1) 空气质量检测模块采用夏普PM2.5检测传感器,用于检测空气中的PM2.5含量。传感器将数据转化为电信号,STM32读取并处理数据。(2) 噪声检测模块使用模拟量输出的噪声检测传感器,传感器输出电压信号与声音的大小成正比,STM32通过ADC接口采集并分析噪声数据。(3) LCD显示模块使用1.44寸的LCD显示屏,实时显示空气质量、噪声、温湿度等数据。通过STM32的SPI接口与LCD连接,显示系统监测的各项指标。(4) 温湿度检测模块使用SHT30模块来测量环境的温度和湿度。该模块通过I2C接口与STM32连接,STM32读取数据并显示或传输到服务器。(5) 加湿器控制模块使用继电器控制加湿器。当PM2.5超过预设范围时,STM32控制继电器打开加湿器,对空气进行喷水,降低灰尘浓度。继电器通过数字输出控制,STM32负责监测和决策。(6) WIFI通信模块使用ESP8266模块进行WIFI通信,传输传感器数据至服务器。ESP8266与STM32通过串口进行数据交换,将数据通过TCP协议发送给远程服务器。(7) 主控模块使用STM32F103RCT6作为主控芯片,负责整个系统的控制、数据采集和处理。STM32连接所有传感器模块,处理数据并通过WIFI模块将数据上传到服务器。(8) 电源模块使用USB接口为系统提供电力,通过USB供电模块转化为系统所需的电压(如5V),为主控芯片和传感器提供稳定电源。(9) 服务器端通信模块使用Python的Socket模块在服务器端建立TCP服务器,接收设备上传的数据。数据通过WIFI传输,最终传递给Flask Web应用进行可视化展示。(10) Web应用模块使用Flask框架开发Web应用,用于展示数据。Flask应用接收从TCP服务器获取的传感器数据,并通过浏览器展示实时监控的数据。1.4 设计思路本项目的设计思路主要分为硬件选型、数据采集与处理、通信方式、控制系统以及可视化展示几个方面。在硬件选型上,考虑到项目的需求和稳定性,我们选择了STM32F103RCT6作为主控芯片,它具备强大的处理能力和丰富的外设接口,适合处理多种传感器的数据采集与控制任务。为了监测空气质量,选择了夏普PM2.5传感器,该传感器能精确测量空气中的PM2.5含量,通过模拟信号输出,STM32通过ADC采集数据并进行处理。噪声检测则采用了模拟输出噪声传感器,噪声强度通过电压信号体现,STM32通过相应的接口读取数据。环境温湿度的检测选用了SHT30模块,通过I2C接口读取温湿度数据。加湿器控制通过继电器实现,当PM2.5超标时,STM32发出信号启动继电器,控制加湿器进行加湿操作。数据采集与处理方面,STM32负责读取所有传感器的数据并进行必要的处理。通过模拟信号输入的噪声传感器和PM2.5传感器数据,STM32会对其进行实时监测,根据设定的阈值判断是否启动加湿器。当PM2.5值超过预设的安全范围时,STM32会控制继电器开启加湿器,以降低空气中的粉尘浓度,保证环境的安全性。环境温湿度数据则会被实时采集并传送给显示屏和服务器端,确保数据的准确性与实时性。在通信方式上,采用ESP8266模块为系统提供WIFI功能,方便数据远程传输。通过TCP协议,设备端将实时采集到的数据通过ESP8266传送到服务器,确保数据可以及时传输到远程服务器端,供后续的数据分析和可视化展示使用。STM32和ESP8266通过串口进行数据交换,确保数据传输的稳定性和效率。在控制系统方面,STM32不仅负责采集和处理数据,还承担了整个系统的控制任务。例如,在检测到PM2.5超过安全阈值时,STM32会自动启动继电器控制加湿器,确保空气质量得到改善。温湿度数据和噪声数据则持续监测和更新,在LCD显示屏上实时反馈。数据的可视化展示是本项目的一项重要功能。通过Flask框架,设计了一个Web应用,服务器接收从设备端传输的数据后,通过浏览器进行可视化展示,用户可以通过PC或手机端实时查看工地的空气质量、噪声强度、温湿度等数据。这部分的设计使用了Python的Socket模块来接收来自设备的数据,并使用Flask框架生成网页,展现实时数据,进一步提高了监测系统的实用性和便捷性。本项目通过合理的硬件选型、数据采集与处理方式、通信手段和控制策略,打造了一个高效且实时的工地扬尘与噪音监测系统,为环境监控提供了强大的技术支持。1.5 系统功能总结功能模块功能描述空气质量检测采用夏普PM2.5传感器,实时检测空气中的PM2.5含量。噪声检测使用模拟量输出噪声传感器,检测环境中的噪声强度并通过电压信号反馈。LCD显示屏显示通过1.44寸LCD显示屏实时显示PM2.5含量、噪声值、温湿度等数据。温湿度检测采用SHT30模块实时监测环境温度和湿度,通过I2C接口将数据传输给STM32并显示。加湿器控制当PM2.5浓度超过预设范围时,系统自动启动继电器控制加湿器喷洒水雾,减少空气中的粉尘浓度。数据传输设备通过ESP8266模块连接WIFI,将实时采集的数据通过TCP协议传输至服务器端。远程数据监控使用Python的Socket模块和Flask框架创建Web应用,浏览器可以实时查看传感器数据的可视化界面。系统控制STM32主控芯片负责数据采集、处理和控制任务,保证系统的正常运行和数据传输。电源管理通过USB接口提供电源,为系统供电,确保稳定运行。1.8 模块的技术详情介绍【1】ESP8266模块ESP8266是一款低功耗、低成本的WiFi模块,广泛应用于物联网(IoT)项目中。它集成了WiFi无线通信功能,可以实现设备与互联网的无线连接,具有非常高的性价比。ESP8266模块的设计旨在简化无线网络的配置和连接过程,特别适合嵌入式系统和智能硬件应用。ESP8266模块基于Tensilica Xtensa架构的32位微处理器,并集成了WiFi协议栈、网络功能以及各种控制和通信接口,能够支持WiFi标准的IEEE 802.11 b/g/n协议。它内置有处理器、存储器、WiFi射频模块以及网络协议栈,支持通过AT命令或通过编程来控制和操作。用户可以通过编程将其嵌入到各种应用中,作为通信桥梁在微控制器和互联网之间进行数据传输。该模块通常包括多个版本,常见的有ESP-01、ESP-12E等,它们的差异主要体现在引脚数目、外部存储、天线设计等方面。ESP8266具有较强的处理能力,能够支持复杂的通信协议,并能够独立执行部分任务,无需外部微处理器的支持。它的主要功能是将嵌入式设备连接到WiFi网络,通过HTTP、MQTT、WebSocket等协议与云端进行数据交互和控制。在实际应用中,ESP8266模块通过串口(UART)与其他硬件设备进行通信,且其支持AT命令集,通过这些命令可以配置WiFi参数、控制网络连接、发送和接收数据。对于开发者来说,它的开发环境支持Arduino IDE、NodeMCU、PlatformIO等,极大地简化了开发流程。使用这些开发环境,开发者可以通过编程实现更复杂的功能,如数据采集、远程控制、智能家居应用等。ESP8266的低功耗特点使得它特别适合于物联网设备的应用。模块的工作电压范围为3.3V,虽然其本身的功耗较低,但在深度休眠模式下,功耗可以进一步降低到微安级别,从而延长电池寿命。这使得ESP8266在需要长期运行的无线传感器网络和便携式设备中具有广泛的应用。在物联网应用中,ESP8266常常用于实现设备与互联网的互联互通,能够通过WiFi协议将数据上传到云平台,如华为云、AWS、ThingSpeak等,实现数据存储、远程监控、控制和分析。在智能家居、智能农业、环境监控等领域,ESP8266作为通信模块发挥着至关重要的作用。ESP8266凭借其低成本、高集成度、强大的WiFi连接功能以及良好的开发支持,成为了物联网领域中最受欢迎的无线通信模块之一,尤其适用于需要无线连接的嵌入式设备和智能硬件项目。【2】TCP协议TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输层协议,它位于OSI七层模型中的传输层。TCP协议主要用于在计算机网络中实现可靠的数据传输,它保证了数据的正确性和顺序性,适用于对数据传输质量要求较高的应用场景,如网页浏览、文件传输和实时数据交换。TCP协议的核心特性是可靠性和有序性。在TCP连接中,发送方和接收方建立了一个可靠的连接,确保数据能够按顺序到达接收方。TCP通过使用数据包的序列号来确保数据的顺序性,并通过校验和机制来检测数据传输过程中的错误。如果在传输过程中出现丢包或错误,接收方会请求重传,保证数据传输的完整性。建立TCP连接时,采用了三次握手(three-way handshake)过程。首先,客户端发送一个SYN(同步)包,表示请求连接;然后,服务器回应一个SYN-ACK(同步应答)包,表示同意连接并回送确认信息;最后,客户端发送一个ACK(确认)包,完成连接的建立。这个过程确保了双方都准备好进行数据传输。连接建立后,双方就可以开始数据的双向传输了。在数据传输过程中,TCP采用流量控制和拥塞控制机制。流量控制通过调整发送窗口的大小,确保发送方不会超过接收方的处理能力;而拥塞控制则通过动态调整发送速度,避免过多的数据包在网络中引发拥塞,从而提高网络的整体性能。TCP的拥塞控制通常使用四种算法:慢启动、拥塞避免、快速重传和快速恢复,来有效地应对网络的波动。此外,TCP协议还提供了端到端的连接管理。每个TCP连接都由一个四元组唯一标识:源IP地址、源端口号、目的IP地址和目的端口号。通过这个四元组,数据可以精确地发送到网络中的特定应用程序。TCP协议通过序列号和确认号来跟踪和控制数据的传输,保证数据的可靠传送并解决丢包和乱序的问题。TCP连接的关闭也需要经过四次挥手(four-way handshake)。当传输完成后,任一一方可以主动发起连接关闭请求。首先,发送方发送一个FIN(结束)包,表示数据发送完毕;接收方确认收到FIN包后,返回一个ACK包;接着,接收方发送一个FIN包,表示它也已经准备好关闭连接;最后,发送方返回ACK包,确认连接关闭。通过这种方式,TCP确保了双方在完全断开连接前能够完成数据的最终传输。TCP协议是实现可靠通信的基石,尤其适合需要高可靠性和数据完整性的应用。虽然TCP相比于UDP(User Datagram Protocol,用户数据报协议)在性能上存在一定的开销,但其可靠的数据传输机制、流量控制、拥塞控制以及顺序保证使得它在需要保证数据完整和正确的场景中成为首选协议。【3】SHT30温湿度模块SHT30温湿度模块是一款由Sensirion公司生产的数字化温湿度传感器模块,采用I2C接口进行数据传输,广泛应用于环境监测、气象站、家居智能系统等领域。SHT30模块具有高精度、高稳定性和低功耗的特点,适合需要精确温湿度数据采集的应用场景。SHT30模块的工作原理基于湿度传感器和温度传感器的组合。它通过电容式湿度传感元件和半导体温度传感器来测量环境的温度和湿度。当传感器采集到温湿度数据后,会将数据通过I2C协议发送到主控芯片(如STM32、Arduino等)。SHT30能够提供高达±2%相对湿度和±0.3°C的温度精度,确保在多种环境条件下都能稳定可靠地工作。在通信方面,SHT30模块采用I2C总线协议,这使得它与主控芯片的连接变得简单方便。I2C协议是一种双向串行数据传输协议,允许多个设备共用两根数据线(SDA和SCL),使得传感器的连接和控制更加高效。通过I2C总线,主控芯片可以发出命令来启动温湿度测量操作,接收测量结果。SHT30模块支持不同的工作模式,包括单次测量模式和周期性测量模式,用户可以根据需要选择合适的模式进行配置。SHT30模块的优势之一是其低功耗设计,适用于对能耗有较高要求的场合。在正常工作模式下,SHT30的功耗非常低,适合长时间运行而不会消耗大量电池电量,这使得它成为物联网(IoT)设备和可穿戴设备中的常见选择。它还支持宽广的工作电压范围(2.4V至5.5V),适用于不同电压等级的应用场景。除了高精度和低功耗,SHT30模块还具有较强的抗干扰能力和稳定性。它采用了先进的封装和温湿度传感技术,能够在高湿度、高温度等恶劣环境下稳定工作,并且提供长期的可靠数据输出。对于需要在复杂环境中工作的应用,SHT30能够有效地避免因环境变化而引起的测量误差。SHT30温湿度模块是一款性能优异、易于使用的传感器,它能够提供准确、稳定的温湿度数据,广泛应用于各种智能监测和控制系统中。通过I2C接口与主控芯片进行数据交换,用户能够方便地采集到环境的温湿度信息,进而实现精准的环境监测与调节。二、安装Python环境2.1 环境介绍操作系统: win10 64位python版本: 3.8IDE: 采用vscode用到的相关安装包下载地址: cid:link_0三、设计后端服务器与前端页面3.1 Python后端代码(http_server.py)import socket from flask import Flask, render_template, jsonify ​ # 初始化Flask应用 app = Flask(__name__) ​ # 全局变量保存最新上传的数据 data = { "pm25": None, "noise": None, "temperature": None, "humidity": None, "humidifier_status": None } ​ # TCP服务器处理设备端数据上传 def start_tcp_server(): host = '0.0.0.0' port = 5005 ​ server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(5) print(f"Listening on {host}:{port}") while True: client_socket, addr = server_socket.accept() print(f"Connection from {addr}") try: while True: received_data = client_socket.recv(1024).decode("utf-8").strip() if not received_data: break # 如果没有数据,退出循环 print(f"Raw Data received: {received_data}") # 解析数据 try: values = received_data.split(',') if len(values) == 5: global data data["pm25"] = float(values[0]) data["noise"] = float(values[1]) data["temperature"] = float(values[2]) data["humidity"] = float(values[3]) data["humidifier_status"] = "ON" if int(values[4]) == 1 else "OFF" # 打印解析后的数据 print(f"Parsed Data:") print(f" PM2.5: {data['pm25']} μg/m³") print(f" Noise: {data['noise']} dB") print(f" Temperature: {data['temperature']} °C") print(f" Humidity: {data['humidity']} %") print(f" Humidifier Status: {data['humidifier_status']}") except Exception as e: print(f"Error parsing data: {e}") except Exception as e: print(f"Error handling client connection: {e}") finally: client_socket.close() ​ # 启动TCP服务器线程 import threading threading.Thread(target=start_tcp_server, daemon=True).start() ​ # Web路由 @app.route('/') def index(): return render_template("index.html") ​ @app.route('/api/data') def get_data(): return jsonify(data) ​ if __name__ == "__main__": app.run(host="0.0.0.0", port=8080, debug=True)3.2 HTML前端代码(index.html)<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>工地扬尘与噪音监测系统</title> <link rel="stylesheet" href="style.css"> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <!-- 图表库 --> <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js"></script> <!-- ECharts图表库 --> </head> <body> <div class="container"> <header> <h1>工地扬尘与噪音实时监测系统</h1> </header> ​ <section class="dashboard"> <!-- PM2.5 --> <div class="card pm25"> <h2>PM2.5含量</h2> <div id="pm25-value">0</div> <canvas id="pm25-chart"></canvas> </div> ​ <!-- 噪音 --> <div class="card noise"> <h2>噪声水平</h2> <div id="noise-value">0</div> <canvas id="noise-chart"></canvas> </div> ​ <!-- 温湿度 --> <div class="card temp-humidity"> <h2>温湿度</h2> <div id="temp-humidity-value">温度: 0°C 湿度: 0%</div> </div> ​ <!-- 加湿器状态 --> <div class="card humidifier"> <h2>加湿器状态</h2> <div id="humidifier-status">关闭</div> <button id="humidifier-toggle">切换加湿器</button> </div> </section> ​ <footer> <p>监测数据由STM32系统提供</p> </footer> </div> ​ <script src="script.js"></script> </body> </html> ​3.3 style.css文件/* 通用样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } ​ body { font-family: Arial, sans-serif; background-color: #2c3e50; color: #ecf0f1; display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100vh; } ​ .container { width: 90%; max-width: 1200px; margin: 0 auto; } ​ header { text-align: center; margin-bottom: 20px; } ​ header h1 { font-size: 3em; color: #1abc9c; } ​ .dashboard { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 20px; } ​ .card { background-color: #34495e; padding: 20px; border-radius: 10px; text-align: center; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } ​ .card h2 { font-size: 1.5em; margin-bottom: 10px; } ​ .card div { font-size: 2em; margin-top: 10px; } ​ footer { margin-top: 20px; text-align: center; font-size: 1em; color: #7f8c8d; } ​ /* 图表样式 */ canvas { max-width: 100%; height: 200px; margin-top: 20px; } ​ #pm25-value, #noise-value, #temp-humidity-value, #humidifier-status { font-size: 1.5em; font-weight: bold; color: #f39c12; }3.4 script.js 文件// 获取数据并更新页面内容 function updateData(data) { // 更新PM2.5 const pm25Value = document.getElementById('pm25-value'); pm25Value.textContent = `${data.pm25} µg/m³`; updatePM25Chart(data.pm25); ​ // 更新噪声 const noiseValue = document.getElementById('noise-value'); noiseValue.textContent = `${data.noise} dB`; updateNoiseChart(data.noise); ​ // 更新温湿度 const tempHumidityValue = document.getElementById('temp-humidity-value'); tempHumidityValue.textContent = `${data.temp}°C / ${data.humidity}%`; ​ // 更新加湿器状态 const humidifierStatus = document.getElementById('humidifier-status'); humidifierStatus.textContent = data.humidifier === 1 ? '开启' : '关闭'; } ​ // 更新PM2.5图表 function updatePM25Chart(pm25) { const pm25Chart = document.getElementById('pm25-chart').getContext('2d'); const chart = new Chart(pm25Chart, { type: 'bar', data: { labels: ['PM2.5'], datasets: [{ label: 'PM2.5含量', data: [pm25], backgroundColor: 'rgba(46, 204, 113, 0.6)', borderColor: 'rgba(46, 204, 113, 1)', borderWidth: 1 }] }, options: { responsive: true, scales: { y: { beginAtZero: true, max: 300 } } }); } ​ // 更新噪声图表 function updateNoiseChart(noise) { const noiseChart = document.getElementById('noise-chart').getContext('2d'); const chart = new Chart(noiseChart, { type: 'line', data: { labels: ['噪声'], datasets: [{ label: '噪声级别', data: [noise], borderColor: 'rgba(241, 196, 15, 1)', backgroundColor: 'rgba(241, 196, 15, 0.3)', borderWidth: 1 }] }, options: { responsive: true, scales: { y: { beginAtZero: true, max: 120 } } }); } ​ // 从服务器获取数据 function fetchData() { // 从服务器接收数据,您可以替换为从实际服务器获取 const mockData = { pm25: 65, noise: 80, temp: 25.3, humidity: 40, humidifier: 1 }; ​ updateData(mockData); } ​ // 每5秒获取一次数据 setInterval(fetchData, 5000); ​ // 初始化页面 fetchData();3.5 运行效果四、STM32代码设计在main.c文件中,进行必要的初始化,包括传感器、WIFI模块和USART接口,然后循环采集数据并通过TCP协议传输给服务器。#include "stm32f1xx_hal.h" #include "string.h" #include "stdio.h" #include "esp8266.h" // 假设ESP8266模块的驱动函数已编写 #include "pm25_sensor.h" // 假设PM2.5传感器的接口函数已编写 #include "noise_sensor.h" // 假设噪声传感器的接口函数已编写 #include "sht30.h" // 假设SHT30温湿度模块的接口函数已编写 ​ #define SERVER_IP "192.168.1.100" // 服务器IP地址 #define SERVER_PORT 8080 // 服务器端口 ​ // 函数声明 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); void send_data_to_server(char *data); ​ int main(void) { // 初始化硬件资源 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); ​ // 初始化ESP8266模块(假设该模块已初始化完毕) ESP8266_Init(); ​ // 初始化传感器(假设各传感器模块已初始化完毕) PM25_Init(); NoiseSensor_Init(); SHT30_Init(); ​ // 数据传输字符串 char data_buffer[100]; ​ while (1) { // 获取PM2.5数据 int pm25_value = PM25_ReadData(); ​ // 获取噪声数据 int noise_value = NoiseSensor_ReadData(); ​ // 获取温湿度数据 float temperature = SHT30_ReadTemperature(); float humidity = SHT30_ReadHumidity(); ​ // 获取加湿器开关状态(此处为模拟,如果有实际的继电器控制,请替换为实际代码) int humidifier_status = (pm25_value > 100) ? 1 : 0; ​ // 格式化数据字符串 snprintf(data_buffer, sizeof(data_buffer), "#%d,%d,%.1f,%.1f,%d\r\n", pm25_value, noise_value, temperature, humidity, humidifier_status); ​ // 发送数据到服务器 send_data_to_server(data_buffer); } } ​ void send_data_to_server(char *data) { // 通过ESP8266模块发送数据(假设ESP8266已经建立TCP连接) ESP8266_SendData(SERVER_IP, SERVER_PORT, data); } ​ void SystemClock_Config(void) { // 系统时钟配置代码(根据具体的硬件平台来配置) } ​ static void MX_GPIO_Init(void) { // GPIO初始化代码 } ​ static void MX_USART1_UART_Init(void) { // UART初始化代码,用于ESP8266与STM32通信 USART1_Init(); }硬件初始化:HAL_Init():初始化硬件抽象层。SystemClock_Config():系统时钟配置函数,通常根据具体硬件平台进行配置。MX_GPIO_Init() 和 MX_USART1_UART_Init():分别用于初始化GPIO和USART接口,这里USART1用于与ESP8266模块通信。传感器初始化:PM25_Init()、NoiseSensor_Init() 和 SHT30_Init()分别初始化PM2.5传感器、噪声传感器和温湿度模块。假设这些模块已经在其他地方编写好,并且能够提供相关数据。数据采集:PM25_ReadData():从PM2.5传感器读取PM2.5数据。NoiseSensor_ReadData():从噪声传感器读取噪声数据。SHT30_ReadTemperature() 和 SHT30_ReadHumidity():分别获取环境的温度和湿度数据。加湿器控制:humidifier_status变量控制加湿器的开关状态。当PM2.5浓度超过100时(这里是模拟阈值,实际值可根据需求调整),加湿器开启,状态为1;否则,状态为0。数据格式化与发送:使用snprintf格式化数据为符合要求的字符串:#PM2.5含量,噪声检测,环境温度,湿度检测,加湿器开关状态\r\n。send_data_to_server(data_buffer):通过ESP8266模块发送数据至服务器。ESP8266_SendData是与ESP8266通信的假设函数,具体的发送逻辑需要根据ESP8266的驱动进行实现。五、总结本项目设计了一个基于STM32的工地扬尘与噪音实时监测系统,通过集成多个传感器模块,实现了对工地环境中PM2.5、噪声、温湿度等参数的实时监控。系统通过无线通信技术(ESP8266模块)将数据上传至服务器,并通过Web界面进行可视化展示,方便用户进行远程监控和数据分析。加湿器控制功能也被集成到系统中,通过继电器控制加湿器来减少空气中的粉尘,确保环境的安全和健康。在硬件方面,系统选择了适合的传感器模块,如夏普PM2.5传感器、噪声传感器、SHT30温湿度模块等,以确保数据采集的准确性与稳定性。STM32F103RCT6作为主控芯片,承担着数据采集、处理和控制任务,通过I2C和SPI接口与各个模块进行连接与通信,确保系统的高效运行。通过WIFI模块ESP8266实现数据的远程传输,使得系统具备了实时监控和远程管理的能力。在软件和通信部分,系统采用了TCP协议和Flask框架,通过Web浏览器展示实时数据,为用户提供了便捷的操作界面。Python的Socket模块用于建立TCP连接,确保设备与服务器之间的数据传输稳定可靠。通过这些设计,用户可以方便地获取工地环境的实时数据,并根据需求进行进一步的分析和处理。通过该系统的设计与实现,不仅能实时监测工地环境的空气质量、噪声水平、温湿度等关键指标,还能通过智能控制(如加湿器)改善环境条件,提高工地工作人员的工作环境安全性。未来,该系统可以进一步扩展功能,如加入更多环境参数的监测、支持多种通信方式、增强数据分析功能等,以应对更复杂的实际应用场景。本项目实现了一个高效、实时、可视化的环境监控系统,展示了STM32在物联网和智能监测领域的广泛应用潜力。通过硬件和软件的有机结合,系统不仅满足了当前工地扬尘与噪音监测的需求,还为类似的环境监控系统提供了可参考的设计思路和技术实现。
  • 【开发者日南京站】产品体验官:快速上手TinyEngine低代码引擎插件开发
    华为云开发者日·南京站来啦!参加“快速上手TinyEngine低代码引擎插件开发”体验项目提出你的建议或使用体验有机会获得开发者盲盒礼包惊喜不容错过,快叫上小伙伴一起来参加吧~【体验项目】快速上手TinyEngine低代码引擎插件开发【活动时间】2024年10月25日-10月31日【参与方式】直接在此活动帖下方回帖提建议/提建议即可比如对产品功能的改进建议、对活动流程的感想、对现场活动的感悟等等PS:不要少于30字哦~【获奖规则】奖项设置有效回复楼层评选条件获奖名额激励礼品优质建议奖20对产品功能有改进价值的建议1名开发者盲盒礼品价值50-100元积极反馈奖20优质建议奖轮空的情况下进行抽取每满20层抽取1名开发者盲盒礼品价值50元【活动规则】1、本帖的回帖建议不少于30字,仅限于对“快速上手TinyEngine低代码引擎插件开发”体验项目,其他项目建议不参与此次活动,否则将视为无效内容。2、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;以上奖品均为实物奖品,具体发放视出库情况而定;3、活动预计于结束后七天内完成奖项公示,并于结束后15个工作日内完成邮寄。【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
  • 【开发者日南京站】产品体验官:CodeArts云上持续规划与设计实践
    华为云开发者日·南京站来啦!参加“CodeArts云上持续规划与设计实践”体验项目提出你的建议或使用体验有机会获得开发者盲盒礼包惊喜不容错过,快叫上小伙伴一起来参加吧~【体验项目】CodeArts云上持续规划与设计实践【活动时间】2024年10月25日-10月31日【参与方式】直接在此活动帖下方回帖提建议/提建议即可比如对产品功能的改进建议、对活动流程的感想、对现场活动的感悟等等PS:不要少于30字哦~【获奖规则】奖项设置有效回复楼层评选条件获奖名额激励礼品优质建议奖20对产品功能有改进价值的建议1名开发者盲盒礼品价值50-100元积极反馈奖20优质建议奖轮空的情况下进行抽取每满20层抽取1名开发者盲盒礼品价值50元【活动规则】1、本帖的回帖建议不少于30字,仅限于对“CodeArts云上持续规划与设计实践”体验项目,其他项目建议不参与此次活动,否则将视为无效内容。2、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;以上奖品均为实物奖品,具体发放视出库情况而定;3、活动预计于结束后七天内完成奖项公示,并于结束后15个工作日内完成邮寄。【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
  • [产品体验官] 【开发者日武汉站】产品体验官:CodeArts云上持续规划与设计实践
    华为云开发者日·武汉站来啦!参加“CodeArts云上持续规划与设计实践”体验项目提出你的建议或使用体验有机会获得开发者盲盒礼包惊喜不容错过,快叫上小伙伴一起来参加吧~【体验项目】CodeArts云上持续规划与设计实践【活动时间】2024年10月16日-10月20日【参与方式】直接在此活动帖下方回帖提建议/提建议即可比如对产品功能的改进建议、对活动流程的感想、对现场活动的感悟等等PS:不要少于30字哦~【获奖规则】奖项设置有效回复楼层评选条件获奖名额激励礼品优质建议奖20对产品功能有改进价值的建议1名开发者盲盒礼品价值50-100元积极反馈奖20优质建议奖轮空的情况下进行抽取每满20层抽取1名开发者盲盒礼品价值50元【活动规则】1、本帖的回帖建议不少于30字,仅限于对“CodeArts云上持续规划与设计实践”体验项目,其他项目建议不参与此次活动,否则将视为无效内容。2、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;以上奖品均为实物奖品,具体发放视出库情况而定;3、活动预计于结束后七天内完成奖项公示,并于结束后15个工作日内完成邮寄。【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
  • [技术干货] 图像分析处理技术:从基础到应用的未来趋势
    图像分析处理技术是计算机视觉领域的核心,涉及图像的获取、处理、分析和理解。随着人工智能和机器学习技术的飞速发展,图像分析处理技术在各行各业中扮演着越来越重要的角色。本文将探讨图像识别、图像分析以及图像处理技术的特点、应用场景和技术方案,并展望其未来的发展趋势与挑战。一、图像识别技术图像识别是图像分析处理技术的一个重要分支,它涉及到从图像中识别出特定的对象、场景或活动。这一技术的核心是模式识别,即通过算法识别图像中的模式并将其与已知的模式进行匹配。特点自动化:自动识别图像中的对象,无需人工干预。高效率:能够快速处理大量图像数据。高准确率:随着模型训练的深入,识别准确率可以非常高。可扩展性:可以应用于不同的图像识别任务,如面部识别、车牌识别等。应用场景面部识别:用于安全验证和个人身份确认。物体识别:在零售、物流等领域自动识别商品。场景识别:在自动驾驶中识别道路和交通标志。典型技术方案卷积神经网络(CNN):一种深度学习模型,特别适用于图像识别任务。支持向量机(SVM):一种监督学习模型,用于分类和识别。深度信念网络(DBN):由多个受限玻尔兹曼机堆叠而成的深度学习模型。二、图像分析技术图像分析不仅包括图像识别,还包括对图像内容的深入分析和理解。图像分析通常涉及到图像的预处理、特征提取、模式识别和决策制定。特点复杂性:分析过程涉及多个步骤,需要复杂的算法。多维度:不仅识别图像中的对象,还分析其属性和关系。适应性:能够适应不同的图像条件和环境。应用场景医疗图像分析:在放射学中分析X光片、CT扫描和MRI图像。卫星图像分析:用于地理信息系统(GIS)和环境监测。视频监控分析:在安全监控中分析视频流以检测异常行为。典型技术方案图像分割:将图像分割成多个区域或对象的技术。特征提取:从图像中提取关键特征,如边缘、角点等。机器学习算法:包括决策树、随机森林等,用于图像分析的分类和回归任务。三、图像处理技术图像处理技术是图像分析处理技术的基础,它涉及到对图像数据的修改、改善和转换,以满足特定的应用需求。特点多样性:处理方法多样,可以根据需求选择不同的技术。实时性:许多图像处理操作可以实时进行,适用于视频流等动态图像。可定制性:可以根据具体的应用场景定制处理流程。应用场景图像增强:提高图像的可见性,如对比度增强、亮度调整等。滤波:去除图像噪声,如高斯滤波、中值滤波等。图像变换:进行图像的几何变换,如旋转、缩放、裁剪等。典型技术方案图像滤波器:用于平滑图像或突出图像的某些特征。图像变换算法:如傅里叶变换、小波变换等,用于分析图像的频域特性。图像增强技术:包括直方图均衡化、锐化等,用于改善图像的视觉质量。四、技术对比虽然图像识别、图像分析和图像处理紧密相关,但它们各自有不同的侧重点和应用场景:图像识别:侧重于从图像中识别出特定的对象或场景;通常需要较高的计算资源,依赖于复杂的算法和模型。图像分析:不仅识别图像内容,还深入分析图像的特征和属性;侧重于理解和解释图像内容,可能涉及到复杂的决策过程。图像处理:更多关注图像质量的改善和信息的提取,不一定需要复杂的模型;更多是技术性的,关注图像数据的修改和转换。尽管存在差异,但这些技术经常相互融合,共同解决复杂的图像分析问题。例如,图像处理可以作为图像识别和分析的预处理步骤,而图像分析的结果又可以用于指导图像处理的方向。五、应用方向图像分析处理技术的应用领域非常广泛,以下是一些主要的应用方向:工业自动化在工业自动化中用于质量控制、机器人导航和装配线监控。通过图像识别和分析,机器可以自动检测产品缺陷、分类物品和执行精确的操作。医疗健康在医疗领域,图像分析处理技术用于诊断、治疗规划和手术辅助。例如,通过分析医学影像,医生可以更准确地识别疾病和制定治疗方案。安全监控安全监控是图像分析技术的另一个重要应用领域。通过实时视频分析,可以检测异常行为、入侵者和其他安全威胁。社交媒体与娱乐在社交媒体和娱乐行业,图像分析用于内容推荐、用户交互和增强现实(AR)体验。例如,通过面部识别技术,用户可以在社交媒体上创建有趣的滤镜和效果。交通管理图像分析在交通管理中用于交通流量监控、事故检测和交通违规识别。这有助于提高道路安全性和交通效率。农业监测在农业领域,图像分析用于作物监测、病虫害检测和产量预测。通过分析卫星图像和无人机拍摄的图像,农民可以更好地管理作物和资源。六、未来趋势与挑战图像分析处理技术正在快速发展,同时也面临着一些挑战。技术发展趋势更深层次的网络结构:随着计算能力的提升,更深的网络结构正在被开发,以提高识别和分析的准确性。端到端学习:从输入到输出的端到端学习正在成为趋势,减少了对中间特征工程的依赖。多模态学习:结合视觉信息和其他类型的数据(如文本、声音)进行多模态学习。面临的挑战数据隐私:随着图像数据的大量收集和分析,如何保护个人隐私成为一个重要问题。算法偏见:机器学习模型可能会学习到训练数据中的偏见,导致不公平的结果。可解释性:深度学习模型通常被认为是“黑箱”,提高模型的可解释性是一个挑战。潜在的解决方案隐私保护技术:如差分隐私和联邦学习,可以在不泄露个人数据的情况下进行学习。公平性算法:开发新的算法来减少模型的偏见,提高决策的公平性。模型解释性:研究新的技术来解释深度学习模型的决策过程。七、总结图像分析处理技术是当今科技领域中最活跃和最有前景的领域之一。从基础的图像处理到复杂的图像识别和分析,这些技术正在不断进步,并被应用于各种实际问题中。图像分析处理技术对于提高生产效率、改善生活质量、增强安全保障等方面发挥着重要作用。不同的技术方案针对不同的应用场景,显示了这一领域的多样性和创新性。随着技术的发展,我们也必须面对数据隐私、算法偏见和模型可解释性等挑战。图像分析处理技术将继续发展,新的技术、算法和应用将不断涌现,为社会带来更多的价值。
  • [技术干货] 基于STM32+微波雷达设计的非接触式睡眠监控系统(服务器采用华为云IOT)
    一、前言1.1 项目介绍项目设计里用到的全部工具软件都可以在这里下载。cid:link_2【1】项目开发背景随着现代生活节奏的加快,人们对于健康管理的需求日益增长,尤其是对于睡眠健康的关注度显著提升。良好的睡眠质量不仅关系到个人的精神状态,更直接影响着工作和学习效率乃至整体生活质量。然而,快节奏的生活压力、不规律的生活作息等因素导致越来越多的人遭受睡眠障碍的困扰。传统的睡眠监测方式通常需要佩戴设备或接触式传感器,这可能会干扰到用户的自然睡眠状态,从而影响监测结果的准确性。因此,开发一种非接触式的睡眠监测系统,成为了提高睡眠质量研究的重要方向之一。非接触式睡眠监测技术的发展,得益于近年来毫米波雷达技术的进步。毫米波雷达具有高精度、强穿透力的特点,可以在不直接接触人体的情况下,精准地捕捉到人体微动,如呼吸和心跳等细微动作。这种技术的应用,不仅可以避免传统监测手段可能带来的不适感,还能在用户不知情的状态下进行连续监测,保证了数据的真实性和有效性。与此同时,物联网技术的发展使得数据的远程传输与分析成为可能,进一步推动了智能健康监测系统的普及。本项目正是基于这样的背景下展开的。它利用了60GHz毫米波雷达技术,结合高性能的STM32微控制器,设计了一套完整的非接触式睡眠监控系统。该系统不仅能准确地获取用户的睡眠信息,还能通过Wi-Fi连接云端,让用户可以通过手机应用程序随时查看自己的睡眠报告。此外,系统还具备异常生理指标报警功能,能够在第一时间提醒用户注意健康状况,为用户提供了一个全方位、智能化的健康管理方案。通过这一创新性的解决方案,期望能够帮助更多人改善睡眠质量,提升生活质量。设备安装角度:【2】设计实现的功能(1)人体存在感知与运动感知:通过使用60GHz频段的毫米波雷达模块,系统能够感知房间内是否存在人体以及人体的微小运动,如呼吸和心跳的变化。(2)睡眠状态监测:系统能够根据睡眠过程中身体的运动幅度变化和呼吸心率的变化,实时判断目标的睡眠状态,并在睡眠周期结束后提供一个综合的睡眠评分。(3)生理指标检测:系统能够检测并记录睡眠者的心率、呼吸频率等重要生理指标,这些数据有助于分析睡眠质量。(4)远程数据上传与查看:系统集成了Wi-Fi模块,可以将监测到的睡眠数据上传到华为云物联网平台,用户可以通过智能手机应用程序远程查看每天的睡眠质量报告和其他生理指标。(5)异常情况报警:当检测到的生理指标超出预设的安全阈值时,系统会触发报警机制,及时通知用户或监护人可能存在健康风险。(6)本地数据显示:系统配备了1.44寸SPI协议的TFT LCD显示屏,用于实时显示监测到的生理指标及环境相关信息,便于用户即时查看。(7)体温检测:通过集成MLX90614红外体温传感器,系统能够检测人体体温,并将其作为一项重要的生理参数纳入睡眠质量评估体系中。【3】项目硬件模块组成(1)主控单元:选用STM32F103RCT6微控制器作为核心处理单元,负责接收来自各传感器的数据,并处理和控制系统的各项功能。(2)毫米波雷达模块:采用60GHz频段的R60ABD1毫米波雷达模块,用于非接触式地检测人体的存在、呼吸频率和心率等生理信号。(3)无线通信模块:集成ESP8266-Wi-Fi模块,实现数据的无线传输功能,确保睡眠数据能够实时上传至华为云物联网平台。(4)显示模块:采用1.44寸TFT LCD显示屏,分辨率为128x128像素,通过SPI协议与主控单元通讯,用于显示监测到的生理指标和环境信息。(5)体温检测模块:采用MLX90614红外体温传感器,用于无接触地测量人体体温,提供额外的健康监测数据。(6)电源管理模块:采用外置的5V稳压电压,包括电源转换电路和电池管理电路,确保整个系统能够稳定运行,并为各个模块提供所需电压。(7)报警模块:设计蜂鸣器声音形式的报警装置,当系统检测到异常生理指标时,能够及时提醒用户。【4】需求总结项目:基于STM32+微波雷达设计的非接触式睡眠监控系统​1. 可以实现 人体存在感知、人体运动感知、根据睡眠过程中的身体运动幅度变化和呼吸心率变化,对目标的睡眠状态、呼吸心跳频率进行实时判断,在一段睡眠过程结束后输出睡眠评分呼吸、能够检测心率、睡眠时长、睡眠质量等生理指标(此功能采用60GHz频段的毫波雷达来实现)2. 可以实现能将数据通过 ESP8266-WIFI上传到华为云物联网云平台、设计手机APP可以远程查看每天的睡眠质量、生理指标、环境相关信息。3. 可以实现当检测到的生理指标数据超过阈值时,系统发出报警提醒。 4. 可以实现能在本地LCD显示屏显示监测到的生理指标、环境相关信息。5. 支持检测人体体温。​ 硬件选型:主控芯片选择 STM32F103RCT6LCD显示屏采用1.44寸 SPI协议的 TFT显示屏,分辨率是128x128。人体体温检测采用MLX90614红外体温传感器。人体的呼吸、心率、采用60G毫米波 生物感知雷达R60ABD1模块来实现检测。呼吸睡眠雷达基于毫米波雷达体制实现人体生物存在感知及人体运动感知,持续记录人体存在情况,根据睡眠过程中的身体运动幅度变化和呼吸心率变化,对目标的睡眠状态、呼吸心跳频率进行实时判断,在一段睡眠过程结束后输出睡眠评分,根据相关睡眠参数的输出结合到健康康养的应用上。1.2 设计思路设计思路源于对现代人睡眠健康需求的关注以及对现有睡眠监测技术局限性的思考。在设计之初,注意到传统的睡眠监测手段往往依赖于接触式的穿戴设备,这种方式虽然能够提供较为精确的数据,但却有可能影响用户的自然睡眠状态。因此,设计目标是创造一个非侵入式的睡眠监控系统,能够让用户在自然的睡眠环境中得到准确而有效的监测。为了实现这一目标,选择了60GHz频段的毫米波雷达技术作为主要的监测手段。毫米波雷达具有非接触、高分辨率和强穿透性等特点,非常适合用来监测人体微弱的生理信号,如呼吸和心跳。通过算法优化,能够从雷达回波中提取出稳定的呼吸和心跳信号,并据此评估睡眠质量和生理指标。考虑到用户体验的重要性,决定将系统与互联网技术相结合,通过ESP8266-Wi-Fi模块将睡眠数据上传至云端,方便用户通过智能手机应用程序随时随地查看自己的睡眠报告。同时,为了应对突发状况,设计了阈值报警机制,当检测到异常生理指标时,系统能够立即向用户发出警告,以确保用户的安全。硬件选型方面,选择了性能稳定且广泛使用的STM32F103RCT6作为主控芯片,以确保系统的可靠性和可扩展性。为了直观展示数据,选用了1.44寸的TFT LCD显示屏,它可以清晰地显示监测到的各项生理指标和环境信息。此外,还加入了MLX90614红外体温传感器,以便系统能够监测用户的体温变化,进一步完善健康监测功能。总体的设计思路是在不干扰用户正常生活的情况下,利用先进的毫米波雷达技术和物联网平台,创建一个能够全天候监测睡眠状态、生理指标,并及时反馈给用户的智能系统。这样不仅能够帮助用户更好地了解自己的睡眠质量,还能在出现异常时提供及时的帮助,从而提升整体的生活品质。1.3 系统功能总结功能类别描述人体存在感知利用60GHz毫米波雷达检测房间内是否有人存在。运动感知感知人体的微小运动,如呼吸和心跳。睡眠状态监测根据身体运动幅度变化和呼吸心率变化实时判断睡眠状态。生理指标检测记录并分析心率、呼吸频率等重要生理指标。远程数据上传通过ESP8266-Wi-Fi模块将监测数据上传至华为云物联网平台。移动端查看用户可以通过手机应用程序远程查看睡眠质量报告和其他生理指标。异常报警当检测到的生理指标超过设定阈值时,系统会发出报警提醒。本地数据显示通过1.44寸TFT LCD显示屏实时显示监测到的生理指标和环境信息。体温检测使用MLX90614红外体温传感器检测人体体温,并将其纳入健康监测数据中。1.4 开发工具的选择【1】设备端开发STM32的编程语言选择C语言,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是有点不适应界面的。【2】上位机开发上位机的开发选择Qt框架,编程语言采用C++;Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。Qt能轻松创建具有原生C++性能的连接设备、用户界面(UI)和应用程序。它功能强大且结构紧凑,拥有直观的工具和库。1.5 模块的技术详情介绍【1】ESP8266-WIFI模块ESP8266是一款广受欢迎的低成本、低功耗的Wi-Fi模块,广泛应用于物联网(IoT)领域。它由乐鑫科技(Espressif Systems)开发,最初作为一款简单易用的无线模块推向市场,但因其强大的功能和灵活性迅速获得了开发者们的青睐。ESP8266内置了Tensilica L106超低功耗32位微处理器,主频最高可达160MHz,并且拥有512KB的SRAM,这使得它不仅能够作为一个简单的Wi-Fi模块使用,还可以作为独立的微控制器来执行复杂的任务。ESP8266模块支持IEEE 802.11 b/g/n标准,能够工作在2.4GHz频段上。它具有多种工作模式,包括Station模式(客户端)、Access Point模式(热点)以及Station+AP模式(同时作为客户端和热点)。这意味着它可以连接到现有的Wi-Fi网络,也可以自己创建一个Wi-Fi热点供其他设备连接,极大地增加了其在不同应用场景中的适用性。对于开发者而言,ESP8266的一个重要优势在于其丰富的开发资源和支持。乐鑫科技提供了详细的开发文档,包括硬件接口说明、固件升级指南和API参考手册等。此外,ESP8266还支持多种编程语言,如C/C++和Lua,同时还有成熟的开发框架如Arduino IDE的支持,使得开发者能够快速上手,并利用各种库函数简化开发流程。ESP8266的低功耗特性也是一大亮点,它提供了多种省电模式,可以根据实际应用需求调整工作状态,以延长电池寿命。这对于那些依赖电池供电的物联网设备来说尤为重要。ESP8266凭借其出色的性价比、强大的功能、易于开发的特性以及广泛的社区支持,已经成为许多DIY项目、智能家居设备和小型物联网应用的理想选择。无论是作为独立的微控制器还是作为Wi-Fi模块,ESP8266都能够满足大多数物联网项目的需求。【2】MLX90614红外体温传感器MLX90614红外体温传感器是由Melexis公司生产的一款高性能、非接触式温度测量传感器。这款传感器集成了红外温度测量功能与环境温度测量功能于一体,适用于需要快速、准确测量物体表面温度的应用场合。由于其非接触式的特点,MLX90614特别适合用于医疗领域,如监测人体体温,以及其他工业或商业用途,例如食品温度检测、设备过热保护等。MLX90614的工作原理基于红外辐射理论。所有物体都会发射红外辐射,其强度与物体的温度成正比。MLX90614通过检测目标物体发射的红外辐射能量,并结合传感器所在环境的温度,计算出目标物体的表面温度。这款传感器具有较高的灵敏度,能够检测到非常微小的温度变化,并且具有较好的响应速度。从硬件角度来看,MLX90614采用了SMD(Surface Mount Device)封装,使其易于集成到各种设备中。它具有数字I²C接口,可以方便地与微控制器或其他数字系统进行通信。此外,MLX90614还提供了不同的视场角版本,允许用户根据具体的应用需求选择最适合的角度,从而获得最准确的测量结果。在使用MLX90614时,需要注意几个关键参数。首先是距离系数(Distance-to-Spot Size Ratio),即传感器与目标之间的距离与目标面积直径之比。这个参数决定了传感器的有效测量区域大小。其次是传感器的温度测量范围,一般为-70°C至+380°C,足以覆盖大部分日常应用。此外,MLX90614还具备较高的测温精度,通常在±0.5°C左右,这使得它在医疗和工业应用中具有很高的实用性。对于开发人员来说,MLX90614的另一个优点是其易于集成。Melexis提供了详尽的技术文档和支持,包括电路设计指南、编程示例等资源,使得开发者能够快速地将MLX90614集成到他们的产品中。此外,市面上也有许多现成的开发板和库文件,可以帮助开发者简化开发流程,加速产品的上市时间。综上所述,MLX90614红外体温传感器以其高精度、非接触式测量的特点,在多个行业中得到了广泛应用,尤其是在需要快速、准确温度读数的场合。【3】微波雷达模块生物感知雷达R60ABD1模块是一款基于60GHz毫米波雷达技术的产品,专为人体呼吸心率感知及睡眠评估而设计。它采用FMCW(调频连续波)雷达体制,能够针对特定场合内的人员进行呼吸心率频率的输出,并结合长时间的睡眠姿态体动采集,及时上报人员的睡眠状态和历史记录。模块的一发三收天线形式使得它适合于置顶安装模式,能够精准扫描人体全身的动作层析,实现人体动静态时的睡眠探测和不同姿态下的呼吸心率采集。该模块的工作原理基于雷达天线发射电磁波信号,并接收目标反射回来的回波信号。通过雷达处理器解析不同接收天线回波信号的波形参量之间的相位差和能量变化,从而反馈目标运动的微动能量变化、距离、方向和速度等信息。这使得R60ABD1模块能够探测目标的运动状态和胸腔呼吸起伏的频次状态。在雷达探测范围内,即便是轻微的手部晃动或呼吸引起的胸腔起伏等微小运动,也能够被模块捕捉到。R60ABD1模块具有多种功能,包括运动检测、呼吸探测、呼吸心率频率采集等功能。模块能够检测到诸如走动或小幅度手晃动等运动,并触发有人状态的指示。当人处于静止状态时,模块也能检测到由呼吸引起的胸腔起伏,并维持有人状态的输出。更重要的是,它能统计呼吸心跳引起的胸腔起伏,并输出每分钟的呼吸心跳数值。这些功能使得该模块在全屋智能、智能家电、区域人员探测和睡眠看护等领域有着广泛的应用前景。该模块的电气特性包括工作电压在4.6V至6V之间,典型工作电流为93mA,工作温度范围从-20°C至+60°C,存储温度范围则从-40°C至+105°C。其RF性能方面,工作频率位于61GHz至61.5GHz区间,发射功率不超过6dBm。天线增益为4dBi,水平和垂直波束宽度均为20°(-3dB点)。R60ABD1模块提供了标准的UART通信接口,并支持涂鸦协议,便于与其他设备集成。模块尺寸小巧,体积仅为35mm×31mm×7.5mm,并配有双排插针接口,接口间距为2.0mm。这些接口包括电源输入、地、串口接收和发送端、以及多个可定义的通用I/O引脚。其中,部分引脚可用于输出有人/无人状态、活跃/静止状态、体征参数等信息。此外,模块还支持多种参数设置,如人体存在开关、呼吸探测开关、心跳探测开关、睡眠探测开关以及探测模式切换开关(实时探测/睡眠模式)。这些设置使得模块可以根据不同应用场景的需求进行灵活配置。在安装方面,R60ABD1模块推荐倾斜安装,并且平行于扫描面的距离不超过1.5米。特别是用于睡眠呼吸心跳探测时,雷达应安装在床头正上方1米的高度,向下倾斜45°对着床中间,确保雷达与人体胸腔的距离在1.5米范围内,以确保雷达正常进行探测。1.6 微波雷达安装说明生物感知雷达R60ABD1模块的安装需要遵循特定的指导原则以确保其最佳性能。首先,雷达模块应该朝向为丝印标识的方向进行安装,这意味着在安装时需要确保雷达的正面朝向正确。为了达到理想的探测效果,R60ABD1雷达模块建议采用倾斜安装的方式,倾斜角度应在30到45度之间。这种安装方式有助于雷达的波束覆盖到所需的探测区域,并且可以减少因环境因素引起的误报。在确定雷达的具体安装位置时,建议将雷达安装在床头正上方大约1米的高度处,这样可以确保雷达的主要波束能够覆盖到床的中心区域。这样做是为了确保雷达可以有效地探测到床上人的呼吸和心跳活动,同时也能够监测到人体的其他微动。安装高度的选择也是基于雷达波束覆盖范围的考虑,以确保人体存在检测的最大距离为约2.5米,而人体呼吸频率检测的最大距离约为1.5米。除了正确的安装位置和角度外,还需要注意避免雷达前方出现明显的金属或电解质遮挡物。这是因为毫米波雷达的探测机制依赖于雷达波的反射,如果存在金属或电解质遮挡物,则可能会影响雷达波的反射路径,从而影响到雷达的探测准确性。因此,在安装雷达时,应确保雷达前方没有诸如金属窗帘条、风扇、空调电机等潜在的干扰源。在实际安装过程中,还应当注意雷达模块的安装高度和角度会影响到其探测效果。为了使雷达的主波束能够覆盖到整个睡眠区域,雷达的安装高度应该保持在与床面的高度差在0.9米左右,误差不超过0.2米。同时,雷达模块的安装需要保证其前方没有明显的遮挡物,尤其是金属材质的物体,因为这些物体可能会反射雷达波,造成干扰。为了确保雷达能够正常工作,安装完成后还需注意雷达模块的供电稳定性。雷达模块对电源品质有一定的要求,需要无门限毛刺或纹波现象,并且需要有效屏蔽来自附近设备的电源噪声。为了保证模块内部VCO电路的正常工作,雷达模块需要+5V到+6V的供电,且电压纹波不能超过100mV。外部电源还需要提供足够的电流输出能力和瞬态响应能力,以防止由于电源不稳定导致的探测距离缩短或误报率增加等问题。1.7 微波雷达的完整功能概述(快速上手)R60ABD1呼吸睡眠雷达模组是一款基于60GHz毫米波雷达技术设计的非接触式生物感知设备,主要用于人体存在感知及运动感知。它能够根据睡眠过程中身体运动幅度变化和呼吸心率变化,实时判断目标的睡眠状态、呼吸心跳频率,并在睡眠结束后输出睡眠评分。该模组的探测功能不受温度、湿度、噪声气流、尘埃、光照和人体完全静止等因素的影响,适合安装在室内顶部使用。模组具备多种功能,包括有人/无人状态检测、人体静止/活跃状态切换检测、人体距离主动上报、体动幅度参数输出、人体方位上报、心跳数值及波形输出、呼吸数值及波形输出、入床/离床状态判断、睡眠状态(清醒/浅睡/深睡)识别、清醒/浅睡/深睡时长统计、睡眠质量评分、睡眠异常上报、异常挣扎上报、无人计时上报以及睡眠质量评级上报等。这些功能通过不同的数据点(DP)以特定的时间间隔或状态变化时上报。为了确保雷达的准确探测,模组的安装需要遵循一定的规范。雷达应该安装在床头正上方1米的高度,向下倾斜30至45度,以确保主波束能够覆盖到睡眠区域。此外,雷达前方不应有明显的金属或电解质遮挡物,以免影响探测效果。在安装过程中,还需确认雷达探测范围内是否存在干扰源,如空调、风扇等,并尽可能移除这些干扰源。模组的引脚包括电源输入、地、串口接收与发送端、以及若干备用扩展引脚。其中,部分引脚可以根据用户需求重新定义功能。为了便于用户操作,在官方的文档还介绍了如何准备必要的工具,如TTL串口工具、杜邦线、PC电脑、串口助手终端和Radar-EVB demo板,并给出了上电及工作的数据上报规则和睡眠模式检测逻辑。在官方的文档最后提供了主要功能测试指引,包括睡眠质量状态判断测试、入离床状态判断测试、离床状态判断测试、呼吸频率测试以及心跳频率测试等。每项测试都有明确的操作步骤和判定标准,以帮助用户验证模组的功能是否正常。此外,官方的文档还对体动幅度参数的输出进行了详细说明,并附带了相关的测试表格格式,便于用户记录和分析测试结果。二、微波雷达调试过程2.1 接线说明2.2 安装说明倾斜安装: * 确保雷达探测准确性,建议安装在床头上方,以 45°斜向下安装! R60ABD1-呼吸睡眠雷达倾斜安装,倾斜角度为 30~45°,安装在床头上方,雷达安装高度建议为高于床面 0.8-1m;保证雷达主波束覆盖探测区域;雷达前面无明显(金属/电解质)遮挡物及覆盖物。受雷达安装高度及雷达波束范围影响,在该安装模式下,人体存在检测最大距离 L3 ≈ 2.5 米;睡眠检测最大距离 L2 ≈ 2.5 米;人体呼吸频率检测最大距离 L1 ≈ 1.5 米。2.3 连接电脑调试将60G毫米波雷达模块与电脑连接,调试模块是否正常可以运行,60G毫米波雷达模块默认的波特率是115200GND-----GNDVCC-----VCCTX------RXRX------TX串口调试助手返回的数据:睡眠雷达上位机:三、华为云服务器部署与上位机APP开发这里直接看视频,可以了解的更加清楚。(1)华为云物联网开发(一)设备上云:cid:link_0(2)华为云物联网云平台对应的上位机开发步骤:cid:link_1四、STM32代码开发(微波雷达模块数据处理)4.1 微波雷达数据处理(头文件)#ifndef _DATAHANDLE_H#define _DATAHANDLE_H​#include "stdint.h"​/* 定义包头及指令信息 *///帧头#define HEADER1 0x53#define HEADER2 0x59//控制字#define CMD_TICK 0x01 //心跳包#define CMD_PRODUCT_INFO 0x02 //产品信息#define CMD_OTA 0x03 // OTA升级#define CMD_WORK_STATE 0x05 //工作状态#define CMD_RADAR_DETECT_RANGE 0x07 //雷达探测范围#define CMD_BODY_EXIST_DETECT 0x80 //人体存在检测#define CMD_BREATH_DETECT 0x81 //呼吸检测#define CMD_SLEEP_DETECT 0x84 //睡眠检测#define CMD_HEART_DETECT 0x85 //心率检测//帧尾#define END1 0x54#define END2 0x43​/* 枚举读取数据报文的状态 */typedef enum{ IDLE, SEEN_HEADER1, SEEN_HEADER2, SEEN_CONTROL, SEEN_COMMAND, SEEN_LENGTH, SEEN_DATA, SEEN_SUM, SEEN_END1, SEEN_END2} rx_datagram_state_t;​/* 枚举控制模式 */typedef enum{ MODE_IDLE, MODE_SEND_TICK, MODE_SEND_PRODUCT_INFO, MODE_SEND_OTA, MODE_SEND_WORK_STATE, MODE_SEND_RADAR_DETECT_RANGE, MODE_SEND_BODY_EXIST_DETECT, MODE_SEND_BREATH_DETECT, MODE_SEND_SLEEP_DETECT, MODE_SEND_HEART_DETECT} control_mode_t;​/*******************************************************************************///人体存在功能typedef struct{ uint8_t body_exist_flag; //有人无人检测标志 uint8_t work_state; //运动状态 uint8_t body_move_param; //体动参数 uint16_t body_distance; //人体距离 uint8_t body_direction[3]; //人体方位} body_exist_detect_t;​//呼吸检测功能typedef struct{ uint8_t breath_detect_switch; //开关呼吸功能 uint8_t breath_detect_state; //呼吸检测状态 uint8_t breath_detect_value; //呼吸检测值 uint8_t breath_wave_data[5]; //呼吸波形} breath_detect_t;​//睡眠评分typedef struct{ uint8_t sleep_detail_exist; //睡眠详细状态 uint8_t sleep_detail_state; //睡眠详细评分​ uint8_t sleep_detail_score; //睡眠评分 uint16_t sleep_detail_time; //睡眠时间 uint8_t sleep_detail_awake; //清醒时长占比 uint8_t sleep_detail_light; //浅睡时长占比 uint8_t sleep_detail_deep; //深睡时长占比 uint8_t sleep_detail_away; //离床时长占比 uint8_t sleep_detail_away_times; //离床次数 uint8_t sleep_detail_turn_over_times; //翻身次数 uint8_t sleep_detail_avg_breath; //平均呼吸 uint8_t sleep_detail_avg_heart; //平均心率 uint8_t sleep_detail_breath_stoptimes; //呼吸停顿次数 uint8_t sleep_detail_turn_over_L; //大动作次数 uint8_t sleep_detail_turn_over_S; //小动作次数} sleep_detail_t;​//睡眠检测功能typedef struct{ uint8_t sleep_detect_switch; //开关睡眠功能 uint8_t sleep_bed_state; //入床/离床状态 uint8_t sleep_detect_state; //睡眠检测状态​ uint8_t sleep_wake_hour; //清醒时间 uint8_t sleep_light_hour; //浅睡时长 uint8_t sleep_deep_hour; //深睡时长​ uint8_t sleep_score; //睡眠质量评分 sleep_detail_t sleep_score_detail; //睡眠质量评分详情 sleep_detail_t sleep_score_detail_1; //睡眠质量评分详情1 uint8_t sleep_score_detail_err; //睡眠质量评分详情2} sleep_detect_t;​//心率检测功能typedef struct{ uint8_t heart_detect_switch; //开关心率功能 uint8_t heart_detect_value; //心率检测值 uint8_t heart_wave_data[5]; //心率波形} heart_detect_t;​//数据变化标志typedef struct{ unsigned data_change_body_exist : 1; unsigned data_change_breath : 1; unsigned data_change_sleep : 1; unsigned data_change_heart : 1;} data_change_t;​void ProcessRx(uint8_t *buff,uint8_t size);// void ProcessRx(void);​​extern body_exist_detect_t body_exist_detect;extern breath_detect_t breath_detect;extern sleep_detect_t sleep_detect;extern heart_detect_t heart_detect;​#endif​4.2 微波雷达数据处理(源文件)#include "datahandle.h"#include "debug.h"body_exist_detect_t body_exist_detect = {0};breath_detect_t breath_detect = {0};sleep_detect_t sleep_detect = {0};heart_detect_t heart_detect = {0};data_change_t data_change = {0};​/* 定义数据包接收状态的变量,并初始化为空闲状态 */rx_datagram_state_t rx_datagram_state = IDLE;control_mode_t control_mode = MODE_IDLE;​/* 协议数据处理函数 */void ProcessRx(uint8_t *buff, uint8_t size){ /****************************************************************************/ uint8_t receivedbyte, rx_sum, command; //数据存储数组 uint8_t rx_data[10];​ uint16_t rx_dategram_len; while (size) { switch (rx_datagram_state) { case IDLE: //在空闲时,判断是否读取帧头1 { receivedbyte = *buff; if (HEADER1 == receivedbyte) { // printf("HEADER1:%x\n", *buff); rx_sum = 0; rx_sum += receivedbyte; rx_datagram_state = SEEN_HEADER1; buff++; } break; } case SEEN_HEADER1: //读取第一帧之后,判断是否读取帧头2 { receivedbyte = *buff; if (HEADER2 == receivedbyte) { // printf("HEADER2:%x\n", *buff); rx_sum += receivedbyte; rx_datagram_state = SEEN_HEADER2; buff++; } break; }​ case SEEN_HEADER2: //读取第二帧后,根据控制字判断数据模式 { uint8_t ctrl_mode = *buff; //控制字 rx_sum += ctrl_mode;​ if (ctrl_mode == CMD_TICK) control_mode = MODE_SEND_TICK; else if (ctrl_mode == CMD_PRODUCT_INFO) control_mode = MODE_SEND_PRODUCT_INFO; else if (ctrl_mode == CMD_OTA) control_mode = MODE_SEND_OTA; else if (ctrl_mode == CMD_WORK_STATE) control_mode = MODE_SEND_WORK_STATE; else if (ctrl_mode == CMD_RADAR_DETECT_RANGE) control_mode = MODE_SEND_RADAR_DETECT_RANGE; else if (ctrl_mode == CMD_BODY_EXIST_DETECT) control_mode = MODE_SEND_BODY_EXIST_DETECT; else if (ctrl_mode == CMD_BREATH_DETECT) control_mode = MODE_SEND_BREATH_DETECT; else if (ctrl_mode == CMD_SLEEP_DETECT) control_mode = MODE_SEND_SLEEP_DETECT; else if (ctrl_mode == CMD_HEART_DETECT) control_mode = MODE_SEND_HEART_DETECT; else control_mode = MODE_IDLE;​ rx_datagram_state = SEEN_CONTROL; // printf("SEEN_CONTROL:%x\n", ctrl_mode); buff++; } break;​ case SEEN_CONTROL: //读取控制字后,判断命令字 { command = *buff; //命令字 rx_sum += command; rx_datagram_state = SEEN_COMMAND; // printf("SEEN_COMMAND:%x\n", command); buff++; } break;​ case SEEN_COMMAND: //读取命令字后,识别数据长度 { uint8_t len_temp[2]; len_temp[0] = *buff; rx_sum += len_temp[0];​ buff++; len_temp[1] = *buff; rx_sum += len_temp[1];​ rx_dategram_len = (len_temp[0] << 8) | len_temp[1]; rx_datagram_state = SEEN_LENGTH; // printf("SEEN_LENGTH:%x\n", rx_dategram_len); buff++; } break;​ case SEEN_LENGTH: //读取数据长度后,保存数据 { if (size < (int)rx_dategram_len) //判断数据包是否完整 { rx_datagram_state = IDLE; return; } uint8_t readlen = rx_dategram_len; //数据包长度 uint8_t tmp[rx_dategram_len]; //数据包缓存 uint8_t *ptmp = tmp; //数据包缓存指针 while (readlen--) { receivedbyte = *buff; *ptmp++ = receivedbyte; //将数据存入缓存 rx_sum += receivedbyte; //校验和 } // TODO 使用上面操作,可以直接操作rx_data指针,不用拷贝数据到rx_data数组中 for (uint8_t i = 0; i < rx_dategram_len; i++) //将数据存储到数组中 { rx_data[i] = tmp[i]; }​ rx_datagram_state = SEEN_DATA; buff++; } break;​ case SEEN_DATA: //读取数据后,判断校验和,根据数据、控制字、命令字读取状态 { uint8_t getsum = *buff;​ //判断校验和是否正确 if (getsum != rx_sum) { rx_datagram_state = IDLE; return; } else { //判断控制字模式 switch (control_mode) { case MODE_SEND_TICK: //心跳包 { printf("MODE_SEND_TICK\n"); } break;​ case MODE_SEND_PRODUCT_INFO: //产品信息 { printf("MODE_SEND_PRODUCT_INFO\n"); } break;​ case MODE_SEND_OTA: // OTA升级 { printf("MODE_SEND_OTA\n"); } break;​ case MODE_SEND_WORK_STATE: //工作状态 { printf("MODE_SEND_WORK_STATE\n"); } break;​ case MODE_SEND_RADAR_DETECT_RANGE: //雷达检测范围 { printf("MODE_SEND_RADAR_DETECT_RANGE\n"); } break;​ case MODE_SEND_BODY_EXIST_DETECT: //人体存在检测 { data_change.data_change_body_exist = 1; switch (command) { case 1: { //检测人体存在 body_exist_detect.body_exist_flag = (0 != rx_data[0]) ? 1 : 0; printf("Body Exist flag State:%d\n", body_exist_detect.body_exist_flag); } break;​ case 2: { //运动状态 body_exist_detect.work_state = rx_data[0]; printf("Move State:%d\n", body_exist_detect.work_state); } break;​ case 3: { //运动值 body_exist_detect.body_move_param = rx_data[0]; printf("Body Move Value:%d\n", body_exist_detect.body_move_param); } break;​ case 4: { //人体距离 body_exist_detect.body_distance = (rx_data[0] << 8) | rx_data[1]; printf("Body Distance:%d\n", body_exist_detect.body_distance); } break;​ case 5: { //人体方位 body_exist_detect.body_direction[0] = (rx_data[0] << 8) | rx_data[1]; body_exist_detect.body_direction[1] = (rx_data[2] << 8) | rx_data[3]; body_exist_detect.body_direction[2] = (rx_data[4] << 8) | rx_data[5]; } break; } } break;​ case MODE_SEND_BREATH_DETECT: //呼吸检测 { data_change.data_change_breath = 1; switch (command) { case 1: { //呼吸检测状态 breath_detect.breath_detect_state = rx_data[0]; printf("Breath State:%d\n", breath_detect.breath_detect_state); } break;​ case 2: { //呼吸值 breath_detect.breath_detect_value = rx_data[0]; printf("Breath Value:%d\n", breath_detect.breath_detect_value); } } } break;​ case MODE_SEND_SLEEP_DETECT: //睡眠检测 { data_change.data_change_sleep = 1; //判断命令字 switch (command) { case 1: { //入床/离床状态 sleep_detect.sleep_bed_state = rx_data[0]; printf("Sleep1 State:%d\n", sleep_detect.sleep_bed_state); } break;​ case 2: { //睡眠状态 sleep_detect.sleep_detect_state = rx_data[0]; printf("Sleep State:%d\n", sleep_detect.sleep_detect_state); } break;​ case 3: { //清醒时长 sleep_detect.sleep_wake_hour = (rx_data[0] << 8) | rx_data[1]; printf("Sleep Wake Hours:%d\n", sleep_detect.sleep_wake_hour); } break;​ case 4: { //浅睡时长 sleep_detect.sleep_light_hour = (rx_data[0] << 8) | rx_data[1]; printf("Sleep Light Hours:%d\n", sleep_detect.sleep_light_hour); } break;​ case 5: { //深睡时长 sleep_detect.sleep_deep_hour = (rx_data[0] << 8) | rx_data[1]; printf("Sleep Deep Hours:%d\n", sleep_detect.sleep_deep_hour); } break;​ case 0x06: { //睡眠质量评分 sleep_detect.sleep_score = rx_data[0]; printf("Sleep Score:%d\n", sleep_detect.sleep_score); } break;​ case 0x0c: { //睡眠检测结果 sleep_detect.sleep_score_detail.sleep_detail_exist = rx_data[0]; sleep_detect.sleep_score_detail.sleep_detail_state = rx_data[1]; sleep_detect.sleep_score_detail.sleep_detail_avg_breath = rx_data[2]; sleep_detect.sleep_score_detail.sleep_detail_avg_heart = rx_data[3]; sleep_detect.sleep_score_detail.sleep_detail_turn_over_times = rx_data[4]; sleep_detect.sleep_score_detail.sleep_detail_turn_over_L = rx_data[5]; sleep_detect.sleep_score_detail.sleep_detail_turn_over_S = rx_data[6]; sleep_detect.sleep_score_detail.sleep_detail_breath_stoptimes = rx_data[7]; } break;​ case 0x0d: { //睡眠详情 sleep_detect.sleep_score_detail_1.sleep_detail_score = rx_data[0]; sleep_detect.sleep_score_detail_1.sleep_detail_time = (rx_data[1] << 8) | rx_data[2]; sleep_detect.sleep_score_detail_1.sleep_detail_awake = rx_data[3]; sleep_detect.sleep_score_detail_1.sleep_detail_light = rx_data[4]; sleep_detect.sleep_score_detail_1.sleep_detail_away = rx_data[5]; sleep_detect.sleep_score_detail_1.sleep_detail_away_times = rx_data[6]; sleep_detect.sleep_score_detail_1.sleep_detail_avg_breath = rx_data[7]; sleep_detect.sleep_score_detail_1.sleep_detail_avg_heart = rx_data[8]; sleep_detect.sleep_score_detail_1.sleep_detail_breath_stoptimes = rx_data[9]; } break;​ case 0x0e: { //异常检测 sleep_detect.sleep_score_detail_err = rx_data[0]; } break; } } break;​ case MODE_SEND_HEART_DETECT: //心率检测 { data_change.data_change_heart = 1; switch (command) { case 0: { //开关心率检测 } break;​ case 2: { //心率值 heart_detect.heart_detect_value = rx_data[0]; printf("Heart rate Value:%d\n", heart_detect.heart_detect_value); } break;​ case 5: { //心率波形 heart_detect.heart_wave_data[0] = rx_data[0]; heart_detect.heart_wave_data[1] = rx_data[1]; heart_detect.heart_wave_data[2] = rx_data[2]; heart_detect.heart_wave_data[3] = rx_data[3]; heart_detect.heart_wave_data[4] = rx_data[4]; } break; } } break;​ case MODE_IDLE: //空闲 { } break; } } rx_datagram_state = SEEN_SUM; buff++; } break;​ case SEEN_SUM: //读取校验后,判断帧尾1 { rx_datagram_state = (END1 == *buff) ? SEEN_END1 : IDLE; } break;​ case SEEN_END1: //读取帧尾1后,判断帧尾2 { rx_datagram_state = (END2 == *buff) ? SEEN_END2 : IDLE; } break;​ case SEEN_END2: //判断帧尾2后,设置接收完成标志 { // rx_flag = 1; rx_datagram_state = IDLE; } break;​​ default: { receivedbyte = 0; rx_datagram_state = IDLE; size = 0; break; } } size--; }}五、总结本项目开发一种非接触式的睡眠监控系统,该系统利用先进的60GHz毫米波雷达技术和STM32微控制器,实现了对人体在睡眠过程中的存在感知、运动感知以及生理指标如呼吸频率、心率的实时监测。系统能够自动评估睡眠质量,并在用户睡眠周期结束时提供睡眠评分。为了确保用户能够在任何地点了解自己的睡眠状况,系统集成了Wi-Fi模块,可以将收集到的数据上传至华为云物联网平台,并通过专门设计的移动应用程序供用户远程访问。此外,系统还具备超阈值报警功能,当检测到异常的生理指标时会发出警报提醒。本地1.44寸TFT LCD显示屏用于实时显示监测到的信息,包括生理指标和环境数据。为了全面监测用户的健康状况,系统还加入了MLX90614红外体温传感器来检测人体体温。通过集成多种传感器和技术,该项目为健康管理和智能家居应用提供了有力支持。
  • [技术干货] WIFI、NBIOT、4G模块调试AT指令连接华为云物联网服务器(MQTT协议)
    一、前言随着物联网(IoT)技术的飞速发展,越来越多的设备开始连接到互联网,形成了一个万物互联的世界。在这个背景下,设备与云端之间的通讯变得尤为重要。本文将探讨几种常见的无线通信模块——EC20-4G、Air724ug-4G、NBIOT-BC26 和 ESP8266-WIFI,并展示如何通过发送AT指令来控制这些模块,利用MQTT协议连接华为云物联网平台,实现数据的高效上传。EC20-4G 和 Air724ug-4G 模块以其高速的数据传输能力和广泛的网络覆盖成为4G LTE通信的理想选择;NBIOT-BC26 模块则专为低功耗广域网(LPWAN)设计,特别适合于要求低带宽、远距离传输的应用场景;而 ESP8266-WIFI 模块则凭借其成本效益高、易于集成的特点,在Wi-Fi连接领域备受青睐。下面将逐一介绍这些模块的基础配置方法,并通过具体的实例说明如何使用AT指令建立与华为云物联网平台的安全连接。介绍MQTT协议的优势,包括其轻量化、低延迟和高可靠性等特性,这些特性使得MQTT成为物联网领域中最受欢迎的消息传递协议之一。通过这些模块的学习,可以了解到如何选择适合自己项目的通信模块,还能掌握实际的操作步骤,从硬件初始化到软件编程,最终成功地将传感器数据上传到云端。二、模块介绍2.1 EC20-4G模块EC20-4G是Quectel(Quectel Wireless Solutions)公司推出的一款4G LTE无线通信模块,它主要面向全球市场,支持多个频段的4G LTE网络以及向下兼容的3G和2G网络。这款模块非常适合用于数据传输速率要求较高的应用场合,如工业路由器、移动支付终端、远程医疗设备、车联网和其他M2M(Machine to Machine)通讯领域。EC20-4G模块采用LGA封装形式,拥有紧凑的设计,使得它可以轻松集成到各种类型的设备中,即便是在空间有限的应用环境中也能发挥良好的性能。该模块支持多种网络协议,例如TCP/IP, FTP, HTTP等,这使得开发者可以灵活地根据不同的应用场景选择合适的网络协议栈。除了基本的数据传输功能外,EC20-4G还具备丰富的扩展接口,包括UART、USB、GPIO等,方便与其他硬件组件进行连接和交互。此外,还支持多种定位技术,比如GPS/GLONASS/Galileo/QZSS,使得集成位置服务成为可能。在软件支持方面,EC20-4G提供了广泛的AT指令集,便于开发人员进行编程控制。同时,Quectel也为这款模块提供了详尽的技术文档和支持,帮助开发人员快速完成产品的开发和上市。2.2 ESP8266-WIFI模块ESP8266是一款由乐鑫科技(Espressif Systems)开发的高度集成的Wi-Fi SoC(系统级芯片),它专为移动设备、可穿戴技术和物联网应用而设计。ESP8266芯片内部集成了一个Tensilica L106超低功耗32位微处理器,主频可达80MHz至160MHz,拥有512KB的SRAM,以及内置的Wi-Fi模块,支持IEEE 802.11 b/g/n标准。这些特性使ESP8266成为一种成本效益高的解决方案,能够快速实现设备的Wi-Fi连接功能。ESP8266模块通常以小型化的形式出现,比如ESP-01,它是一个非常小巧的模块,尺寸仅约为25mm x 18mm,却包含了所有必要的Wi-Fi功能。这样的尺寸使得它非常适合集成到空间受限的项目中。ESP8266模块通过简单的AT命令集来进行配置和控制,这让它对于那些希望快速添加互联网连接功能到现有产品中的工程师来说非常有吸引力。除了作为独立的微控制器运行之外,ESP8266还可以作为从机与另一个主控器(如Arduino或树莓派、STM32、51单片机)配合工作,通过串口接收命令来执行Wi-Fi相关的任务。这种方式允许开发者利用ESP8266的强大网络功能,同时保持主控器对整个系统的控制。2.3 BC26-NBIOT模块BC26-NB是Quectel公司推出的一款窄带物联网(NB-IoT)模块,它专门针对低功耗广域网(LPWAN)的应用需求进行了优化。BC26-NB模块支持3GPP Release 13 NB-IoT标准,适用于各种需要长距离、低功耗、可靠连接的物联网应用,如智能计量、资产追踪、智慧城市基础设施监测等场景。该模块采用了紧凑型设计,适合集成到空间受限的设备中。BC26-NB模块不仅支持NB-IoT网络,还具备低功耗模式,使得它可以在电池供电的情况下长时间运行,这对于需要长期部署在野外或难以更换电池的设备来说是非常有利的特点。此外,它还提供了一系列的硬件接口,如UART、SPI、I2C、PWM等,方便与外部传感器或其他硬件设备进行连接和数据交换。在软件支持方面,BC26-NB模块配备了全面的AT指令集,简化了模块的初始化和配置过程。开发人员可以通过这些指令来控制模块的网络连接、数据传输等功能。Quectel公司还提供了详细的开发指南和技术支持,帮助用户快速地将BC26-NB模块集成到他们的物联网解决方案中。由于NB-IoT网络覆盖范围广、穿透力强,BC26-NB模块可以实现深覆盖区域内的可靠通信,即使是在地下室或偏远地区也能保持稳定的连接。这种能力对于需要在复杂环境中工作的物联网设备来说至关重要。2.4 Air724-UG-4G模块Air724-UG是Quectel公司推出的一款高性能的4G无线通信模块,它专为全球市场设计,支持多个频段的4G LTE Cat 4网络,同时兼容3G和2G网络,以便在全球范围内提供广泛的网络覆盖。该模块特别适合应用于需要高数据传输速率和稳定连接的行业解决方案中,如车载系统、工业路由器、远程监控系统以及移动支付终端等。Air724-UG模块采用了LGA封装,具有紧凑的外形尺寸,这使其能够轻松地集成到空间受限的产品设计中。它支持多种网络协议,包括TCP/IP、FTP、HTTP等,这使得开发人员可以根据具体的应用场景灵活选择适当的协议栈。此外,Air724-UG还具备多个物理接口,如UART、USB、GPIO等,便于与其他硬件组件进行连接,从而增强系统的功能性和互操作性。在功能特性方面,Air724-UG模块不仅支持高速数据传输,最高可达下行150Mbps和上行50Mbps的速率,还提供了丰富的扩展能力和附加功能。例如,它支持GNSS(全球导航卫星系统)功能,可用于定位服务;具备语音通话功能,适用于某些需要语音支持的应用场景;同时,该模块还支持多种安全机制,如SSL/TLS加密,保障了数据的安全传输。Quectel为Air724-UG模块提供了详尽的技术文档和支持资源,包括开发指南、参考设计和SDK等,帮助开发人员快速启动项目并缩短产品上市时间。模块的易用性和Quectel的技术支持使得Air724-UG成为了一款理想的4G LTE解决方案,适用于多种专业领域的设备连接需求。三、MQTT协议介绍MQTT协议概述MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,它被设计用来提供一对多的消息分发和应用之间的通讯,尤其适用于远程位置的设备和高延迟或低带宽的网络。MQTT协议基于客户端-服务器架构,客户端可以订阅任意数量的主题,并可以发布消息到这些主题。服务器(通常称为MQTT Broker)则负责接受来自客户端的连接请求,并转发消息给感兴趣的客户端。MQTT协议特点MQTT协议具有以下主要特点:轻量级:MQTT协议的实现非常轻巧,占用资源少,非常适合于资源受限的设备,如传感器、嵌入式设备等。低带宽需求:MQTT协议的设计考虑到了带宽的高效利用,其报头非常小,这使得它能够在低带宽环境下有效工作。可靠的消息传递:MQTT提供了三种服务质量等级(QoS),允许发布者和订阅者之间选择合适的服务质量级别。支持多种传输层:虽然MQTT最初是基于TCP/IP设计的,但它也支持使用WebSockets和其他传输协议,以便更好地集成到现代Web应用中。安全性:MQTT支持TLS加密通信,保证了数据的安全性,并可以通过认证机制增强安全性。MQTT协议的基本概念MQTT协议的核心概念包括客户端、服务器(Broker)、主题和消息。客户端(Client):任何连接到Broker的应用程序都可以被称为客户端。客户端可以订阅感兴趣的主题,接收其他客户端发布的消息,也可以发布消息。服务器(Broker):MQTT服务器或Broker是消息的中心节点,它接受客户端的连接请求,存储订阅关系,并将消息从发布者路由到订阅者。主题(Topic):主题是一个字符串,用于标识消息的类别或目的。客户端订阅主题后,可以接收到发布到该主题的所有消息。消息(Message):消息是由客户端发布的一组数据,它包含两部分:主题名和消息体。MQTT协议的工作流程MQTT的工作流程如下:连接:客户端向Broker发送连接请求,包含客户端ID、用户名、密码等信息。订阅:一旦连接成功,客户端可以订阅一个或多个主题。发布:客户端可以向特定主题发布消息。接收:如果客户端订阅了一个主题,则它可以接收该主题下的消息。断开连接:当客户端完成所有操作后,可以断开与Broker的连接。MQTT协议的应用场景由于其轻量级特性和高效的消息传递能力,MQTT协议广泛应用于物联网(IoT)领域,特别是在智能家居、工业自动化、远程监控等领域。此外,随着移动互联网的发展,MQTT也被用于移动应用程序中的实时数据更新和推送服务。四、上云测试【1】MQTT服务器地址信息下面的这个我华为云IOT物联网服务器的设备信息,方便下面进行测试。连接这个服务器。IP地址:117.78.5.125端口号:1883ClientId 64000697352830580e48df07_dev1_0_0_2023030206Username 64000697352830580e48df07_dev1Password a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449订阅主题:$oc/devices/64000697352830580e48df07_dev1/sys/messages/down发布主题:$oc/devices/64000697352830580e48df07_dev1/sys/properties/report发布的消息:{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}【2】ESP8266-WIFI连接要通过ESP8266模块使用AT指令来连接MQTT服务器,订阅特定的主题,并发布消息,可以按照以下步骤操作。请注意,这里提供的AT命令序列是基于ESP8266模块支持的MQTT功能。下面是一个示例流程:初始化ESP8266AT+RST 重启模块AT 测试模块是否响应AT+CIPMUX=1 设置多连接模式(可选)AT+CIPRXGET=1,100 设置接收数据的方式(可选)设置Wi-Fi连接AT+CWMODE=3 设置为Station+AP模式(通常只需要Station模式即可,即设置为1)AT+CWJAP="yourSSID","yourPassword" 连接到Wi-Fi网络配置MQTT客户端AT+CIPMQTTCFG="117.78.5.125",1883,"64000697352830580e48df07_dev1_0_0_2023030206","64000697352830580e48df07_dev1","","a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449",0,0,60 配置MQTT客户端参数,包括服务器地址、端口、客户端ID、用户名、密码等连接MQTT服务器AT+CIPMQTTC=1 连接到MQTT服务器订阅主题AT+CIPMQTTSUB=0,"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down",2 订阅指定的主题发布消息AT+CIPMQTTPUB=0,"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report",2,0,0,"{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}" 发布消息到指定主题断开MQTT连接AT+CIPMQTTDISC=0 断开与MQTT服务器的连接关闭TCP/IP连接AT+CIPCLOSE 关闭当前的TCP/IP连接注意,在使用中,需要将"yourSSID"和"yourPassword"替换为实际使用的Wi-Fi网络的SSID和密码。【3】NBIOT-BC26使用NBIoT-BC26模块连接MQTT服务器的过程与使用ESP8266类似,但是命令集有所不同。以下是使用NBIoT-BC26模块通过AT指令连接MQTT服务器、订阅主题以及发布消息的示例流程:初始化模块AT 检查模块是否在线ATE0 关闭回显AT+CFUN=1 启用射频功能AT+CGATT=1 附着到网络设置网络参数AT+CNOPS=0 设置网络操作模式AT+CGDCONT=1,"IP","your_apn" 设置PDP上下文,使用您的运营商提供的APN激活PDP上下文AT+CGACT=1,1 激活PDP上下文配置MQTT客户端AT+QMTOPEN=0,"tcp","117.78.5.125",1883 打开一个TCP连接到MQTT服务器建立MQTT连接使用AT+QMTCONN命令进行连接,此命令会发送MQTT CONNECT包给服务器。AT+QMTCONN=0,"64000697352830580e48df07_dev1_0_0_2023030206",60,0,1,0,"64000697352830580e48df07_dev1","a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449" 连接MQTT服务器,参数包括客户端ID,保持活动时间,Clean Session标志,Will标志,Will QoS,Will保留位,用户名和密码。订阅主题AT+QMTSUB=0,2,"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down" 订阅主题发布消息AT+QMTPUB=0,1,"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report",0,0,0,512 开始发送消息{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]} 发送的消息内容断开MQTT连接AT+QMTDISC=0 断开MQTT连接关闭TCP连接AT+QMTCLS=0 关闭TCP连接去激活PDP上下文AT+CGACT=1,0 去激活PDP上下文上述命令序列是基于NBIoT-BC26模块的MQTT功能。【4】EC20-4G模块对于EC20模块(通常是4G LTE模块),连接MQTT服务器、订阅主题和发布消息的AT指令会有所不同。以下是使用EC20模块通过AT指令完成这些操作的流程:初始化EC20模块AT检查EC20是否正常工作。设置工作模式为数据模式(如果尚未设置)AT+QCFG="nwscanmode",0,1设置网络扫描模式为自动。连接到移动网络AT+QNWINFO检查网络连接状态。设置MQTT服务器的IP地址和端口AT+QMTOPEN=0,"117.78.5.125",1883连接到MQTT服务器的指定IP和端口。登录MQTT服务器AT+QMTCONN=0,"64000697352830580e48df07_dev1","a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449",0,0使用客户端ID、用户名和密码连接MQTT服务器。订阅MQTT主题AT+QMTSUB=0,"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down",1订阅指定的MQTT主题。发布消息到MQTT主题AT+QMTPUB=0,"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report",0,0,{"services":[{"service_id":"stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}向指定的MQTT主题发布消息。断开MQTT连接AT+QMTDISC=0断开与MQTT服务器的连接。关闭EC20模块(如果需要)AT+QPOWD=1关闭EC20模块或使其进入省电模式。检查状态(可选)AT+QMTSTAT=0检查MQTT连接状态。请注意:AT+QMTOPEN、AT+QMTCONN、AT+QMTSUB 和 AT+QMTPUB 命令中的第一个参数 0 是连接的会话编号。可以根据需要调整它。发布的消息格式要符合MQTT协议的要求,可能需要根据具体的EC20模块固件版本调整。确保你已经在模块中设置了正确的APN,并成功连接到移动网络。
  • [技术干货] Linux系统下串口AT指令控制EC20连接华为云物联网平台
    一、前言在当今万物互联的时代背景下,物联网技术的快速发展极大地推动了智能化社会的构建。作为其中的关键一环,设备与云端平台之间的通信变得尤为重要。本文介绍如何在Linux操作系统环境下,利用串口通信来实现EC20模块与华为云物联网平台的有效连接。使用Linux下的/dev/ttyUSB0设备文件通过AT指令来配置EC20模块,采用C语言和Python这两种编程语言实现这一过程。EC20 是Quectel 生产的 4G LTE 模块。是一个多功能的通信模块,广泛应用于各种 IoT(物联网)设备中,提供了可靠的无线通信能力。EC20 支持 LTE FDD、LTE TDD、WCDMA 和 GSM 网络,能够实现高速的数据传输和稳定的语音通信。EC20 模块支持全球主要的频段,使其能够在多个国家和地区的网络环境中正常工作。它能够提供最高达 150 Mbps 的下行速率和 50 Mbps 的上行速率,这使得它非常适合需要高带宽的应用场景,如视频流、远程监控和数据传输。该模块具有强大的数据通信能力,包括支持 TCP/IP 和 UDP 协议的网络连接。EC20 还支持各种 AT 命令,通过这些命令用户可以控制模块的操作,配置网络设置,发送和接收数据。其内置的网络协议栈使得模块可以直接进行 MQTT、HTTP、FTP 等网络协议的通信,为开发者提供了极大的便利。除了数据通信功能,EC20 模块还支持语音通话和短信功能。这使得它不仅可以用于数据传输,还可以作为语音通信解决方案。通过 AT 命令,用户可以方便地进行拨打和接听电话,发送和接收短信,满足不同应用场景的需求。在电源管理方面,EC20 模块具有低功耗模式,能够有效地延长设备的电池寿命。它支持多种电源管理功能,包括睡眠模式和省电模式,使得它在不使用的时候能够降低功耗,减少能量消耗。模块的物理接口包括多个 UART 串口、USB 接口和 GPIO 引脚,这些接口允许模块与其他硬件进行连接。通过这些接口,用户可以实现串口通信、USB 数据传输以及各种数字信号的输入输出,提供了高度的灵活性和可扩展性。在设计和生产方面,EC20 模块遵循了工业标准,确保其在各种恶劣环境下的可靠性。它的设计小巧且坚固,适合嵌入到各种嵌入式系统和终端设备中。Quectel 提供了详细的技术文档和开发工具,帮助开发者快速集成和部署模块。二、实例代码2.1 服务器信息下面是我的华为云物联网服务器设备信息。关于创建过程,可以看视频:cid:link_0IP地址:117.78.5.125端口号:1883ClientId 64000697352830580e48df07_dev1_0_0_2023030206Username 64000697352830580e48df07_dev1Password a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449订阅主题:$oc/devices/64000697352830580e48df07_dev1/sys/messages/down发布主题:$oc/devices/64000697352830580e48df07_dev1/sys/properties/report发布的消息:{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}2.2 Python代码本小节介绍 通过串口 /dev/ttyUSB0 发送 AT 指令以控制 EC20 模块连接华为云物联网平台,并完成 MQTT 通信,使用 Python 脚本实现。AT 指令:AT+RST: 重启模块AT+CSIM=1: 设置工作模式为数据模式(请根据实际模块手册确认是否需要此指令)AT+QMTOPEN=0,"IP地址",端口号: 连接到 MQTT 服务器AT+QMTCONN=0,"ClientId","Username","Password": 使用提供的 ID、用户名和密码连接到 MQTT 服务器AT+QMTSUB=0,0,"主题",1: 订阅指定主题AT+QMTPUB=0,0,0,0,"主题",消息内容: 发布消息到指定主题下面是实现代码,展示了如何用 Python 通过串口发送 AT 指令来配置 EC20 模块并连接到华为云物联网平台:# -*- coding: utf-8 -*-​import serialimport time​# 串口配置SERIAL_PORT = '/dev/ttyUSB0'BAUDRATE = 115200TIMEOUT = 1​# MQTT 服务器信息MQTT_SERVER_IP = '117.78.5.125'MQTT_SERVER_PORT = '1883'MQTT_CLIENT_ID = '64000697352830580e48df07_dev1_0_0_2023030206'MQTT_USERNAME = '64000697352830580e48df07_dev1'MQTT_PASSWORD = 'a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449'​# 发布的消息PUBLISH_MESSAGE = '{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}'​# 发送 AT 指令并获取响应def send_at_command(serial_conn, command, response_termination='OK', delay=1): print(f"Sending command: {command}") serial_conn.write((command + '\r\n').encode()) time.sleep(delay) response = serial_conn.read(serial_conn.inWaiting()).decode() print(f"Response: {response}") if response_termination and response_termination not in response: raise Exception(f"Unexpected response: {response}") return response​def main(): # 打开串口连接 with serial.Serial(SERIAL_PORT, BAUDRATE, timeout=TIMEOUT) as ser: try: # 重启模块 send_at_command(ser, 'AT+RST')​ # 设置工作模式为数据模式 send_at_command(ser, 'AT+CSIM=1')​ # 连接到 MQTT 服务器 send_at_command(ser, f'AT+QMTOPEN=0,"{MQTT_SERVER_IP}",{MQTT_SERVER_PORT}') send_at_command(ser, 'AT+QMTCONN=0,"{MQTT_CLIENT_ID}","{MQTT_USERNAME}","{MQTT_PASSWORD}"') time.sleep(5) # 等待连接​ # 订阅主题 send_at_command(ser, 'AT+QMTSUB=0,0,"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down",1')​ # 发布消息 send_at_command(ser, f'AT+QMTPUB=0,0,0,0,"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report",{PUBLISH_MESSAGE}')​ except Exception as e: print(f"An error occurred: {e}")​if __name__ == "__main__": main()运行命令:root@flexusx-1a58:~# python3 mqtt_connect.py 2.3 C语言代码本小节介绍 用 C 语言实现通过串口发送 AT 指令来控制 EC20 模块并完成 MQTT 通信。下面是实现代码,通过串口配置 EC20 模块并连接到 MQTT 服务器:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <termios.h>#include <errno.h>​#define SERIAL_PORT "/dev/ttyUSB0"#define BAUDRATE B115200​int setup_serial_port(const char *port) { int fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); }​ struct termios options; tcgetattr(fd, &options); cfsetispeed(&options, BAUDRATE); cfsetospeed(&options, BAUDRATE);​ options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;​ tcsetattr(fd, TCSANOW, &options);​ return fd;}​void send_at_command(int fd, const char *command) { write(fd, command, strlen(command)); write(fd, "\r\n", 2); usleep(100000); // Wait for 100ms for the module to respond​ char response[256]; int n = read(fd, response, sizeof(response) - 1); if (n > 0) { response[n] = '\0'; printf("Response: %s\n", response); } else { printf("No response or read error.\n"); }}​int main() { int fd = setup_serial_port(SERIAL_PORT);​ // 1. Reset the module send_at_command(fd, "AT+RST");​ // 2. Connect to MQTT server char command[300]; snprintf(command, sizeof(command), "AT+QMTOPEN=0,\"%s\",%d", "117.78.5.125", 1883); send_at_command(fd, command);​ snprintf(command, sizeof(command), "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"", "64000697352830580e48df07_dev1_0_0_2023030206", "64000697352830580e48df07_dev1", "a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449"); send_at_command(fd, command);​ usleep(5000000); // Wait 5 seconds for connection to establish​ // 3. Subscribe to a topic send_at_command(fd, "AT+QMTSUB=0,0,\"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down\",1");​ // 4. Publish a message sprintf(command, "AT+QMTPUB=0,0,0,0,\"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report\",\"{\\\"services\\\": [{\\\"service_id\\\": \\\"stm32\\\",\\\"properties\\\":{\\\"DHT11_T\\\":18,\\\"DHT11_H\\\":80,\\\"MQ2\\\":1,\\\"water\\\":1,\\\"flame\\\":1,\\\"light\\\":0,\\\"LED1\\\":0,\\\"LED2\\\":0,\\\"LED3\\\":0}}]}\""); send_at_command(fd, command);​ close(fd); return 0;}编译运行:root@flexusx-1a58:~# gcc mqtt_connect.c root@flexusx-1a58:~# ./a.out 2.4 创建虚拟串口方便测试在与硬件通信之前,可以先建立一个虚拟串口测试一下。创建一个虚拟的串口设备 /dev/ttyUSB0 主要有两种方式:使用 socat 工具创建虚拟串口对(虚拟串口设备),或者使用 tty0tty 驱动来创建虚拟串口对。方法 1: 使用 socat 创建虚拟串口socat 是一个强大的网络工具,可以创建虚拟串口设备。下面是如何使用 socat 创建两个虚拟串口对:安装 socat: 在大多数 Linux 发行版上,可以使用包管理工具安装 socat。例如,在 Debian 或 Ubuntu 上运行:sudo apt-get install socat创建虚拟串口对: 运行以下命令来创建两个虚拟串口设备 /dev/ttyV0 和 /dev/ttyV1:socat -d -d PTY,link=/dev/ttyV0,raw,echo=0 PTY,link=/dev/ttyV1,raw,echo=0这将创建两个虚拟串口设备 /dev/ttyV0 和 /dev/ttyV1,它们会像物理串口一样工作,可以在程序中使用它们进行测试。使用虚拟串口设备:可以将一个设备用于发送数据,另一个设备用于接收数据进行测试。例如,可以将一个串口设备配置为连接到模拟的设备,另一个设备配置为模拟的串口设备的接收端。方法 2: 使用 tty0tty 驱动tty0tty 是一个内核模块,用于创建虚拟串口对。以下是如何安装和使用 tty0tty:安装 tty0tty: 需要从源代码编译和安装 tty0tty。按照以下步骤进行:sudo apt-get install build-essential linux-headers-$(uname -r)git clone https://github.com/ntop/tty0tty.gitcd tty0ttymakesudo make installsudo depmod -a加载内核模块: 运行以下命令加载 tty0tty 内核模块:sudo modprobe tty0tty这将创建虚拟串口设备 /dev/ttyt0 和 /dev/ttyt1。使用虚拟串口设备:/dev/ttyt0 和 /dev/ttyt1 现在可以作为虚拟串口设备使用。可以在程序中将它们作为串口设备来进行测试。示例代码假设已经创建了 /dev/ttyV0 和 /dev/ttyV1(使用 socat),可以在 Python 中使用这些虚拟串口设备进行测试。例如:import serial​# 打开虚拟串口ser1 = serial.Serial('/dev/ttyV0', 115200, timeout=1)ser2 = serial.Serial('/dev/ttyV1', 115200, timeout=1)​# 发送数据ser1.write(b'Hello, world!\n')​# 读取数据response = ser2.readline()print('Received:', response.decode('utf-8'))​# 关闭串口ser1.close()ser2.close()
  • [技术干货] 基于STM32单片机设计的矿山环境作业安全监测系统
    一、前言1.1 项目介绍项目设计里用到的全部工具软件和文档源码,都可以在这里下载。cid:link_10【1】项目开发背景矿山环境作业安全监测系统的开发背景主要源于对矿井作业环境中潜在危险因素的有效监控需求。矿山作为重要的资源开采场所,其工作环境往往存在诸多安全隐患,如瓦斯爆炸、粉尘超标等,这些因素不仅威胁着矿工的生命安全,还可能导致严重的经济损失和社会影响。因此,建立一个能够实时监测矿井内环境状况,并能在危险发生前及时预警的安全监测系统显得尤为重要。随着物联网技术的发展,利用先进的传感器技术与无线通信技术相结合,可以实现对矿山环境的全方位监控。本项目选择以STM32F103RCT6单片机作为核心控制器,因其具备高性能、低功耗的特点,非常适合用于此类环境下的数据采集与控制任务。通过集成DHT11温湿度传感器、MQ5气体传感器、PM2.5传感器等,系统能够实时获取环境数据,并依据预设的阈值进行判断,从而采取相应的措施,比如启动通风装置降低瓦斯浓度或通过喷淋系统减少空气中的颗粒物含量。此外,为了使矿山管理人员能够远程监控矿井内的实际情况,本项目还将通过BC26(NBIOT)模块将收集到的数据上传至华为云物联网平台,实现了数据的云端存储与分析。同时,借助移动应用技术,开发了一款APP,以便于工作人员随时查看环境参数及接收警报信息,进一步增强了系统的实用性和灵活性。本项目的开发提供一套高效、可靠的矿山环境作业安全监测解决方案,通过技术手段提升矿山安全管理效率,保障矿工的人身安全,促进矿山行业的可持续发展。【2】设计实现的功能(1) 本项目设计的核心是以STM32F103RCT6单片机作为主控单元,负责整个系统的协调控制,实现对矿山环境各项关键参数的监测与管理。(2) 采用DHT11温湿度传感器进行环境温度和湿度的实时采集,一旦检测到的数值超出安全范围,则通过蜂鸣器发出警报信号。(3) 使用MQ5气体传感器监测瓦斯浓度,当浓度达到预设阈值时,系统将通过控制继电器启动风扇,以稀释瓦斯浓度。(4) 配备PM2.5传感器用以检测空气中颗粒物的浓度,当浓度超标时,激活雾化喷淋系统以降低灰尘含量。(5) 选用OLED显示屏作为人机交互界面,实时显示由各传感器采集到的环境数据。(6) 利用BC26(NBIOT)模块将现场采集到的数据上传至华为云物联网平台,便于远程监控和数据分析。(7) 实现自动模式功能,系统能够按照预先设定的阈值自动监测环境参数,并在必要时触发警报或执行相应控制动作,如启动风扇或喷淋系统。(8) 提供手动模式功能,允许用户通过按键直接控制风扇和雾化降尘设备的开关状态,并且开发了基于Qt框架的Android平台手机APP,以便于远程控制这些设备的运行状态。(9) 设计中考虑了系统的稳定供电方案,采用5V 2A的外部稳压电源为系统供电。(10) 风扇和雾化降尘设备均采用5V电源供电,并通过继电器模块实现开关控制。(11) OLED显示屏采用SPI协议进行数据传输,以确保信息显示的准确性和实时性。【3】项目硬件模块组成(1) 控制核心模块:STM32F103RCT6单片机最小系统模块,作为整个监测系统的控制中心。(2) 温湿度采集模块:DHT11温湿度传感器,用于实时检测环境的温度和湿度。(3) 气体检测模块:MQ5气体传感器,用于监测环境中的瓦斯浓度。(4) 颗粒物检测模块:PM2.5传感器,用于检测空气中悬浮颗粒物的浓度。(5) 显示模块:0.96寸OLED显示屏,采用SPI协议连接至控制核心,显示各项环境参数。(6) 报警模块:蜂鸣器,当检测到环境参数异常时发出声音警报。(7) 执行机构控制模块:继电器模块,用于控制风扇和雾化降尘设备的开关状态。(8) 通风设备:风扇,由继电器控制,用于降低瓦斯浓度。(9) 降尘设备:雾化喷淋系统,同样由继电器控制,用于减少空气中颗粒物含量。(10) 远程通信模块:BC26(NBIOT)模块,负责将采集到的数据通过窄带物联网技术上传至云端。(11) 电源供应模块:5V 2A外部稳压电源,为整个系统提供稳定的电力支持。(12) 操作接口:按键模块,允许用户手动控制设备的开启与关闭。(13) 移动终端交互模块:基于Qt开发的Android平台手机APP,实现远程监控和控制功能。【4】需求总结项目名称:基于STM32单片机设计的矿山环境作业安全监测系统1、本次设计以 STM32F103RCT6 单片机最小系统模块作为系统控制核心,确定各种传感器模块选型,完成系统硬件结构设计。2、采用 DHT11 温湿度采集模块进行环境温湿度检测。当传感器检测到环境值超过控制系统设定的阀值参数时,可触发蜂鸣器报警。3、采用 MQ5气体传感器来检测环境的瓦斯浓度。当瓦斯浓度达到阈值时,控制系统控制继电器开关模块动作,实现风扇自动控制功能。4、采用 PM2.5 传感器检测环境中的颗粒物,超过阈值触发报警,可打开雾化模块进行喷淋降低。5、采用 OLED 显示屏作为显示模块显示实时数据。6、将采集到的环境信息通过BC26(NBIOT)模块将数据上传到华为云物联网平台。7、自动模式功能根据预设的阈值设定,监测环境参数,并在超过阈值时触发警报和控制设备使用定时器进行周期性的环境参数监测。设计逻辑判断程序,根据环境参数触发不同的处理动作。8、手动模式功能实现按键功能,根据用户的操作控制风扇和雾化降尘设备的开关状态。开发手机 APP,使用Qt作为 Android 平台的开发工具实现与BC26(NBIOT)模块的通信和数据显示功能。在手机 APP 上实现远程控制风扇和雾化降尘设备的开关功能以及显示实时监测到的环境参数和警报信息9、供电采用 5V 2A外部稳压电源10、风扇和雾化降尘设备采用5V加湿器模块,通过继电器控制开关。11、OLED显示屏采用SPI协议的0.96寸OLED显示屏1.2 设计思路设计思路的核心是围绕提高矿山作业环境的安全性展开,考虑到矿山环境复杂多变的特点,本项目构建一个能够实时监测并有效应对潜在危险因素的自动化系统。该系统的设计从硬件选型到软件架构都遵循了模块化和易维护的原则,确保了系统的可靠性和扩展性。在硬件层面,选择了性能稳定且易于编程的STM32F103RCT6单片机作为中央处理器,这是因为STM32系列芯片拥有丰富的外设接口,能够方便地与各种传感器和执行机构进行通信。同时,考虑到矿山环境的特殊性,传感器的选择上优先考虑了可靠性与准确性,如DHT11用于温湿度监测,MQ5用于瓦斯浓度检测,PM2.5传感器则用于颗粒物浓度测量。此外,为了实现环境参数的直观展示,选用了OLED显示屏作为人机交互界面,并通过继电器模块来控制风扇和雾化喷淋系统,以应对不同的紧急情况。软件方面,系统的设计着重于逻辑清晰的程序架构,通过编写高效的算法来处理来自不同传感器的数据,并依据预设的安全阈值进行逻辑判断。当环境参数超出正常范围时,系统会自动触发相应的警报机制,并启动相应的应急措施,例如启动通风设备降低瓦斯浓度或启用喷淋系统减少粉尘。此外,为了便于远程监控,系统集成了BC26(NBIOT)模块,能够将采集到的数据上传至华为云物联网平台,同时开发了配套的手机应用程序,使得管理者能够随时随地查看环境状况,并进行远程控制。整体而言,该项目的设计思路充分结合了现代物联网技术和传统矿山安全管理的需求,力求通过智能化手段提升矿山作业的安全水平,减少事故发生的可能性,保障矿山工作的顺利进行。1.3 系统功能总结功能类别描述环境监测实时采集矿山环境的温度、湿度、瓦斯浓度、颗粒物浓度等数据。自动警报当环境参数超过预设安全阈值时,自动触发蜂鸣器警报。自动控制达到特定阈值时,自动控制风扇和雾化喷淋系统,以降低瓦斯浓度和颗粒物含量。数据显示OLED显示屏实时显示采集到的各种环境参数。数据上传通过BC26(NBIOT)模块将环境数据上传至华为云物联网平台,便于远程监控和数据分析。定时监测使用定时器进行周期性的环境参数监测,确保数据的连续性和及时性。手动控制用户可以通过按键手动控制风扇和雾化降尘设备的开关状态。远程控制开发了基于Qt框架的Android平台手机APP,实现远程控制风扇和雾化降尘设备的开关功能。数据可视化在手机APP上显示实时监测到的环境参数和警报信息。稳定供电采用5V 2A外部稳压电源为系统提供稳定的电力支持。设备控制风扇和雾化降尘设备采用5V电源供电,并通过继电器模块实现开关控制。人机交互OLED显示屏采用SPI协议,保证信息显示的准确性和实时性。1.4 开发工具的选择【1】设备端开发STM32的编程语言选择C语言,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是有点不适应界面的。【2】上位机开发上位机的开发选择Qt框架,编程语言采用C++;Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。Qt能轻松创建具有原生C++性能的连接设备、用户界面(UI)和应用程序。它功能强大且结构紧凑,拥有直观的工具和库。1.5 模块的技术详情介绍【1】BC26-NBIOT模块BC26-NBIOT模块是一款专为窄带物联网(Narrow Band Internet of Things, NB-IoT)设计的无线通信模块,适用于低功耗广域网络(LPWAN)的应用场景。该模块主要针对物联网市场的需求而开发,尤其适用于那些需要长距离通信、低功耗、低成本和高容量的应用场合,如智能城市、环境监测、智能家居等领域。BC26-NBIOT模块具备良好的网络覆盖能力,能够在较远的距离内保持稳定的通信连接,这对于矿山环境作业安全监测系统来说至关重要。由于矿山内部结构复杂,通信条件苛刻,传统的无线通信技术可能难以满足要求,而NB-IoT技术凭借其优秀的穿透能力和低功耗特性,可以在这种环境下实现可靠的通信。BC26-NBIOT模块支持全球主流运营商的NB-IoT频段,这意味着它可以无缝接入不同的网络环境,为用户提供灵活的部署选项。这使得矿山监测系统不仅可以在国内使用,也可以在全球范围内实施,增强了系统的通用性和适用性。在能耗方面,BC26-NBIOT模块设计有低功耗模式,可以在不活跃期间大幅降低功耗,这对于延长电池寿命或减少系统整体功耗非常重要。尤其是在矿山这样的环境中,由于电源可能不是随时可得,低功耗特性就显得尤为关键。模块还提供了丰富的接口,包括UART、GPIO、PWM等,便于与其他传感器或执行器进行连接和数据交换。这使得开发者可以根据具体的应用需求,灵活地构建起复杂的物联网系统。同时,BC26-NBIOT模块通常支持AT命令集,这简化了开发过程,使得开发人员能够更快地上手进行开发工作。BC26-NBIOT模块以其卓越的通信性能、广泛的兼容性和低功耗特性,成为矿山环境作业安全监测系统中的理想选择,能够有效地支持数据的远程传输和系统的远程管理,提高了矿山作业的安全性和管理效率。【2】DHT11温湿度模块DHT11温湿度模块是一种经济实惠且广泛使用的数字温湿度传感器,它集成了温度和湿度感应元件以及一个信号转换电路。这款模块因其简单易用、成本低廉而被众多DIY爱好者和专业开发者所青睐,在智能家居、气象站、农业自动化等多种应用场景中都有广泛的应用。DHT11模块的核心是由一个NTC热敏电阻和一个湿度敏感电容组成的复合传感器。NTC热敏电阻用于检测环境温度的变化,而湿度敏感电容则用于检测空气中的水分含量。这些原始数据经过内部电路的处理后,通过单线串行接口输出给外部微控制器。这种集成化的处理方式大大简化了传感器的使用,使得开发人员无需关心内部的具体实现细节。在硬件接口方面,DHT11模块通常配备四个引脚,分别是电源正极(VCC)、电源地(GND)、信号输出(DATA)和预留的空引脚。其中,VCC引脚提供工作电压,通常为3.3V到5V之间;GND引脚接地;DATA引脚则是用于与外部微控制器进行数据通信的串行接口。为了保证数据传输的稳定性,通常会在DATA引脚与GND之间接一个上拉电阻。在软件层面上,DHT11模块的操作相对简单,它遵循一种特定的通信协议。当微控制器想要读取温湿度数据时,需要向DHT11发送一个启动信号,然后等待DHT11回应一个确认信号。之后,DHT11会依次发送湿度整数部分、湿度小数部分、温度整数部分、温度小数部分以及一个校验位。开发人员只需要编写简单的函数来发送启动信号,并接收和解析返回的数据即可。DHT11模块具有价格优势和易于使用的特性,它的精度不高,湿度测量范围为20%RH至90%RH,精度±5%RH;温度测量范围为0℃至50℃,精度±2℃。【3】PM2.5粉尘模块PM2.5粉尘模块是一种专门用于检测空气中细颗粒物(Particulate Matter 2.5,简称PM2.5)浓度的传感器。PM2.5是指直径小于或等于2.5微米的颗粒物,这类颗粒物因为体积小、面积大、活性强,容易携带污染物,对人体健康尤其是呼吸系统有着较大的危害。因此,监测PM2.5浓度对于环境保护和个人健康具有重要意义。PM2.5粉尘模块通常基于光散射原理工作。当空气中的颗粒物通过传感器时,内置的光源(通常是红外LED)会照射这些颗粒物,导致光的散射。传感器内部装有一个光电二极管,用来接收散射光,并将其转换成电信号。通过分析这些电信号的强度,就可以估算出空气中PM2.5颗粒物的浓度。这种检测方法简单、快速,适用于各种便携式或固定式的空气质量监测设备。市场上常见的PM2.5粉尘模块如PMS5003、SDS011等,它们通常具备较小的尺寸和较低的功耗,适合集成到各种物联网设备中。这些模块一般都提供标准的串行通信接口(如TTL UART),可以直接与微控制器(如STM32系列)相连,进行数据的读取和处理。此外,一些高级模块还支持I2C或SPI接口,提供更多的配置选项和更高的数据传输速率。在硬件设计上,PM2.5粉尘模块内部集成了气流通道、光源、光接收器以及信号处理电路。为了保证测量结果的准确性,模块内部通常设有风机来确保空气能够均匀流动并通过传感器区域。此外,为了防止外界干扰,传感器通常会配备有防尘网或过滤器,以保护内部元件不受污染。从软件角度来看,使用PM2.5粉尘模块相对简单。开发人员只需要按照模块提供的数据手册编写相应的驱动程序,就能实现对模块的初始化和数据读取。大多数模块都会提供一整套的通信协议,其中包括了如何发送查询命令以及如何解析返回的数据格式。例如,一些模块会以ASCII码形式返回数据,包含PM2.5、PM10等不同粒径颗粒物的浓度值,以及其他辅助信息如温度、湿度等。值得注意的是,虽然PM2.5粉尘模块在一定程度上能够提供准确的颗粒物浓度数据,但在实际应用中,还需要考虑诸如环境温度、湿度等因素对测量结果的影响。此外,为了确保数据的长期稳定性和准确性,定期对传感器进行校准也是非常必要的。PM2.5粉尘模块作为一种有效的颗粒物浓度监测工具,已经广泛应用于家庭、办公室、工厂等各种环境下的空气质量监测系统中,为人们提供了便捷的方式来监控和改善生活环境质量。二、BC26-NBIOT模块调试过程2.1 模块调试接线2.2 测试模块第一步接上之后,串口调试助手选择波特率为115200,勾选软件上的发送新行选项。发送AT过去,正常模块会返回OK。只有收到了OK,才表示模块工作正常。2.3 上电初始化操作【1】查询模块是否正常AT​OK​​【2】获取卡号,查询卡是否插好AT+CIMI​460041052911195​OK​​【3】激活网络AT+CGATT=1​OK​​【4】获取网络激活状态AT+CGATT?​+CGATT: 1​OK​​【5】查询网络质量AT+CSQ​+CSQ: 26,0​OK 【6】 检查网络状态AT+CEREG=? //+CEREG: 0,1 //找网成功OK2.4 开启GPS定位如果需要使用GPS定位就开,不需要使用就不用管。使用GPS定位还需要将模块上的GPS天线接好,否则也是没有信号的。官方文档:【1】激活GPS,要等一段时间AT+QGNSSC=1​OK​​【2】查询激活状态,1表示成功激活AT+QGNSSC?​+QGNSSC: 1​OK​​【3】获取一次GPS定位语句AT+QGNSSRD="NMEA/RMC"+QGNSSRD: $GNRMC,120715.00,A,3150.78179,N,11711.93433,E,0.000,,310818,,,A,V*19OK二、部署华为云物联网平台华为云官网: cid:link_11打开官网,搜索物联网,就能快速找到 设备接入IoTDA。2.1 物联网平台介绍华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助我们快速构筑物联网解决方案。使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。2.2 开通物联网服务地址: cid:link_8点击立即创建。正在创建标准版实例,需要等待片刻。创建完成之后,点击实例名称。 可以看到标准版实例的设备接入端口和地址。在上面也能看到 免费单元的限制。开通之后,点击总览,也能查看接入信息。 我们当前设备准备采用MQTT协议接入华为云平台,这里可以看到MQTT协议的地址和端口号等信息。总结:端口号: MQTT (1883)| MQTTS (8883) 接入地址:ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com根据域名地址得到IP地址信息:打开Windows电脑的命令行控制台终端,使用ping 命令。ping一下即可。Microsoft Windows [版本 10.0.19045.4170](c) Microsoft Corporation。保留所有权利。​C:\Users\11266>ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com​正在 Ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字节的数据:来自 117.78.5.125 的回复: 字节=32 时间=35ms TTL=93来自 117.78.5.125 的回复: 字节=32 时间=36ms TTL=93来自 117.78.5.125 的回复: 字节=32 时间=36ms TTL=93来自 117.78.5.125 的回复: 字节=32 时间=39ms TTL=93​117.78.5.125 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),往返行程的估计时间(以毫秒为单位): 最短 = 35ms,最长 = 39ms,平均 = 36ms​C:\Users\11266>MQTT协议接入端口号有两个,1883是非加密端口,8883是证书加密端口,单片机无法加载证书,所以使用1883端口比较合适。 接下来的ESP8266就采用1883端口连接华为云物联网平台。2.3 创建产品(1)创建产品(2)填写产品信息根据自己产品名字填写,下面的设备类型选择自定义类型。(3)产品创建成功创建完成之后点击查看详情。(4)添加自定义模型产品创建完成之后,点击进入产品详情页面,翻到最下面可以看到模型定义。模型简单来说: 就是存放设备上传到云平台的数据。你可以根据自己的产品进行创建。比如:烟雾可以叫 MQ2温度可以叫 Temperature湿度可以叫 humidity火焰可以叫 flame其他的传感器自己用单词简写命名即可。 这就是你的单片机设备端上传到服务器的数据名字。先点击自定义模型。再创建一个服务ID。接着点击新增属性。2.4 添加设备产品是属于上层的抽象模型,接下来在产品模型下添加实际的设备。添加的设备最终需要与真实的设备关联在一起,完成数据交互。(1)注册设备(2)根据自己的设备填写(3)保存设备信息创建完毕之后,点击保存并关闭,得到创建的设备密匙信息。该信息在后续生成MQTT三元组的时候需要使用。(4)设备创建完成(5)设备详情2.5 MQTT协议主题订阅与发布(1)MQTT协议介绍当前的设备是采用MQTT协议与华为云平台进行通信。MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。目前MQTT拥有各种平台和设备上的客户端,已经形成了初步的生态系统。MQTT是一种消息队列协议,使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合,相对于其他协议,开发更简单;MQTT协议是工作在TCP/IP协议上;由TCP/IP协议提供稳定的网络连接;所以,只要具备TCP协议栈的网络设备都可以使用MQTT协议。 本次设备采用的ESP8266就具备TCP协议栈,能够建立TCP连接,所以,配合STM32代码里封装的MQTT协议,就可以与华为云平台完成通信。华为云的MQTT协议接入帮助文档在这里: cid:link_6业务流程:(2)华为云平台MQTT协议使用限制描述限制支持的MQTT协议版本3.1.1与标准MQTT协议的区别支持Qos 0和Qos 1支持Topic自定义不支持QoS2不支持will、retain msgMQTTS支持的安全等级采用TCP通道基础 + TLS协议(最高TLSv1.3版本)单帐号每秒最大MQTT连接请求数无限制单个设备每分钟支持的最大MQTT连接数1单个MQTT连接每秒的吞吐量,即带宽,包含直连设备和网关3KB/sMQTT单个发布消息最大长度,超过此大小的发布请求将被直接拒绝1MBMQTT连接心跳时间建议值心跳时间限定为30至1200秒,推荐设置为120秒产品是否支持自定义Topic支持消息发布与订阅设备只能对自己的Topic进行消息发布与订阅每个订阅请求的最大订阅数无限制(3)主题订阅格式帮助文档地址:cid:link_6对于设备而言,一般会订阅平台下发消息给设备 这个主题。设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。以当前设备为例,最终订阅主题的格式如下:$oc/devices/{device_id}/sys/messages/down 最终的格式:$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down(4)主题发布格式对于设备来说,主题发布表示向云平台上传数据,将最新的传感器数据,设备状态上传到云平台。这个操作称为:属性上报。帮助文档地址:cid:link_2根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:发布的主题格式:$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":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}2.6 MQTT三元组MQTT协议登录需要填用户ID,设备ID,设备密码等信息,就像我们平时登录QQ,微信一样要输入账号密码才能登录。MQTT协议登录的这3个参数,一般称为MQTT三元组。接下来介绍,华为云平台的MQTT三元组参数如何得到。(1)MQTT服务器地址要登录MQTT服务器,首先记得先知道服务器的地址是多少,端口是多少。帮助文档地址:cid:link_1MQTT协议的端口支持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鉴权三元组: cid:link_7打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。下面是打开的页面:填入设备的信息: (上面两行就是设备创建完成之后保存得到的)直接得到三元组信息。得到三元组之后,设备端通过MQTT协议登录鉴权的时候,填入参数即可。ClientId 663cb18871d845632a0912e7_dev1_0_0_2024050911Username 663cb18871d845632a0912e7_dev1Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac2372.7 模拟设备登录测试经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。(1)填入登录信息打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。(2)打开网页查看完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。点击详情页面,可以看到上传的数据:到此,云平台的部署已经完成,设备已经可以正常上传数据了。(3)MQTT登录测试参数总结MQTT服务器: 117.78.5.125MQTT端口号: 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":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}2.8 创建IAM账户创建一个IAM账户,因为接下来开发上位机,需要使用云平台的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。地址: cid:link_4【1】获取项目凭证 点击左上角用户名,选择下拉菜单里的我的凭证项目凭证:28add376c01e4a61ac8b621c714bf459【2】创建IAM用户鼠标放在左上角头像上,在下拉菜单里选择统一身份认证。点击左上角创建用户。创建成功:【3】创建完成用户信息如下:主用户名 l19504562721IAM用户 ds_abc密码 DS123456782.9 获取影子数据帮助文档:cid:link_5设备影子介绍:设备影子是一个用于存储和检索设备当前状态信息的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三、上位机开发为了方便查看设备上传的数据,接下来利用Qt开发一款Android手机APP 和 Windows上位机。使用华为云平台提供的API接口获取设备上传的数据,进行可视化显示,以及远程控制设备。3.1 Qt开发环境安装Qt的中文官网: cid:link_12QT5.12.6的下载地址:cid:link_9或者去网盘里下载:cid:link_10打开下载链接后选择下面的版本进行下载:qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details软件安装时断网安装,否则会提示输入账户。安装的时候,第一个复选框里勾选一个mingw 32编译器即可,其他的不管默认就行,直接点击下一步继续安装。选择MinGW 32-bit 编译器: (一定要看清楚了)说明: 我这里只是介绍PC端,也就是Windows系统下的Qt环境搭建。 Android的开发环境比较麻烦,如果想学习Android开发,想编译Android程序的APP,需要自己去搭建Android环境。也可以看下面这篇文章,不过这个文章是在Qt开发专栏里付费的,需要订阅专栏才可以看。 如果不想付费看,也可以自行找其他教程,自己搭建好必须的环境就行了Android环境搭建的博客链接: cid:link_33.2 新建上位机工程前面2讲解了需要用的API接口,接下来就使用Qt设计上位机,设计界面,完成整体上位机的逻辑设计。【1】新建工程【2】设置项目的名称。【3】选择编译系统【4】选择默认继承的类【5】选择编译器【6】点击完成【7】工程创建完成3.3 设计UI界面与工程配置【1】打开UI文件打开默认的界面如下:【2】开始设计界面根据自己需求设计界面。3.5 编译Windows上位机点击软件左下角的绿色三角形按钮进行编译运行。编译之后的效果:3.6 配置Android环境如果想编译Android手机APP,必须要先自己配置好自己的Android环境。(搭建环境的过程可以自行百度搜索学习)然后才可以进行下面的步骤。【1】选择Android编译器【2】创建Android配置文件创建完成。【3】配置Android图标与名称【3】编译Android上位机Qt本身是跨平台的,直接选择Android的编译器,就可以将程序编译到Android平台。然后点击构建。成功之后,在目录下可以看到生成的apk文件,也就是Android手机的安装包,电脑端使用QQ发送给手机QQ,手机登录QQ接收,就能直接安装。生成的apk的目录在哪里呢? 编译完成之后,在控制台会输出APK文件的路径。知道目录在哪里之后,在Windows的文件资源管理器里,找到路径,具体看下图,找到生成的apk文件。D:/linux-share-dir/QT/build-app_Huawei_Eco_tracking-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Release/android-build//build/outputs/apk/debug/android-build-debug.apk四、STM32代码开发4.1 MQTT协议设计代码字数过多,无法显示...4.2 PM2.5与MQ5采集代码#include "adc.h"#include "delay.h" //初始化ADC1//这里我们仅以规则通道为例//我们默认仅开启通道1 void Adc_Init(void){ //先初始化IO口 RCC->APB2ENR|=1<<2; //使能PORTA口时钟 GPIOA->CRL&=0XFFFFFF0F;//PA1 anolog输入 RCC->APB2ENR|=1<<9; //ADC1时钟使能 RCC->APB2RSTR|=1<<9; //ADC1复位 RCC->APB2RSTR&=~(1<<9);//复位结束 RCC->CFGR&=~(3<<14); //分频因子清零 //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M! //否则将导致ADC准确度下降! RCC->CFGR|=2<<14; ADC1->CR1&=0XF0FFFF; //工作模式清零 ADC1->CR1|=0<<16; //独立工作模式 ADC1->CR1&=~(1<<8); //非扫描模式 ADC1->CR2&=~(1<<1); //单次转换模式 ADC1->CR2&=~(7<<17); ADC1->CR2|=7<<17; //软件控制转换 ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发 ADC1->CR2&=~(1<<11); //右对齐 ADC1->SQR1&=~(0XF<<20); ADC1->SQR1|=0<<20; //1个转换在规则序列中 也就是只转换规则序列1 //设置通道1的采样时间 ADC1->SMPR2&=~(3*1); //通道1采样时间清空 ADC1->SMPR2|=7<<(3*1); //通道1 239.5周期,提高采样时间可以提高精确度 ADC1->CR2|=1<<0; //开启AD转换器 ADC1->CR2|=1<<3; //使能复位校准 while(ADC1->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。 ADC1->CR2|=1<<2; //开启AD校准 while(ADC1->CR2&1<<2); //等待校准结束 //该位由软件设置以开始校准,并在校准结束时由硬件清除 } //获得ADC1某个通道的值//ch:通道值 0~16//返回值:转换结果u16 Get_Adc(u8 ch) { //设置转换序列 ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch ADC1->SQR3|=ch; ADC1->CR2|=1<<22; //启动规则转换通道 while(!(ADC1->SR&1<<1));//等待转换结束 return ADC1->DR; //返回adc值 }//获取通道ch的转换值,取times次,然后平均 //ch:通道编号//times:获取次数//返回值:通道ch的times次转换结果平均值u16 Get_Adc_Average(u8 ch,u8 times){ u32 temp_val=0; u8 t; for(t=0;t<times;t++) { temp_val+=Get_Adc(ch); delay_ms(5); } return temp_val/times;} 4.3 DHT11温湿度采集代码#include "dht11.h"#include "delay.h"//IO方向设置#define DHT11_IO_IN() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}#define DHT11_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}////IO操作函数 #define DHT11_DQ_OUT PGout(11) //数据端口 PG11 #define DHT11_DQ_IN PGin(11) //数据端口 PG11​​u8 DHT11_Init(void); //初始化DHT11u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度u8 DHT11_Read_Byte(void); //读出一个字节u8 DHT11_Read_Bit(void); //读出一个位u8 DHT11_Check(void); //检测是否存在DHT11void DHT11_Rst(void); //复位DHT11 ​​//复位DHT11void DHT11_Rst(void) { DHT11_IO_OUT(); //SET OUTPUT DHT11_DQ_OUT=0; //拉低DQ delay_ms(20); //拉低至少18ms DHT11_DQ_OUT=1; //DQ=1 delay_us(30); //主机拉高20~40us}//等待DHT11的回应//返回1:未检测到DHT11的存在//返回0:存在u8 DHT11_Check(void) { u8 retry=0; DHT11_IO_IN();//SET INPUT while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; else retry=0; while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; return 0;}//从DHT11读取一个位//返回值:1/0u8 DHT11_Read_Bit(void) { u8 retry=0; while(DHT11_DQ_IN&&retry<100)//等待变为低电平 { retry++; delay_us(1); } retry=0; while(!DHT11_DQ_IN&&retry<100)//等待变高电平 { retry++; delay_us(1); } delay_us(40);//等待40us if(DHT11_DQ_IN)return 1; else return 0; }//从DHT11读取一个字节//返回值:读到的数据u8 DHT11_Read_Byte(void) { u8 i,dat; dat=0; for (i=0;i<8;i++) { dat<<=1; dat|=DHT11_Read_Bit(); } return dat;}//从DHT11读取一次数据//temp:温度值(范围:0~50°)//humi:湿度值(范围:20%~90%)//返回值:0,正常;1,读取失败u8 DHT11_Read_Data(u8 *temp,u8 *humi) { u8 buf[5]; u8 i; DHT11_Rst(); if(DHT11_Check()==0) { for(i=0;i<5;i++)//读取40位数据 { buf[i]=DHT11_Read_Byte(); } if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) { *humi=buf[0]; *temp=buf[2]; } }else return 1; return 0; }//初始化DHT11的IO口 DQ 同时检测DHT11的存在//返回1:不存在//返回0:存在 u8 DHT11_Init(void){ RCC->APB2ENR|=1<<8; //使能PORTG口时钟 GPIOG->CRH&=0XFFFF0FFF;//PORTG.11 推挽输出 GPIOG->CRH|=0X00003000; GPIOG->ODR|=1<<11; //输出1 DHT11_Rst(); return DHT11_Check();}五、总结该项目开发一种基于STM32单片机的矿山环境作业安全监测系统,以提高矿山作业的安全性和效率。系统集成了多种传感器,包括DHT11温湿度传感器、MQ5气体传感器和PM2.5传感器,用于实时监测矿山环境中的关键参数,如温度、湿度、瓦斯浓度和颗粒物含量。通过这些传感器,系统能够及时发现潜在的安全隐患,并采取必要的预防措施。在硬件设计方面,系统采用了STM32F103RCT6单片机作为核心控制器,配合蜂鸣器、继电器模块、OLED显示屏等组件,形成了一个完整的监测与控制系统。当检测到的环境参数超过预设的安全阈值时,系统能够自动触发报警,并通过控制风扇和雾化喷淋系统来降低瓦斯浓度和颗粒物含量,从而保障矿工的生命安全。此外,为了实现远程监控与管理,项目还引入了BC26(NBIOT)模块,将环境数据上传至华为云物联网平台,并开发了一款基于Qt框架的Android平台手机应用程序。该应用程序不仅能够实时显示环境参数,还能接收警报信息,并允许用户远程控制风扇和雾化降尘设备的开关状态,极大地提升了系统的实用性和灵活性。该矿山环境作业安全监测系统通过集成先进的传感技术和物联网技术,实现了对矿山环境的全方位监控,能够在危险发生之前提供预警,并采取有效的防护措施,对于提升矿山作业的安全管理水平具有重要意义。
  • [技术干货] 基于STM32设计的农作物生长管理系统
    一、前言1.1 项目介绍【1】项目开发背景随着现代农业技术的发展,智能农业逐渐成为提高农作物产量和品质的关键手段之一。传统的农业生产方式依赖于人工经验,这种方式不仅效率低下,而且难以应对气候变化带来的挑战。特别是在水资源管理和光照控制方面,传统方法往往无法提供精确的控制,这直接影响到了农作物的生长周期和最终产量。在此背景下,基于现代物联网技术的农作物生长管理系统应运而生。这类系统能够通过各种传感器实时监测农田环境,如土壤湿度、光照强度、空气温度和湿度等,并根据这些数据自动调整灌溉、照明等设施的工作状态。这种智能化的管理不仅大大减轻了农民的劳动强度,而且通过优化资源利用,提高了农作物的生产效率。本项目提出了一种基于STM32微控制器和NBIOT通信技术的农作物生长管理系统设计方案。通过将先进的微处理器技术与窄带物联网(NBIOT)结合,本系统能够在无人干预的情况下,实现对农田环境的精确控制。系统还具备远程监控和控制功能,用户可以通过手机应用程序随时查看农田的实时数据,并根据需要调整设备的工作模式。随着科技的进步和人们对食品安全重视程度的提高,智能农业管理系统的需求日益增长。本项目的开发不仅有助于推动农业向更加科学化、精准化的方向发展,同时也为实现可持续农业生产和保障粮食安全提供了技术支持。通过本系统的应用,可以预见未来的农业生产将更加高效、环保,同时也为农民带来了更大的经济效益和社会效益。​【2】设计实现的功能(1)实时检测土壤含水量,并根据预设的阈值自动判断是否需要补水,进而实现自动化的灌溉控制。(2)除了自动补水功能外,系统还提供了本地按钮控制补水选项,同时支持通过远程控制手段进行手动补水操作,增加了补水控制的灵活性。(3)系统支持植物补光灯亮度的PWM自动调节,可以根据环境亮度的变化动态调整灯光亮度,以确保植物获得最佳光照条件。(4)环境温度与湿度检测功能也是系统的重要组成部分,当检测到空气温度或湿度超出设定的安全范围时,系统会触发相应的警报机制。(5)本地OLED屏幕显示当前环境的各项参数,如温度、湿度、土壤含水量以及光线照射强度,方便用户随时查看环境状态。(6)为了及时响应异常情况,系统配备了蜂鸣器报警功能。一旦发现温度、湿度或土壤含水量不符合预设的健康范围,系统会通过蜂鸣器发出声音报警。这些阈值可以通过手机应用程序进行设定。(7)为了避免由于温度突变引起的误操作,系统采用了适当的控制方法,在设定温度发生大变动时延迟系统的反应调节时间,确保系统的稳定性和准确性。(8)通过NBIOT-BC26模块,整个设备可以连接至华为云IoT物联网平台,并采用MQTT协议上传数据。基于此,设计了Android手机APP,以便用户能够远程查看设备上传的数据,并实现远程控制设备的功能,如设置设备的温度阈值等。(9)采用Qt框架开发Android手机应用程序【3】项目硬件模块组成(1)主控芯片:采用STM32F103RCT6作为核心处理器,负责处理系统中所有的逻辑运算和控制任务。(2)环境光照强度检测模块:使用BH1750传感器来测量环境光照强度,为补光灯的亮度调节提供数据支持。(3)环境温湿度检测模块:采用DHT11传感器,用于监测环境中的温度和湿度,确保农作物处于适宜的生长环境中。(4)OLED显示屏模块:选用0.96寸的SPI协议OLED显示屏,用于显示当前环境参数,如温度、湿度、土壤含水量及光线强度等信息。(5)补光灯模块:使用白色LED灯作为植物补光灯,通过PWM技术调节亮度,以适应不同环境下的光照需求。(6)声音报警模块:采用蜂鸣器作为报警装置,当环境参数超出预设阈值时,通过蜂鸣器发出声音警报。(7)土壤湿度检测模块:使用带有ADC模拟量接口的土壤湿度检测传感器,用于实时监测土壤含水量,确保适时补水。(8)网络通信模块:采用NBIOT-BC26模块,实现设备与华为云IoT物联网平台之间的数据传输,通过MQTT协议上传数据。(9)补水控制模块:使用继电器驱动5V抽水电机,根据土壤湿度传感器的反馈信息自动或手动控制补水过程。(10)供电模块:采用USB线5V供电方式,为整个系统提供稳定的电力供应,简化了设备的安装和使用流程。【4】需求总结项目名字: 基于STM32+NBIOT设计的农作物生长管理系统​实现功能:​1. 实时检测土壤含水量,根据设置的阀值判断实现自动补水2. 本地可用按钮控制补水、远程手动控制补水3. 支持植物补光灯亮度PWM自动调节,可根据环境亮度调节灯光亮度4. 支持检测环境温度、湿度,当空气温度、湿度超过设定值范围时会报警。5. 本地0LED屏幕显示当前环境温度、湿度、土壤含水量、光线照射强度等参数。6. 支持蜂鸣器报警提醒,当温度、湿度、土壤含水量阀值不符合设定值时通过蜂鸣器发出声音报警(阀值可通过手机APP设定)7.采用合适的控制方法,当设定温度发生大突变时,为了防止误设置,延迟系统的反应调节时间。8. 整个设备会通过NBIOT-BC26连接华为云IOT物联网平台,通过MQTT协议上传数据到物联网云平台,再设计Android手机APP实现远程显示设备上传的数据,同时可以远程控制设备,设置设备温度阀值等等。9. 采用Qt(C++)设计Android手机APP,实现数据远程监测显示和远程控制。​硬件选型:​1. 主控芯片选择STM32F103RCT62. 环境光照强度检测采用BH17503. 环境温湿度检测采用DHT114. OLED显示屏采用0.96寸SPI协议显示屏5. 补光灯采用白色LED灯6. 声音报警采用蜂鸣器7. 土壤湿度检测采用ADC模拟量接口的土壤湿度检测传感器8. 联网采用NBIOT-BC26模块9. 植物补水采用继电器驱动5V抽水电机抽水进行补水。10.供电电源:采用USB线-5V供电。1.2 设计思路本项目的设计思路围绕着实现一个高度自动化、智能化的农作物生长管理系统展开,通过现代电子技术与物联网技术的融合,为农作物提供最佳的生长环境。首先,系统的核心是基于STM32F103RCT6微控制器,这是因为该芯片具备高性能、低功耗的特点,非常适合用于需要实时处理大量数据的应用场景。通过集成多种传感器,系统能够实时采集环境数据,如土壤湿度、光照强度、温度和湿度等,为后续的决策和控制提供依据。在环境监测方面,系统选用了BH1750光照强度传感器和DHT11温湿度传感器。BH1750能够精确测量光照强度,从而支持植物补光灯的PWM自动调节功能;而DHT11则用于监测空气中的温度和湿度,当这些参数超出预设的安全范围时,系统会通过蜂鸣器报警,提醒用户采取措施。系统配置了土壤湿度检测传感器,它可以实时检测土壤的含水量,并根据设定的阈值自动控制补水,确保植物获得充足的水分。为了使用户能够直观地了解环境状态,系统配备了一块0.96寸的OLED显示屏,通过SPI协议与主控芯片相连,实时显示各项环境参数。这样,即使在没有智能手机的情况下,用户也能通过显示屏掌握当前的环境状况。在联网功能上,系统采用了NBIOT-BC26模块,通过窄带物联网技术实现设备与华为云IoT物联网平台的连接。借助MQTT协议,系统能够将采集到的数据上传至云端,用户可以通过Android手机APP实时查看数据,并远程控制设备。为了进一步增强用户体验,项目还计划使用Qt框架开发Android版的应用程序,以便于用户更方便地进行远程监控和管理。在控制策略上,系统特别考虑到了温度突变可能引发的误操作问题。为此,设计了适当的延时控制机制,即当设定温度发生较大变化时,系统不会立即作出反应,而是经过一段时间的延迟后再进行调节,从而避免了因温度波动导致的误动作。在供电方面,系统选择了简单且可靠的USB线5V供电方式,不仅便于安装和维护,也确保了系统的稳定性。通过这一系列的设计思路,本项目打造一个高效、可靠且易于使用的农作物生长管理系统,助力现代农业的智能化转型。1.3 系统功能总结功能类别描述实时土壤含水量检测与自动补水系统能够实时检测土壤含水量,并根据预设阈值自动判断是否需要启动补水机制。本地与远程补水控制用户可以通过本地按钮手动控制补水,也可以通过远程手段(如手机APP)进行手动补水控制。补光灯亮度自动调节根据环境亮度变化,系统能够自动调节补光灯的亮度,以满足植物生长所需的光照条件。环境温湿度检测与报警通过传感器检测环境温度和湿度,当检测到的数值超出设定范围时,系统会触发报警机制。环境参数本地显示OLED屏幕实时显示当前环境的温度、湿度、土壤含水量及光线照射强度等参数。蜂鸣器声音报警当温度、湿度或土壤含水量不符合预设的健康范围时,系统通过蜂鸣器发出声音报警。温度突变延迟控制针对温度突变的情况,系统采用了延迟反应机制,以防止因温度快速变化而导致的误操作。数据上传与远程监控通过NBIOT-BC26模块将数据上传至华为云IoT平台,并通过MQTT协议传输数据,支持远程监控。远程控制与设置用户可以通过设计的Android手机APP实现远程控制设备,包括查看数据、控制设备和设置温度阈值等功能。1.4 开发工具的选择【1】设备端开发STM32的编程语言选择C语言,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是有点不适应界面的。【2】上位机开发上位机的开发选择Qt框架,编程语言采用C++;Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。Qt能轻松创建具有原生C++性能的连接设备、用户界面(UI)和应用程序。它功能强大且结构紧凑,拥有直观的工具和库。二、部署华为云物联网平台华为云官网: cid:link_11打开官网,搜索物联网,就能快速找到 设备接入IoTDA。2.1 物联网平台介绍华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助我们快速构筑物联网解决方案。使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。2.2 开通物联网服务地址: cid:link_8点击立即创建。正在创建标准版实例,需要等待片刻。创建完成之后,点击实例名称。 可以看到标准版实例的设备接入端口和地址。在上面也能看到 免费单元的限制。开通之后,点击总览,也能查看接入信息。 我们当前设备准备采用MQTT协议接入华为云平台,这里可以看到MQTT协议的地址和端口号等信息。总结:端口号: MQTT (1883)| MQTTS (8883) 接入地址:ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com根据域名地址得到IP地址信息:打开Windows电脑的命令行控制台终端,使用ping 命令。ping一下即可。Microsoft Windows [版本 10.0.19045.4170](c) Microsoft Corporation。保留所有权利。​C:\Users\11266>ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com​正在 Ping ad635970a1.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字节的数据:来自 117.78.5.125 的回复: 字节=32 时间=35ms TTL=93来自 117.78.5.125 的回复: 字节=32 时间=36ms TTL=93来自 117.78.5.125 的回复: 字节=32 时间=36ms TTL=93来自 117.78.5.125 的回复: 字节=32 时间=39ms TTL=93​117.78.5.125 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),往返行程的估计时间(以毫秒为单位): 最短 = 35ms,最长 = 39ms,平均 = 36ms​C:\Users\11266>MQTT协议接入端口号有两个,1883是非加密端口,8883是证书加密端口,单片机无法加载证书,所以使用1883端口比较合适。 接下来的ESP8266就采用1883端口连接华为云物联网平台。2.3 创建产品(1)创建产品(2)填写产品信息根据自己产品名字填写,下面的设备类型选择自定义类型。(3)产品创建成功创建完成之后点击查看详情。(4)添加自定义模型产品创建完成之后,点击进入产品详情页面,翻到最下面可以看到模型定义。模型简单来说: 就是存放设备上传到云平台的数据。你可以根据自己的产品进行创建。比如:烟雾可以叫 MQ2温度可以叫 Temperature湿度可以叫 humidity火焰可以叫 flame其他的传感器自己用单词简写命名即可。 这就是你的单片机设备端上传到服务器的数据名字。先点击自定义模型。再创建一个服务ID。接着点击新增属性。2.4 添加设备产品是属于上层的抽象模型,接下来在产品模型下添加实际的设备。添加的设备最终需要与真实的设备关联在一起,完成数据交互。(1)注册设备(2)根据自己的设备填写(3)保存设备信息创建完毕之后,点击保存并关闭,得到创建的设备密匙信息。该信息在后续生成MQTT三元组的时候需要使用。(4)设备创建完成(5)设备详情2.5 MQTT协议主题订阅与发布(1)MQTT协议介绍当前的设备是采用MQTT协议与华为云平台进行通信。MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。目前MQTT拥有各种平台和设备上的客户端,已经形成了初步的生态系统。MQTT是一种消息队列协议,使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合,相对于其他协议,开发更简单;MQTT协议是工作在TCP/IP协议上;由TCP/IP协议提供稳定的网络连接;所以,只要具备TCP协议栈的网络设备都可以使用MQTT协议。 本次设备采用的ESP8266就具备TCP协议栈,能够建立TCP连接,所以,配合STM32代码里封装的MQTT协议,就可以与华为云平台完成通信。华为云的MQTT协议接入帮助文档在这里: cid:link_6业务流程:(2)华为云平台MQTT协议使用限制描述限制支持的MQTT协议版本3.1.1与标准MQTT协议的区别支持Qos 0和Qos 1支持Topic自定义不支持QoS2不支持will、retain msgMQTTS支持的安全等级采用TCP通道基础 + TLS协议(最高TLSv1.3版本)单帐号每秒最大MQTT连接请求数无限制单个设备每分钟支持的最大MQTT连接数1单个MQTT连接每秒的吞吐量,即带宽,包含直连设备和网关3KB/sMQTT单个发布消息最大长度,超过此大小的发布请求将被直接拒绝1MBMQTT连接心跳时间建议值心跳时间限定为30至1200秒,推荐设置为120秒产品是否支持自定义Topic支持消息发布与订阅设备只能对自己的Topic进行消息发布与订阅每个订阅请求的最大订阅数无限制(3)主题订阅格式帮助文档地址:cid:link_6对于设备而言,一般会订阅平台下发消息给设备 这个主题。设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。以当前设备为例,最终订阅主题的格式如下:$oc/devices/{device_id}/sys/messages/down 最终的格式:$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down(4)主题发布格式对于设备来说,主题发布表示向云平台上传数据,将最新的传感器数据,设备状态上传到云平台。这个操作称为:属性上报。帮助文档地址:cid:link_2根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:发布的主题格式:$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":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}2.6 MQTT三元组MQTT协议登录需要填用户ID,设备ID,设备密码等信息,就像我们平时登录QQ,微信一样要输入账号密码才能登录。MQTT协议登录的这3个参数,一般称为MQTT三元组。接下来介绍,华为云平台的MQTT三元组参数如何得到。(1)MQTT服务器地址要登录MQTT服务器,首先记得先知道服务器的地址是多少,端口是多少。帮助文档地址:cid:link_1MQTT协议的端口支持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鉴权三元组: cid:link_7打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。下面是打开的页面:填入设备的信息: (上面两行就是设备创建完成之后保存得到的)直接得到三元组信息。得到三元组之后,设备端通过MQTT协议登录鉴权的时候,填入参数即可。ClientId 663cb18871d845632a0912e7_dev1_0_0_2024050911Username 663cb18871d845632a0912e7_dev1Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac2372.7 模拟设备登录测试经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。(1)填入登录信息打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。(2)打开网页查看完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。点击详情页面,可以看到上传的数据:到此,云平台的部署已经完成,设备已经可以正常上传数据了。(3)MQTT登录测试参数总结MQTT服务器: 117.78.5.125MQTT端口号: 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":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}2.8 创建IAM账户创建一个IAM账户,因为接下来开发上位机,需要使用云平台的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。地址: cid:link_4【1】获取项目凭证 点击左上角用户名,选择下拉菜单里的我的凭证项目凭证:28add376c01e4a61ac8b621c714bf459【2】创建IAM用户鼠标放在左上角头像上,在下拉菜单里选择统一身份认证。点击左上角创建用户。创建成功:【3】创建完成用户信息如下:主用户名 l19504562721IAM用户 ds_abc密码 DS123456782.9 获取影子数据帮助文档:cid:link_5设备影子介绍:设备影子是一个用于存储和检索设备当前状态信息的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三、上位机开发为了方便查看设备上传的数据,接下来利用Qt开发一款Android手机APP 和 Windows上位机。使用华为云平台提供的API接口获取设备上传的数据,进行可视化显示,以及远程控制设备。3.1 Qt开发环境安装Qt的中文官网: cid:link_12QT5.12.6的下载地址:cid:link_9或者去网盘里下载:cid:link_10打开下载链接后选择下面的版本进行下载:qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details软件安装时断网安装,否则会提示输入账户。安装的时候,第一个复选框里勾选一个mingw 32编译器即可,其他的不管默认就行,直接点击下一步继续安装。选择MinGW 32-bit 编译器: (一定要看清楚了)说明: 我这里只是介绍PC端,也就是Windows系统下的Qt环境搭建。 Android的开发环境比较麻烦,如果想学习Android开发,想编译Android程序的APP,需要自己去搭建Android环境。也可以看下面这篇文章,不过这个文章是在Qt开发专栏里付费的,需要订阅专栏才可以看。 如果不想付费看,也可以自行找其他教程,自己搭建好必须的环境就行了Android环境搭建的博客链接: cid:link_33.2 新建上位机工程前面2讲解了需要用的API接口,接下来就使用Qt设计上位机,设计界面,完成整体上位机的逻辑设计。【1】新建工程【2】设置项目的名称。【3】选择编译系统【4】选择默认继承的类【5】选择编译器【6】点击完成【7】工程创建完成3.3 设计UI界面与工程配置【1】打开UI文件打开默认的界面如下:【2】开始设计界面根据自己需求设计界面。3.5 编译Windows上位机点击软件左下角的绿色三角形按钮进行编译运行。编译之后的效果:3.6 配置Android环境如果想编译Android手机APP,必须要先自己配置好自己的Android环境。(搭建环境的过程可以自行百度搜索学习)然后才可以进行下面的步骤。【1】选择Android编译器【2】创建Android配置文件创建完成。【3】配置Android图标与名称【3】编译Android上位机Qt本身是跨平台的,直接选择Android的编译器,就可以将程序编译到Android平台。然后点击构建。成功之后,在目录下可以看到生成的apk文件,也就是Android手机的安装包,电脑端使用QQ发送给手机QQ,手机登录QQ接收,就能直接安装。生成的apk的目录在哪里呢? 编译完成之后,在控制台会输出APK文件的路径。知道目录在哪里之后,在Windows的文件资源管理器里,找到路径,具体看下图,找到生成的apk文件。D:/linux-share-dir/QT/build-app_Huawei_Eco_tracking-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Release/android-build//build/outputs/apk/debug/android-build-debug.apk四、STM32代码开发4.1 MQTT协议设计代码字数过多,无法显示...4.2 OLED显示屏驱动代码#include "oled.h"#include "stdlib.h"#include "oledfont.h" #include "delay.h"//OLED模式设置//0: 4线串行模式 (模块的BS1,BS2均接GND)//1: 并行8080模式 (模块的BS1,BS2均接VCC)#define OLED_MODE 1 //---------------------------OLED端口定义-------------------------- #define OLED_CS PDout(6)#define OLED_RST PGout(15) #define OLED_RS PDout(3)#define OLED_WR PGout(14) #define OLED_RD PGout(13) //PC0~7,作为数据线#define DATAOUT(x) GPIOC->ODR=(GPIOC->ODR&0xff00)|(x&0x00FF); //输出 //使用4线串行接口时使用 #define OLED_SCLK PCout(0)#define OLED_SDIN PCout(1) #define OLED_CMD 0 //写命令#define OLED_DATA 1 //写数据//OLED控制用函数void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Display_On(void);void OLED_Display_Off(void);void OLED_Refresh_Gram(void); void OLED_Init(void);void OLED_Clear(void);void OLED_DrawPoint(u8 x,u8 y,u8 t);void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size); //OLED的显存//存放格式如下.//[0]0 1 2 3 ... 127 //[1]0 1 2 3 ... 127 //[2]0 1 2 3 ... 127 //[3]0 1 2 3 ... 127 //[4]0 1 2 3 ... 127 //[5]0 1 2 3 ... 127 //[6]0 1 2 3 ... 127 //[7]0 1 2 3 ... 127 u8 OLED_GRAM[128][8]; //更新显存到LCD void OLED_Refresh_Gram(void){ u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7) OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址 OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } }#if OLED_MODE==1 //8080并口 //向SSD1306写入一个字节。//dat:要写入的数据/命令//cmd:数据/命令标志 0,表示命令;1,表示数据;void OLED_WR_Byte(u8 dat,u8 cmd){ DATAOUT(dat); OLED_RS=cmd; OLED_CS=0; OLED_WR=0; OLED_WR=1; OLED_CS=1; OLED_RS=1; } #else//向SSD1306写入一个字节。//dat:要写入的数据/命令//cmd:数据/命令标志 0,表示命令;1,表示数据;void OLED_WR_Byte(u8 dat,u8 cmd){ u8 i; OLED_RS=cmd; //写命令 OLED_CS=0; for(i=0;i<8;i++) { OLED_SCLK=0; if(dat&0x80)OLED_SDIN=1; else OLED_SDIN=0; OLED_SCLK=1; dat<<=1; } OLED_CS=1; OLED_RS=1; } #endif //开启OLED显示 void OLED_Display_On(void){ OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON}//关闭OLED显示 void OLED_Display_Off(void){ OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF} //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00; OLED_Refresh_Gram();//更新显示}//画点 //x:0~127//y:0~63//t:1 填充 0,清空 void OLED_DrawPoint(u8 x,u8 y,u8 t){ u8 pos,bx,temp=0; if(x>127||y>63)return;//超出范围了. pos=7-y/8; bx=y%8; temp=1<<(7-bx); if(t)OLED_GRAM[x][pos]|=temp; else OLED_GRAM[x][pos]&=~temp; }//x1,y1,x2,y2 填充区域的对角坐标//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63 //dot:0,清空;1,填充 void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot) { u8 x,y; for(x=x1;x<=x2;x++) { for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot); } OLED_Refresh_Gram();//更新显示}//在指定位置显示一个字符,包括部分字符//x:0~127//y:0~63//mode:0,反白显示;1,正常显示 //size:选择字体 12/16/24void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode){ u8 temp,t,t1; u8 y0=y; u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字体一个字符对应点阵集所占的字节数 chr=chr-' ';//得到偏移后的值 for(t=0;t { if(size==12)temp=asc2_1206[chr][t]; //调用1206字体 else if(size==16)temp=asc2_1608[chr][t]; //调用1608字体 else if(size==24)temp=asc2_2412[chr][t]; //调用2412字体 else return; //没有的字库 for(t1=0;t1<8;t1++) { if(temp&0x80)OLED_DrawPoint(x,y,mode); else OLED_DrawPoint(x,y,!mode); temp<<=1; y++; if((y-y0)==size) { y=y0; x++; break; } } } }//m^n函数u32 mypow(u8 m,u8 n){ u32 result=1; while(n--)result*=m; return result;} //显示2个数字//x,y :起点坐标 //len :数字的位数//size:字体大小//mode:模式 0,填充模式;1,叠加模式//num:数值(0~4294967295); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size){ u8 t,temp; u8 enshow=0; for(t=0;t { temp=(num/mypow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size/2)*t,y,' ',size,1); continue; }else enshow=1; } OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1); }} //显示字符串//x,y:起点坐标 //size:字体大小 //*p:字符串起始地址 void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size){ while((*p<='~')&&(*p>=' '))//判断是不是非法字符! { if(x>(128-(size/2))){x=0;y+=size;} if(y>(64-size)){y=x=0;OLED_Clear();} OLED_ShowChar(x,y,*p,size,1); x+=size/2; p++; } } //初始化SSD1306 void OLED_Init(void){ RCC->APB2ENR|=1<<4; //使能PORTC时钟 RCC->APB2ENR|=1<<5; //使能PORTD时钟 RCC->APB2ENR|=1<<8; //使能PORTG时钟 GPIOD->CRL&=0XF0FF0FFF;//PD3,6 推挽输出 GPIOD->CRL|=0X03003000; GPIOD->ODR|=1<<3; GPIOD->ODR|=1<<6; #if OLED_MODE==1 //8080并口模式 GPIOC->CRL=0X33333333; //PC0~7 OUT GPIOC->ODR|=0X00FF; GPIOG->CRH&=0X000FFFFF; //PG13,14,15 OUT GPIOG->CRH|=0X33300000; GPIOG->ODR|=7<<13; #else //4线SPI模式 GPIOC->CRL&=0XFFFFFF00; //PC0,1 OUT GPIOC->CRL|=0X00000033; GPIOC->ODR|=3<<0; GPIOG->CRH&=0X0FFFFFFF; //RST GPIOG->CRH|=0X30000000; GPIOG->ODR|=1<<15;#endif OLED_CS=1; OLED_RS=1; OLED_RST=0; delay_ms(100); OLED_RST=1; OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示 OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率 OLED_WR_Byte(80,OLED_CMD); //[3:0],分频因子;[7:4],震荡频率 OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数 OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移 OLED_WR_Byte(0X00,OLED_CMD); //默认为0 OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数. OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置 OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭 OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式 OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127; OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置 OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置 OLED_WR_Byte(0x81,OLED_CMD); //对比度设置 OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮) OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期 OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2; OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率 OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示 OLED_WR_Byte(0xAF,OLED_CMD); //开启显示 OLED_Clear();} 4.3 DHT11温湿度模块驱动代码#include "dht11.h"#include "delay.h"//IO方向设置#define DHT11_IO_IN() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}#define DHT11_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}////IO操作函数 #define DHT11_DQ_OUT PGout(11) //数据端口 PG11 #define DHT11_DQ_IN PGin(11) //数据端口 PG11u8 DHT11_Init(void); //初始化DHT11u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度u8 DHT11_Read_Byte(void); //读出一个字节u8 DHT11_Read_Bit(void); //读出一个位u8 DHT11_Check(void); //检测是否存在DHT11void DHT11_Rst(void); //复位DHT11 //复位DHT11void DHT11_Rst(void) { DHT11_IO_OUT(); //SET OUTPUT DHT11_DQ_OUT=0; //拉低DQ delay_ms(20); //拉低至少18ms DHT11_DQ_OUT=1; //DQ=1 delay_us(30); //主机拉高20~40us}//等待DHT11的回应//返回1:未检测到DHT11的存在//返回0:存在u8 DHT11_Check(void) { u8 retry=0; DHT11_IO_IN();//SET INPUT while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; else retry=0; while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; return 0;}//从DHT11读取一个位//返回值:1/0u8 DHT11_Read_Bit(void) { u8 retry=0; while(DHT11_DQ_IN&&retry<100)//等待变为低电平 { retry++; delay_us(1); } retry=0; while(!DHT11_DQ_IN&&retry<100)//等待变高电平 { retry++; delay_us(1); } delay_us(40);//等待40us if(DHT11_DQ_IN)return 1; else return 0; }//从DHT11读取一个字节//返回值:读到的数据u8 DHT11_Read_Byte(void) { u8 i,dat; dat=0; for (i=0;i<8;i++) { dat<<=1; dat|=DHT11_Read_Bit(); } return dat;}//从DHT11读取一次数据//temp:温度值(范围:0~50°)//humi:湿度值(范围:20%~90%)//返回值:0,正常;1,读取失败u8 DHT11_Read_Data(u8 *temp,u8 *humi) { u8 buf[5]; u8 i; DHT11_Rst(); if(DHT11_Check()==0) { for(i=0;i<5;i++)//读取40位数据 { buf[i]=DHT11_Read_Byte(); } if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) { *humi=buf[0]; *temp=buf[2]; } }else return 1; return 0; }//初始化DHT11的IO口 DQ 同时检测DHT11的存在//返回1:不存在//返回0:存在 u8 DHT11_Init(void){ RCC->APB2ENR|=1<<8; //使能PORTG口时钟 GPIOG->CRH&=0XFFFF0FFF;//PORTG.11 推挽输出 GPIOG->CRH|=0X00003000; GPIOG->ODR|=1<<11; //输出1 DHT11_Rst(); return DHT11_Check();}4.4 定时器配置代码#include "timer.h"#include "led.h"//定时器3中断服务程序 void TIM3_IRQHandler(void){ if(TIM3->SR&0X0001)//溢出中断 { LED1=!LED1; } TIM3->SR&=~(1<<0);//清除中断标志位 }//通用定时器3中断初始化//这里时钟选择为APB1的2倍,而APB1为36M//arr:自动重装值。//psc:时钟预分频数//这里使用的是定时器3!void TIM3_Int_Init(u16 arr,u16 psc){ RCC->APB1ENR|=1<<1; //TIM3时钟使能 TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟 TIM3->DIER|=1<<0; //允许更新中断 TIM3->CR1|=0x01; //使能定时器3 MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2 }//TIM3 PWM部分初始化 //PWM输出初始化//arr:自动重装值//psc:时钟预分频数void TIM3_PWM_Init(u16 arr,u16 psc){ //此部分需手动修改IO口设置 RCC->APB1ENR|=1<<1; //TIM3时钟使能 RCC->APB2ENR|=1<<3; //使能PORTB时钟 GPIOB->CRL&=0XFF0FFFFF; //PB5输出 GPIOB->CRL|=0X00B00000; //复用功能输出 RCC->APB2ENR|=1<<0; //开启辅助时钟 AFIO->MAPR&=0XFFFFF3FF; //清除MAPR的[11:10] AFIO->MAPR|=1<<11; //部分重映像,TIM3_CH2->PB5 TIM3->ARR=arr; //设定计数器自动重装值 TIM3->PSC=psc; //预分频器不分频 TIM3->CCMR1|=7<<12; //CH2 PWM2模式 TIM3->CCMR1|=1<<11; //CH2预装载使能 TIM3->CCER|=1<<4; //OC2 输出使能 TIM3->CR1=0x0080; //ARPE使能 TIM3->CR1|=0x01; //使能定时器3 } //定时器5通道1输入捕获配置//arr:自动重装值//psc:时钟预分频数void TIM5_Cap_Init(u16 arr,u16 psc){ RCC->APB1ENR|=1<<3; //TIM5 时钟使能 RCC->APB2ENR|=1<<2; //使能PORTA时钟 GPIOA->CRL&=0XFFFFFFF0; //PA0 清除之前设置 GPIOA->CRL|=0X00000008; //PA0 输入 GPIOA->ODR|=0<<0; //PA0 下拉 TIM5->ARR=arr; //设定计数器自动重装值 TIM5->PSC=psc; //预分频器 TIM5->CCMR1|=1<<0; //CC1S=01 选择输入端 IC1映射到TI1上 TIM5->CCMR1|=0<<4; //IC1F=0000 配置输入滤波器 不滤波 TIM5->CCMR1|=0<<10; //IC2PS=00 配置输入分频,不分频 TIM5->CCER|=0<<1; //CC1P=0 上升沿捕获 TIM5->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中 TIM5->DIER|=1<<1; //允许捕获中断 TIM5->DIER|=1<<0; //允许更新中断 TIM5->CR1|=0x01; //使能定时器2 MY_NVIC_Init(2,0,TIM5_IRQn,2);//抢占2,子优先级0,组2 }//捕获状态//[7]:0,没有成功的捕获;1,成功捕获到一次.//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.//[5:0]:捕获高电平后溢出的次数u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态 u16 TIM5CH1_CAPTURE_VAL; //输入捕获值//定时器5中断服务程序 void TIM5_IRQHandler(void){ u16 tsr; tsr=TIM5->SR; if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if(tsr&0X01)//溢出 { if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 { if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 { TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 TIM5CH1_CAPTURE_VAL=0XFFFF; }else TIM5CH1_CAPTURE_STA++; } } if(tsr&0x02)//捕获1发生捕获事件 { if(TIM5CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 { TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 TIM5CH1_CAPTURE_VAL=TIM5->CCR1; //获取当前的捕获值. TIM5->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获 }else //还未开始,第一次捕获上升沿 { TIM5CH1_CAPTURE_STA=0; //清空 TIM5CH1_CAPTURE_VAL=0; TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 TIM5->CNT=0; //计数器清空 TIM5->CCER|=1<<1; //CC1P=1 设置为下降沿捕获 } } } TIM5->SR=0;//清除中断标志位 }五、总结本项目致力于构建一套基于STM32F103RCT6微控制器和NBIOT-BC26通信模块的农作物生长管理系统。系统的核心功能在于实时监测农田环境中的关键参数,例如土壤含水量、环境光照强度、温度与湿度,并据此实现自动化管理。具体而言,系统能够依据预设的阈值自动控制补水,同时允许用户通过本地按钮或远程控制的方式进行手动补水。此外,系统还能根据环境亮度的变化自动调节补光灯的亮度,以保证植物获得适宜的光照条件。为了保障作物生长环境的安全性,系统配置了环境温湿度传感器(DHT11),并在检测到温度或湿度超出预设范围时触发蜂鸣器报警。这些阈值可以通过手机应用程序进行设定,使得系统更加灵活易用。系统还配备了一块0.96寸的OLED显示屏,用于实时显示环境温度、湿度、土壤含水量以及光照强度等重要参数,使用户能够直观地了解当前的环境状况。考虑到突然的温度变化可能导致误操作,系统采用了适当的控制策略,在设定温度出现较大波动时延迟系统的反应调节时间,从而避免不必要的误动作。整个设备通过NBIOT-BC26模块连接至华为云IoT平台,并采用MQTT协议上传数据,使得用户能够借助微信小程序远程监控设备状态并进行控制,包括调整设备的温度阈值等设置。项目利用Qt框架开发了一个Android版的应用程序,进一步增强了系统的远程监控与控制能力。该应用程序不仅可以显示远程监测数据,还可以让用户随时随地控制设备的各项功能。供电方面,系统选择了简便且易于获取的USB线5V供电方案,方便用户安装与使用。该项目通过集成先进的传感器技术和物联网应用,为现代化农业生产提供了一套高效、便捷且智能化的解决方案。
  • XX项目-RDA-SMS主机迁移
    案例简介:       采用专线网络迁移,带宽1G,利用两个私网NAT网关,配置SNAT、DNAT规则,可同时将源、目的网段地址转换为中转IP,通过使用中转IP实现两VPC间互通。私网NAT网关解决了两个重叠网段VPC中的云主机互相访问的问题。 在HCSO部署RDA迁移工具,在RDA界面配置云环境信息,测试RDA到源端IDC主机以及RDA到HCSO上ECS连通性;配置主机迁移任务进行主机迁移测试。将IDC机房Vmware虚拟化主机以及物理机通过RDA-SMS迁移至HCSO上ECS,对于外接物理Key的物理机,将物理机迁移至ECS后改造物理key为电子密钥;个别有物理秘钥且不可改造的物理机通过物理搬迁的方式托管在政务云托管区。主机迁移后进行数据校验及功能验证,确保业务可正常使用,验证完成后割接前做一次或多次增量数据迁移,缩短割接时最后一次增量迁移的时间。割接:优先割接无公网及数据库依赖的独立系统,最后统一割接依赖Oracle数据库及59段公网IP的所有系统。方案描述:开放端口:1、RDA服务器采集源端主机信息, Linux主机通过ssh协议root账户采集,需要开通RDA到源端主机ssh协议端口(默认为22,如果做过修改则开放对应端口)。Windows主机通过Winrm服务管理员账户采集,需要开通Winrm服务端口(默认为5985,目前RDA不支持修改Windows主机采集端口)。2、迁移时数据传输,Linux主机通过rsync传输文件,通过ssh协议需要开放目的端主机ssh默认端口22,Windows通过8899/8900端口传输数据,需要开放目的端主机8899/8900端口.迁移步骤:1、登录RDA服务平台,配置RDA所要上云的云账号及云环境。创建迁移任务。2、迁移任务配置好之后RDA通过API网关去OBS桶下载SMS-agent插件。3、 RDA服务推送SMS-agent插件到源端服务器并解压后启动安装,同时校验源端服务器到API网关的连通性。4、源端服务器通过SMS-agent调用EVS接口创建临时EVS公有镜像磁盘。5、挂载临时迁移镜像到目的端服务器。6、对目的端ECS进行规格,磁盘查询,如果目的端主机未创建会通过接口创建虚拟机。7、迁移源端磁盘数据到目的端服务器。相关文档:RDA 2.0用户指南RDA主机迁移最佳实践公有云上云迁移工具SMSRDA培训及实操
  • 北非XX项目AWS DynamoDB到GeminiDB Cassandra迁移上云
    案例简介:XX公司成立于2015年,是目前全球UGC赛道最大的中国游戏公司,在全球拥有XX万注册用户,覆盖美国、新加坡、港澳台、法国、阿联酋、巴西等XX个国家。目前客户现网以AWS+GCP部署为主,目前在AWS一年消耗XXWUSD,主要为业务大厅服源站以及数据收集和分析功能,包含大数据、数据库等业务,GCP一年消耗XXUSD,主要为业务战斗服,包含服务器和流量业务,本次迁移包含DynamoDB(XX张表,XTB)需要跨云平台迁移。方案描述:数据迁移:1、在华为云申请ECS主机用于安装DynamoMigration;2、配置DynamoMigration参数文件;3、启动DynamoMigration进行全量迁移;4、全量迁移完成后,对数据进行抽检,检查数据一致性校验;5、数据校验通过后,停止DynamoMigration服务,业务连接华为云GaussDB for Cassandra实例开始对外提供业务。回退方案:1、AWS侧创建备用表,承接回退数据;2、配置DynamoMigration配置文件,建立华为云-AWS全量迁移链路;3、待全量迁移完成后,对数据一致性进行校验4、数据校验通过后,停止DynamoMigration服务,应用修改数据库链接为AWS 实例备用表,对外提供业务。
  • [技术干货] 【开发者空间】华为云开发者云主机体验过程
    一、前言云主机是华为云为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具体系,让每一位开发者拥有一台云主机,基于华为根生态开发、创新。二、领取云主机领取地址:cid:link_0申请之后,会提示加入开发者空间,根据提示选择配置就行了。配置之后。在这里可以进去云主机的工作空间。第一次配置,初始化需要一点时间。初始化完毕之后,就可以进去桌面体验了。下面是进入桌面的提示状态。进去桌面后的效果。直接在浏览器里访问很方面。 非常方便在Linux环境下做项目开发测试。对于复制粘贴,本地电脑不能直接copy,需要使用工具进行安全的复制粘贴。三、快速体验YOLOV3YOLOv3(You Only Look Once version 3)是一种高效的目标检测算法,由Joseph Redmon等人开发。它是YOLO系列算法的第三个版本,旨在实现快速而准确的对象检测。与传统的两阶段目标检测方法(如R-CNN系列算法)不同,YOLOv3采用了一次性(single-shot)检测方法,这意味着它可以在一个单一的神经网络前向传播过程中同时完成对象分类和边界框回归。YOLOv3的主要特性包括:主干网络:YOLOv3使用Darknet-53作为其基础网络,这是对YOLOv2中Darknet-19的一个深度增强版,提供了更好的特征提取能力。多尺度检测:YOLOv3采用了特征金字塔网络(Feature Pyramid Network,FPN)的概念,实现了在三个不同的尺度上进行检测,分别是13x13、26x26和52x53的特征图分辨率,这有助于检测不同大小的对象。锚框(Anchor Boxes):YOLOv3使用预定义的锚框来预测对象的位置,这些锚框是通过对训练数据集中对象的尺寸进行聚类得到的。分类器:在对象分类方面,YOLOv3使用Logistic回归来预测每个类别的概率,这允许它处理包含多个标签的对象,即一个对象可能属于多个类别的情况。损失函数:YOLOv3的损失函数综合考虑了边界框坐标、对象存在性和类别预测的误差。训练和预测:YOLOv3能够在单张图像上同时预测多个对象,且由于其一次性检测的特性,它能实现实时处理速度,非常适合实时视频流处理等场景。YOLOv3因其在速度与精度之间的良好平衡而在工业界和学术界得到了广泛应用。随着后续版本如YOLOv4和YOLOv5的推出,虽然YOLOv3可能不再是最新版本,但它仍然是理解和实现现代目标检测算法的重要基准。YOLO算法官网介绍:cid:link_1You only look once (YOLO) is a state-of-the-art, real-time object detection system. On a Pascal Titan X it processes images at 30 FPS and has a mAP of 57.9% on COCO test-dev.You Only Look Once (YOLO) 是最先进的实时目标检测系统。在 Pascal Titan X 上,它以 30 FPS 处理图像,并且在 COCO 测试开发上的 mAP 为 57.9%。Comparison to Other Detectors YOLOv3 is extremely fast and accurate. In mAP measured at .5 IOU YOLOv3 is on par with Focal Loss but about 4x faster. Moreover, you can easily tradeoff between speed and accuracy simply by changing the size of the model, no retraining required!与其他探测器的比较 YOLOv3 非常快速且准确。在 mAP 中,测量结果为 0.5 IOU YOLOv3 与 Focal Loss 相当,但速度快约 4 倍。此外,只需更改模型的大小即可轻松在速度和准确性之间进行权衡,无需重新训练!在Linux下快速体验YOLO算法的目标检测(采用官方的模型)。(1)安装darknet(打开命令行终端进行操作即可)git clone https://github.com/pjreddie/darknetcd darknetmake如果克隆失败,多试几次即可。编译中:(2)下载权重文件wget https://pjreddie.com/media/files/yolov3.weightsyolov3.weights 是 YOLOv3 网络训练得到的权重文件,存储了神经网络中每个层次的权重和偏置信息。在cfg/目录下已经包含了yolov3对应的配置文件。权重文件下载中:(3)运行detector./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg运行输出的信息:layer filters size input output 0 conv 32 3 x 3 / 1 416 x 416 x 3 -> 416 x 416 x 32 0.299 BFLOPs 1 conv 64 3 x 3 / 2 416 x 416 x 32 -> 208 x 208 x 64 1.595 BFLOPs ....... 105 conv 255 1 x 1 / 1 52 x 52 x 256 -> 52 x 52 x 255 0.353 BFLOPs 106 detectiontruth_thresh: Using default '1.000000'Loading weights from yolov3.weights...Done!data/dog.jpg: Predicted in 0.029329 seconds.dog: 99%truck: 93%bicycle: 99%运行过程:查看原来图片:查看识别成功的图片:识别测试2:./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <video file>如果想实时识别视频,可以运行下面的命令:./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <video file>
  • [问题求助] 数据转发到设备的topic定义
    topic定义为:$oc/devices/{device_id}/sys/messages/down错误原因也搜不到
总条数:141 到第
上滑加载中