• [技术干货] 【CC2530开发基础篇】读取MQ2烟雾的烟雾浓度值【ADC采集】
    一、前言1.1 开发背景本实验基于CC2530单片机和MQ-2气体传感器,通过模拟信号采集的方式实现烟雾浓度的检测与显示。CC2530作为一款强大的低功耗无线单片机,具有丰富的GPIO接口,可以方便地进行多种传感器的接入与数据处理。本实验的重点是通过ADC(模拟到数字转换器)接口读取MQ-2传感器的模拟输出信号,将其转化为数字信号,从而实现烟雾浓度的量化输出。MQ-2气体传感器能够检测多种气体的浓度,常用于烟雾、甲烷、液化气等气体的监测。在本实验中,传感器通过模拟电压信号反映气体浓度的变化。为了提高传感器的灵敏度,可以通过调节MQ-2上的蓝色电阻来优化响应性能。通过使用火机释放少量气体至传感器探头,可以观察到串口调试助手中数据的实时变化,反映出气体浓度的变化情况。本实验的主要目的在于通过实际操作了解如何配置和使用CC2530的GPIO接口,如何使用MQ-2传感器进行气体检测,以及如何将传感器的数据通过串口输出显示。在实验过程中,调节气体浓度,观察串口助手中的数据变化,有助于加深对气体传感原理与传感器应用的理解。这是当前实验使用的CC2530板子的实物图:1.2 MQ-2气体传感器MQ-2气体传感器是一种广泛应用于各种安全监测系统的元件,特别适合用于家庭和工业环境中检测可燃气体泄露以及烟雾浓度。该传感器的核心部分是一个气敏电阻,当周围空气中的特定气体浓度发生变化时,气敏电阻的阻值也会随之改变。MQ-2传感器可以检测多种气体,包括但不限于液化石油气(LPG)、异丁烷、甲烷(CH4)、酒精、氢气(H2)以及烟雾等,这使得它在多个领域内都有非常广泛的应用。MQ-2传感器的设计采用了简单的加热丝结构,工作时需要一定的预热时间,通常建议预热时间为24小时以上,以便达到最佳的工作状态。传感器内部的加热丝在通电后会产生热量,促使气敏材料表面发生化学反应,进而改变其电阻值。通过测量这一变化,就可以间接地得知空气中目标气体的浓度。值得注意的是,MQ-2传感器上配备有一个可调的蓝色电位器,用户可以通过调节这个电位器来调整传感器的灵敏度,以适应不同应用场景的需求。在实际应用中,MQ-2气体传感器通常会与微控制器配合使用,例如本实验中使用的CC2530单片机。通过将传感器输出的模拟信号转换为数字信号,再由微控制器进行处理和分析,最终实现对环境气体浓度的精确监测。此外,为了确保数据的准确性和可靠性,还需要对传感器进行适当的校准。校准过程通常涉及在已知气体浓度的环境下测量传感器的输出值,并据此调整算法中的参数,以提高检测精度。 MQ-2气体传感器以其成本低廉、使用方便、响应迅速等特点,成为了众多气体检测应用的理想选择。1.3 项目硬件模块组成(1) CC2530单片机 作为核心控制单元,CC2530单片机负责接收来自MQ-2气体传感器的模拟信号,通过ADC模块进行转换,并将处理后的浓度数据通过串口输出至串口调试助手。(2) MQ-2气体传感器 MQ-2传感器用于检测空气中的烟雾、甲烷、液化气等气体的浓度。其模拟输出信号(AO)连接到CC2530的ADC输入引脚,CC2530将采集到的模拟电压值转换为数字量,进而计算出气体浓度。(3) 电源模块 为整个系统提供稳定的电源。CC2530单片机和MQ-2传感器都需要通过VCC和GND接入适当的电源(通常为3.3V或5V)。(4) 串口通信模块 用于实现CC2530单片机与PC之间的数据通信。通过串口0(UART)输出烟雾浓度数据,供串口调试助手显示和监控。(5) 调节电阻(蓝色电阻) MQ-2传感器上有一个可调电阻,用于调节传感器的灵敏度。通过调整该电阻,可以改变传感器对气体浓度变化的响应能力,使其适应不同的检测环境。(6) 火机(气体源) 用于向MQ-2传感器释放气体,模拟环境中气体浓度的变化,观察传感器输出和串口数据的响应。(7) 串口调试助手 用于接收和显示来自CC2530单片机通过串口发送的烟雾浓度数据,帮助观察气体浓度变化与传感器响应的关系。1.4 项目实现的功能功能编号功能描述(1)烟雾浓度检测:使用MQ-2气体传感器检测空气中的烟雾浓度,并输出模拟信号。(2)模拟信号转换:CC2530通过ADC模块将MQ-2传感器的模拟信号转换为数字信号。(3)浓度数据计算:CC2530单片机根据ADC采集到的数字信号计算烟雾浓度。(4)串口数据输出:将计算得出的烟雾浓度数据通过串口0输出,供串口调试助手显示。(5)灵敏度调节:通过调节MQ-2传感器上的蓝色电阻,调整传感器的灵敏度,以适应不同环境下的气体检测需求。(6)实时数据监控:通过串口调试助手监控并显示烟雾浓度数据的变化,响应环境中气体浓度的波动。(7)气体源模拟:使用火机释放气体至MQ-2传感器探头,模拟气体浓度的变化,验证系统对浓度变化的响应。二、CC2530基础知识科普2.1 CC2530 与 ZigBee 的含义CC2530是什么CC2530是一款由德州仪器(Texas Instruments,TI)推出的无线微控制器芯片,专为低功耗和无线通信应用设计。它基于8051内核,具有丰富的片上资源,包括128 KB的闪存、8 KB的RAM、多个UART和SPI接口、ADC模块等。此外,CC2530支持IEEE 802.15.4标准,这是ZigBee协议栈的基础。CC2530的低功耗特性和高集成度使其特别适用于智能家居、物联网(IoT)设备和工业自动化等应用场景。ZigBee是什么ZigBee是一种基于IEEE 802.15.4标准的无线通信协议,专为低功耗、低数据速率和短距离应用场景设计。它的主要特点是功耗低、组网灵活、支持大规模网络节点(如星型、网状和树形拓扑),并且具有较强的抗干扰能力。ZigBee常用于智能家居(如智能灯控、温湿度传感器)、工业物联网、医疗设备和农业监控等领域。与Wi-Fi和蓝牙相比,ZigBee适合需要低功耗、低数据速率和高网络节点容量的应用。CC2530与ZigBee的联系CC2530是支持ZigBee协议的硬件平台之一。CC2530的硬件架构和无线射频模块完全符合IEEE 802.15.4标准,而ZigBee协议栈则是运行在该标准之上的通信协议。通过在CC2530芯片上加载ZigBee协议栈(如TI提供的Z-Stack),用户可以构建完整的ZigBee无线通信系统。CC2530作为ZigBee设备的实现平台,可以配置为不同类型的ZigBee节点,包括协调器(Coordinator)、路由器(Router)和终端设备(End Device)。协调器负责整个ZigBee网络的建立和管理,路由器用于中继信号扩展网络范围,终端设备通常是低功耗的传感器或执行器。CC2530是支持ZigBee协议的硬件芯片,而ZigBee是运行在像CC2530这样的硬件平台上的通信协议。CC2530为ZigBee提供硬件支持,ZigBee则为CC2530提供实现复杂网络功能的能力。这种软硬结合使得CC2530成为ZigBee应用中的主流选择之一。2.2 CC2530的开发环境CC2530官方推荐的开发环境是 IAR Embedded Workbench(IAR EW8051)。CC2530的开发环境:IAR Embedded WorkbenchIAR Embedded Workbench(简称IAR)是开发CC2530的主要集成开发环境(IDE)。它是一款专业的嵌入式软件开发工具,提供了编辑、编译、调试和优化等功能,广泛支持各种嵌入式微控制器平台,包括基于8051内核的CC2530。IAR针对低功耗和无线设备开发进行了深度优化,特别适合CC2530这类资源有限的嵌入式芯片。IAR支持德州仪器的ZigBee协议栈(如Z-Stack),并提供了配套的调试工具和编译器,使开发者能够轻松集成ZigBee协议、编写应用代码和调试固件。此外,IAR具有良好的代码优化能力,能有效减少CC2530有限内存的占用,提高程序运行效率。为什么使用IAR开发CC2530使用IAR开发CC2530主要是由于以下原因:官方支持 德州仪器推荐使用IAR开发CC2530,因为其ZigBee协议栈(如Z-Stack)是专门为IAR优化的,许多示例代码和参考项目直接在IAR环境中运行,减少了开发者的移植工作。代码优化能力强 IAR的编译器提供了高效的代码优化功能,包括针对代码大小和运行速度的优化选项。对于资源受限的CC2530(如闪存128 KB和RAM 8 KB),IAR可以显著减小二进制文件大小,让更多复杂功能得以实现。调试工具完善 IAR集成了强大的调试工具,支持CC2530的片上调试功能(On-Chip Debugging)。通过与TI的调试硬件(如CC Debugger)配合,开发者可以实时查看和控制程序运行状态,进行断点设置、变量监控和性能分析。多功能集成 IAR提供了丰富的功能模块,如静态分析、运行时调试和内存分析工具。这些功能特别适合复杂协议栈(如ZigBee)的开发,帮助开发者迅速定位和解决问题。IAR与Keil的区别Keil也是一款非常流行的嵌入式开发工具,但在开发CC2530时,IAR相比Keil具有以下显著区别:官方适配支持 TI官方的ZigBee协议栈和示例项目主要为IAR设计,Keil并没有直接支持这些协议栈。因此,使用Keil开发CC2530需要进行额外的移植工作,而IAR则可以开箱即用。编译器优化效果 IAR的编译器在优化代码大小方面普遍优于Keil,这对于资源有限的CC2530尤为重要。在存储和性能受限的情况下,IAR可以更高效地利用芯片资源。协议栈复杂度支持 ZigBee协议栈本身较为复杂,对编译器和开发环境的要求较高。IAR对复杂嵌入式协议的支持更为成熟,而Keil的侧重点更多在通用8051开发。工具链兼容性 IAR与CC2530配套的调试工具(如CC Debugger)无缝集成,调试体验更流畅。Keil在支持TI调试硬件方面不够完善,可能需要第三方工具或插件进行适配。IAR是CC2530开发的首选环境,其强大的优化能力、完善的调试功能和与ZigBee协议的高兼容性,使得开发者能够更加高效地完成项目。而Keil尽管也支持8051平台,但在CC2530开发中的表现和适配性稍逊一筹。2.3 IAR新建工程的步骤三、代码设计代码的含义看中文注释,这里不再单独写文字介绍代码含义。3.1 main.c#include "ioCC2530.h" #include "string.h" ​ ​ typedef unsigned char uchar; typedef unsigned int uint; typedef signed short int16; typedef unsigned short uint16; ​ char TxBuf[5]; uint16 GasData; ​ uint16 ReadGasData( void ); ​ /**************************************************************************** * 名 称: InitUart() * 功 能: 串口初始化函数 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitUart(void) { PERCFG = 0x00; //外设控制寄存器 USART 0的IO位置:0为P0口位置1 P0SEL = 0x0c; //P0_2,P0_3用作串口(外设功能) P2DIR &= ~0XC0; //P0优先作为UART0 U0CSR |= 0x80; //设置为UART方式 U0GCR |= 8; U0BAUD |= 59; //波特率设为9600 UTX0IF = 0; //UART0 TX中断标志初始置位0 } ​ /**************************************************************************** * 名 称: UartSendString() * 功 能: 串口发送函数 * 入口参数: Data:发送缓冲区 len:发送长度 * 出口参数: 无 ****************************************************************************/ void UartSendString(char *Data, int len) { uint i; for(i=0; i<len; i++) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } } ​ /**************************************************************************** * 名 称: DelayMS() * 功 能: 以毫秒为单位延时 16M时约为535,32M时要调整,系统时钟不修改默认为16M * 入口参数: msec 延时参数,值越大延时越久 * 出口参数: 无 ****************************************************************************/ void DelayMS(uint msec) { uint i,j; for (i=0; i<msec; i++) for (j=0; j<1070; j++); } ​ uint16 ReadGasData( void ) { uint16 reading = 0; /* Enable channel */ ADCCFG |= 0x40; /* writing to this register starts the extra conversion */ ADCCON3 = 0x86;// AVDD5 引脚 00: 64 抽取率(7 位ENOB) 0110: AIN6 /* Wait for the conversion to be done */ while (!(ADCCON1 & 0x80)); /* Disable channel after done conversion */ ADCCFG &= (0x40 ^ 0xFF); //按位异或。如1010^1111=0101(二进制) /* Read the result */ reading = ADCL; reading |= (int16) (ADCH << 8); reading >>= 8; return (reading); } ​ void main(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定为32M CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ InitUart(); //调置串口相关寄存器 while(1) { GasData = ReadGasData(); //读取烟雾传感器引脚上的ad转换值,并没有换算成能表示烟雾浓度的值 //演示如何使用2530芯片的AD功能,更具体在组网中给出 //读取到的数值转换成字符串,供串口函数输出 TxBuf[0] = GasData / 100 + '0'; TxBuf[1] = GasData / 10%10 + '0'; TxBuf[2] = GasData % 10 + '0'; TxBuf[3] = '\n'; TxBuf[4] = 0; UartSendString(TxBuf, 4); //想串口助手送出数据,波特率是115200 DelayMS(2000); //延时函数 } } ​四、总结通过本次实验,成功地将CC2530单片机与MQ-2气体传感器结合,实现了烟雾浓度的实时检测与显示。实验中,使用ADC模块将模拟信号转换为数字信号,从而得到烟雾浓度值,并通过串口输出至调试助手,展示了数据的变化和传感器的响应。整个实验过程不仅加深了对单片机硬件接口配置的理解,还实践了如何与传感器进行交互,采集模拟信号并将其转换为有用的数据。在实验过程中,灵敏度的调节使得传感器对不同气体浓度的响应更加精确,通过调节MQ-2传感器上的蓝色电阻,可以在不同的实验环境中优化其性能。此外,使用火机释放气体测试了传感器的实际响应,验证了系统的功能和数据输出的准确性。本次实验不仅实现了烟雾浓度的检测功能,还帮助掌握了如何通过硬件和软件的结合完成实际的传感器应用。通过串口调试助手实时显示数据,为后续的项目开发提供了良好的实践经验和技术基础,为类似的气体检测项目提供了可行的解决方案。
  • [技术干货] 【CC2530开发基础篇】人体红外传感器
    一、前言1.1 开发背景热释电人体红外传感器广泛应用于智能家居、安防监控、自动控制等领域,能够通过检测人体的热辐射变化来判断是否有人存在。该传感器通过热释电效应将人体热辐射转化为电信号,进而通过数字信号输出,实现对环境中人体活动的感知。与其他传感器相比,热释电人体红外传感器具有响应速度快、灵敏度高、成本低等优势,特别适用于需要检测人体存在或运动的场景。CC2530是一款基于8051内核的低功耗无线单片机,具有丰富的GPIO接口和高效的处理能力,适合与各种传感器进行连接。通过将热释电人体红外传感器与CC2530结合,能够实现对环境中是否有人的实时监测。通过将传感器的OUT脚与CC2530的P0.7引脚连接,系统可以通过数字信号高低电平的变化,判断是否有热源进入传感器的探测范围。在本项目中,CC2530通过读取热释电人体红外传感器的OUT脚信号,实时检测人体的存在与否,并将结果通过串口0发送至串口调试助手,便于实时显示和调试。这种设计简洁且高效,为实现智能化监控与控制提供了基础平台,适用于各种需要检测人员存在的场景。这是当前实验使用的CC2530板子的实物图:1.2 热释电人体红外传感器热释电人体红外传感器是一种利用热释电效应工作的传感器,能够感知到人体等物体所发出的红外辐射。人类和动物的体温大约为37℃,而环境的温度通常较低,这导致人体会以红外辐射的形式发出热量。热释电传感器通过检测这些热辐射的变化来判断是否有热源进入其探测范围,进而实现对人体存在与否的感知。热释电人体红外传感器的核心组件是热释电材料,这种材料对温度变化极为敏感。当人体或其他热源通过传感器的探测区域时,热释电材料会感受到温度的变化并产生电荷。传感器内的电路会将这些电荷转换为电信号,从而检测到红外辐射的变化。这种变化通常表现为传感器输出的电压或电流信号的波动,进而被处理和分析。大多数热释电传感器使用了一个由多个热释电元件构成的阵列,以确保覆盖较大的探测范围。当人体进入传感器的视野时,会在这些元件上产生温度差异,这些差异被转化为电信号,输出至外部电路。通常,这些传感器提供的是数字输出或模拟输出。数字输出表示人体的存在与否(通常是高低电平状态),而模拟输出则提供连续变化的信号,可以用来检测人体活动的强度或距离。热释电人体红外传感器在工作时通常会有一个“静态”信号,即在没有运动或热源变化的情况下输出一个稳定的电平。一旦有运动或热源进入传感器的探测范围,信号会发生变化,从而触发外部设备的响应。由于其高灵敏度和快速响应特性,热释电红外传感器常用于安防、自动照明、智能家居等系统中,能够实现自动化的环境控制和监测。这些传感器通常非常节能,适合长时间运行,且安装和使用都较为简便。它们不需要直接接触被监测物体,只需通过探测热辐射即可,因此具有较高的灵敏度和较长的探测距离。尽管如此,热释电人体红外传感器的工作性能可能会受到环境温度、湿度以及外部光源等因素的影响,因此,在设计和应用中需要对这些因素进行适当的补偿和优化。1.3 项目硬件模块组成(1) CC2530主控芯片 作为系统的核心控制单元,负责读取热释电人体红外传感器的数字信号,并通过串口将检测结果传输到PC端。(2) 热释电人体红外传感器 用于检测环境中的人体活动,当人体进入传感器的探测范围时,传感器输出高电平信号,表示有人的存在。(3) P0.7 GPIO接口 CC2530的P0.7引脚作为输入端口,连接热释电人体红外传感器的OUT引脚,用于接收传感器输出的高低电平信号。(4) 电源模块 提供稳定的电源,确保CC2530和热释电人体红外传感器正常工作。CC2530通常使用3.3V电压,而传感器一般使用5V电压。(5) 串口通信模块 利用CC2530的UART0接口将检测到的信号结果通过串口发送到PC端,用于实时显示和数据监测。(6) 串口调试助手 运行在PC端的调试工具,接收并显示从CC2530传输的串口数据,方便开发人员调试和验证系统的工作状态。1.4 项目实现的功能功能模块具体描述实现方式人体存在检测通过热释电人体红外传感器检测环境中是否有人进入探测范围。热释电人体红外传感器输出高低电平信号信号采集CC2530通过读取热释电传感器的OUT引脚的电平变化,判断是否有人存在。CC2530读取P0.7引脚的高低电平信号实时输出结果将检测到的结果通过串口实时传输至PC端,方便显示和监控。使用CC2530的UART0接口将数据发送至PC端状态显示在PC端的串口调试助手上显示人体是否存在的状态信息,便于用户监控。串口调试助手接收并显示从CC2530传来的数据简单接口设计提供简单的数字信号输出(高低电平),便于直接与单片机或其他控制系统连接,判断人体是否进入探测范围。使用数字信号的高低电平判断人体存在与否低功耗设计CC2530和热释电人体红外传感器具有低功耗特性,适合长时间监测和工作。利用CC2530的低功耗特性和传感器的节能设计便捷调试功能提供串口调试助手用于调试,验证系统的工作状态。通过串口调试助手查看传输的信号,调试系统工作状态灵活扩展系统设计简单,可灵活扩展,支持接入更多传感器或控制模块,扩展更多功能。CC2530的多功能接口可以方便地接入其他传感器或设备二、CC2530基础知识科普2.1 CC2530 与 ZigBee 的含义CC2530是什么CC2530是一款由德州仪器(Texas Instruments,TI)推出的无线微控制器芯片,专为低功耗和无线通信应用设计。它基于8051内核,具有丰富的片上资源,包括128 KB的闪存、8 KB的RAM、多个UART和SPI接口、ADC模块等。此外,CC2530支持IEEE 802.15.4标准,这是ZigBee协议栈的基础。CC2530的低功耗特性和高集成度使其特别适用于智能家居、物联网(IoT)设备和工业自动化等应用场景。ZigBee是什么ZigBee是一种基于IEEE 802.15.4标准的无线通信协议,专为低功耗、低数据速率和短距离应用场景设计。它的主要特点是功耗低、组网灵活、支持大规模网络节点(如星型、网状和树形拓扑),并且具有较强的抗干扰能力。ZigBee常用于智能家居(如智能灯控、温湿度传感器)、工业物联网、医疗设备和农业监控等领域。与Wi-Fi和蓝牙相比,ZigBee适合需要低功耗、低数据速率和高网络节点容量的应用。CC2530与ZigBee的联系CC2530是支持ZigBee协议的硬件平台之一。CC2530的硬件架构和无线射频模块完全符合IEEE 802.15.4标准,而ZigBee协议栈则是运行在该标准之上的通信协议。通过在CC2530芯片上加载ZigBee协议栈(如TI提供的Z-Stack),用户可以构建完整的ZigBee无线通信系统。CC2530作为ZigBee设备的实现平台,可以配置为不同类型的ZigBee节点,包括协调器(Coordinator)、路由器(Router)和终端设备(End Device)。协调器负责整个ZigBee网络的建立和管理,路由器用于中继信号扩展网络范围,终端设备通常是低功耗的传感器或执行器。CC2530是支持ZigBee协议的硬件芯片,而ZigBee是运行在像CC2530这样的硬件平台上的通信协议。CC2530为ZigBee提供硬件支持,ZigBee则为CC2530提供实现复杂网络功能的能力。这种软硬结合使得CC2530成为ZigBee应用中的主流选择之一。2.2 CC2530的开发环境CC2530官方推荐的开发环境是 IAR Embedded Workbench(IAR EW8051)。CC2530的开发环境:IAR Embedded WorkbenchIAR Embedded Workbench(简称IAR)是开发CC2530的主要集成开发环境(IDE)。它是一款专业的嵌入式软件开发工具,提供了编辑、编译、调试和优化等功能,广泛支持各种嵌入式微控制器平台,包括基于8051内核的CC2530。IAR针对低功耗和无线设备开发进行了深度优化,特别适合CC2530这类资源有限的嵌入式芯片。IAR支持德州仪器的ZigBee协议栈(如Z-Stack),并提供了配套的调试工具和编译器,使开发者能够轻松集成ZigBee协议、编写应用代码和调试固件。此外,IAR具有良好的代码优化能力,能有效减少CC2530有限内存的占用,提高程序运行效率。为什么使用IAR开发CC2530使用IAR开发CC2530主要是由于以下原因:官方支持 德州仪器推荐使用IAR开发CC2530,因为其ZigBee协议栈(如Z-Stack)是专门为IAR优化的,许多示例代码和参考项目直接在IAR环境中运行,减少了开发者的移植工作。代码优化能力强 IAR的编译器提供了高效的代码优化功能,包括针对代码大小和运行速度的优化选项。对于资源受限的CC2530(如闪存128 KB和RAM 8 KB),IAR可以显著减小二进制文件大小,让更多复杂功能得以实现。调试工具完善 IAR集成了强大的调试工具,支持CC2530的片上调试功能(On-Chip Debugging)。通过与TI的调试硬件(如CC Debugger)配合,开发者可以实时查看和控制程序运行状态,进行断点设置、变量监控和性能分析。多功能集成 IAR提供了丰富的功能模块,如静态分析、运行时调试和内存分析工具。这些功能特别适合复杂协议栈(如ZigBee)的开发,帮助开发者迅速定位和解决问题。IAR与Keil的区别Keil也是一款非常流行的嵌入式开发工具,但在开发CC2530时,IAR相比Keil具有以下显著区别:官方适配支持 TI官方的ZigBee协议栈和示例项目主要为IAR设计,Keil并没有直接支持这些协议栈。因此,使用Keil开发CC2530需要进行额外的移植工作,而IAR则可以开箱即用。编译器优化效果 IAR的编译器在优化代码大小方面普遍优于Keil,这对于资源有限的CC2530尤为重要。在存储和性能受限的情况下,IAR可以更高效地利用芯片资源。协议栈复杂度支持 ZigBee协议栈本身较为复杂,对编译器和开发环境的要求较高。IAR对复杂嵌入式协议的支持更为成熟,而Keil的侧重点更多在通用8051开发。工具链兼容性 IAR与CC2530配套的调试工具(如CC Debugger)无缝集成,调试体验更流畅。Keil在支持TI调试硬件方面不够完善,可能需要第三方工具或插件进行适配。IAR是CC2530开发的首选环境,其强大的优化能力、完善的调试功能和与ZigBee协议的高兼容性,使得开发者能够更加高效地完成项目。而Keil尽管也支持8051平台,但在CC2530开发中的表现和适配性稍逊一筹。2.3 IAR新建工程的步骤三、代码设计代码的含义看中文注释,这里不再单独写文字介绍代码含义。3.1 main.c/**************************************************************************** * 文 件 名: main.c * 描 述: 人进入其感应范围模块输出高电平,点亮LED1,人离开感应范围LED1熄灭, * P0.6口为HC-SR501传感器的输入端 ****************************************************************************/ #include <ioCC2530.h> ​ typedef unsigned char uchar; typedef unsigned int uint; ​ #define LED1 P1_0 //定义P1.0口为LED1控制端 #define DATA_PIN P0_6 //定义P0.6口为传感器的输入端 ​ /**************************************************************************** * 名 称: DelayMS() * 功 能: 以毫秒为单位延时 16M时约为535,系统时钟不修改默认为16M * 入口参数: msec 延时参数,值越大,延时越久 * 出口参数: 无 ****************************************************************************/ void DelayMS(uint msec) { uint i,j; for (i=0; i<msec; i++) for (j=0; j<535; j++); } ​ /**************************************************************************** * 名 称: InitGpio() * 功 能: 设置LED灯和P0.4相应的IO口 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitLed(void) { P1DIR |= 0x01; //P1.0定义为输出口 P0SEL = 0x00; P0DIR &= ~0x40; //P0.6定义为输入口 P2INP |= 0x20; } ​ void main(void) { InitLed(); //设置LED灯和P0.6相应的IO口 while(1) //无限循环 { if(DATA_PIN == 1) { DelayMS(10); if(DATA_PIN == 1) { LED1 = 0; //有人时LED1亮 } } else LED1=1; //无人时LED1熄灭 } } ​四、总结通过本项目的实现,成功结合了热释电人体红外传感器与CC2530主控芯片,完成了一个简单而高效的环境监测系统。系统能够准确检测到人体是否进入传感器的探测范围,并实时通过串口将检测结果输出到PC端。该项目展示了传感器与单片机之间的协作,通过数字信号的高低电平变化实现对人体活动的灵敏感知,满足了智能家居、安防监控等应用场景的基本需求。项目中,CC2530的低功耗特性使得该系统适用于长期持续监测,确保了系统的高效性和稳定性。结合串口调试助手的使用,开发人员能够轻松验证和调试系统的工作状态,提升了开发过程中的效率和准确性。系统的设计也具有较好的可扩展性,未来可根据需求进一步添加其他传感器或功能模块,满足更复杂的应用需求。本项目为低成本、高效能的智能环境监测提供了一个完整的解决方案,既简便易用,又具备良好的拓展性和稳定性,能够在不同的场合中提供精准可靠的实时监控。
  • [技术干货] 【CC2530开发基础篇】MQ2烟雾传感器
    一、前言1.1 开发背景烟雾浓度检测是许多环境监测与安全预警系统中的重要环节,能够有效帮助识别火灾隐患、工业泄漏或其他烟雾污染情况。通过利用传感器对环境中烟雾的实时监控,可以为系统提供可靠的预警信息,提升环境安全性。CC2530是一款功能强大的低功耗无线SoC芯片,基于8051内核,广泛应用于物联网领域。其丰富的GPIO接口和外设资源,使其能够轻松接入多种传感器和模块,满足复杂应用场景的需求。在本项目中,CC2530作为主控芯片,与MQ2烟雾传感器配合,实现对环境烟雾浓度的数字化监测。MQ2是一种常见的气体与烟雾传感器,支持对多种可燃气体及烟雾的检测。传感器具有模拟输出和数字输出两种接口模式,其中数字输出通过DO引脚以高低电平形式表示是否检测到烟雾。这种简单的输出方式降低了数据处理复杂度,适合直接接入单片机进行逻辑判断。在项目中,MQ2传感器的DO引脚接入CC2530的P0.7引脚,主控芯片通过检测该引脚的高低电平状态,判断环境中是否存在烟雾。检测结果通过CC2530的串口0发送到PC端的串口调试助手,便于实时显示和分析。这种设计实现了硬件资源的高效利用,同时提供了灵活的功能扩展空间。这是当前实验使用的CC2530板子的实物图:1.2 MQ2烟雾传感器MQ2烟雾传感器是一种广泛应用于烟雾、气体泄漏检测领域的电子传感器,具有灵敏度高、响应快、易于使用等特点。它能够检测空气中的可燃气体(如甲烷、丁烷、丙烷、氢气)以及烟雾的浓度,因此常用于火灾报警器、燃气泄漏监测系统以及工业安全设备。MQ2传感器的核心组件是一种金属氧化物半导体材料。当可燃气体或烟雾接触到传感器表面时,该材料的电阻会发生显著变化。这一特性使得传感器可以通过检测电阻变化来感知气体浓度。MQ2传感器集成了模拟输出和数字输出两种接口模式,用户可以根据需要选择适合的信号类型。在数字模式下,MQ2的DO引脚输出高低电平,表示气体浓度是否达到预设的阈值。这种方式非常适合对是否存在气体进行简单的逻辑判断,便于直接与单片机GPIO接口连接。而在模拟模式下,AO引脚输出的电压值与气体浓度成正比,可以实现更加精确的浓度检测。MQ2传感器工作时需要预热,内部加热器会将传感器加热到工作温度,以确保传感材料的反应灵敏度。这意味着在通电后需要等待一定时间(通常为数分钟)才能获得稳定的检测结果。传感器的工作电压通常为5V,数字接口部分可以兼容3.3V的单片机输入,适应性较强。此外,MQ2传感器还配备了灵敏度调节功能。通过调节模块上的电位器,可以设置数字输出的阈值,从而满足不同场景对检测精度和响应速度的需求。这种灵活性使MQ2可以应用于多种环境下的烟雾和气体监测。尽管MQ2在检测多种气体和烟雾方面表现良好,但它的输出信号容易受到温度、湿度等环境因素的影响。因此,在实际使用中通常需要进行适当的校准,以确保检测结果的可靠性和稳定性。整体来看,MQ2以其高性价比和易用性,成为物联网、家庭安全以及工业安全监测系统中的重要组成部分。1.3 项目硬件模块组成(1) CC2530主控芯片 作为核心控制单元,用于读取MQ2传感器的数字信号,并通过串口发送检测结果。(2) MQ2烟雾传感器 用于检测环境中的烟雾或可燃气体浓度,输出高低电平信号来指示是否达到设定的阈值。(3) P0.7 GPIO接口 CC2530的P0.7引脚作为输入端口,连接MQ2传感器的DO引脚,用于接收传感器的数字输出信号。(4) 电源模块 提供系统所需的稳定电源,为CC2530和MQ2传感器分别提供3.3V和5V的工作电压。(5) 串口通信模块 基于CC2530的UART0接口,通过串口将检测结果发送到PC端,便于实时监测和调试。(6) 串口调试助手 运行在PC上的工具,用于接收和显示从CC2530发送的串口数据,验证检测功能是否正常。1.4 项目实现的功能功能模块具体描述实现方式烟雾检测使用MQ2传感器检测环境中的烟雾或可燃气体浓度MQ2传感器的DO引脚输出高低电平信号阈值判断根据MQ2传感器的数字输出信号判断是否检测到烟雾CC2530通过读取P0.7的电平状态判断检测结果数据传输将检测结果通过串口发送到PC端的串口调试助手显示利用CC2530的UART0模块进行串口通信实时监测系统实时采集传感器信号,快速判断环境中是否存在烟雾主循环中不断读取传感器数据灵敏度调节支持通过调整MQ2模块上的电位器改变烟雾检测的灵敏度改变MQ2内部的阈值设置低功耗运行系统整体功耗低,适合持续运行的环境监测场景利用CC2530的低功耗特性调试支持提供串口数据输出,便于开发过程中对系统进行验证和调试使用串口调试助手接收数据系统扩展性具备接入其他传感器或模块的能力,可扩展为更复杂的烟雾报警或环境监测系统依托CC2530的多功能引脚和通信资源二、CC2530基础知识科普2.1 CC2530 与 ZigBee 的含义CC2530是什么CC2530是一款由德州仪器(Texas Instruments,TI)推出的无线微控制器芯片,专为低功耗和无线通信应用设计。它基于8051内核,具有丰富的片上资源,包括128 KB的闪存、8 KB的RAM、多个UART和SPI接口、ADC模块等。此外,CC2530支持IEEE 802.15.4标准,这是ZigBee协议栈的基础。CC2530的低功耗特性和高集成度使其特别适用于智能家居、物联网(IoT)设备和工业自动化等应用场景。ZigBee是什么ZigBee是一种基于IEEE 802.15.4标准的无线通信协议,专为低功耗、低数据速率和短距离应用场景设计。它的主要特点是功耗低、组网灵活、支持大规模网络节点(如星型、网状和树形拓扑),并且具有较强的抗干扰能力。ZigBee常用于智能家居(如智能灯控、温湿度传感器)、工业物联网、医疗设备和农业监控等领域。与Wi-Fi和蓝牙相比,ZigBee适合需要低功耗、低数据速率和高网络节点容量的应用。CC2530与ZigBee的联系CC2530是支持ZigBee协议的硬件平台之一。CC2530的硬件架构和无线射频模块完全符合IEEE 802.15.4标准,而ZigBee协议栈则是运行在该标准之上的通信协议。通过在CC2530芯片上加载ZigBee协议栈(如TI提供的Z-Stack),用户可以构建完整的ZigBee无线通信系统。CC2530作为ZigBee设备的实现平台,可以配置为不同类型的ZigBee节点,包括协调器(Coordinator)、路由器(Router)和终端设备(End Device)。协调器负责整个ZigBee网络的建立和管理,路由器用于中继信号扩展网络范围,终端设备通常是低功耗的传感器或执行器。CC2530是支持ZigBee协议的硬件芯片,而ZigBee是运行在像CC2530这样的硬件平台上的通信协议。CC2530为ZigBee提供硬件支持,ZigBee则为CC2530提供实现复杂网络功能的能力。这种软硬结合使得CC2530成为ZigBee应用中的主流选择之一。2.2 CC2530的开发环境CC2530官方推荐的开发环境是 IAR Embedded Workbench(IAR EW8051)。CC2530的开发环境:IAR Embedded WorkbenchIAR Embedded Workbench(简称IAR)是开发CC2530的主要集成开发环境(IDE)。它是一款专业的嵌入式软件开发工具,提供了编辑、编译、调试和优化等功能,广泛支持各种嵌入式微控制器平台,包括基于8051内核的CC2530。IAR针对低功耗和无线设备开发进行了深度优化,特别适合CC2530这类资源有限的嵌入式芯片。IAR支持德州仪器的ZigBee协议栈(如Z-Stack),并提供了配套的调试工具和编译器,使开发者能够轻松集成ZigBee协议、编写应用代码和调试固件。此外,IAR具有良好的代码优化能力,能有效减少CC2530有限内存的占用,提高程序运行效率。为什么使用IAR开发CC2530使用IAR开发CC2530主要是由于以下原因:官方支持 德州仪器推荐使用IAR开发CC2530,因为其ZigBee协议栈(如Z-Stack)是专门为IAR优化的,许多示例代码和参考项目直接在IAR环境中运行,减少了开发者的移植工作。代码优化能力强 IAR的编译器提供了高效的代码优化功能,包括针对代码大小和运行速度的优化选项。对于资源受限的CC2530(如闪存128 KB和RAM 8 KB),IAR可以显著减小二进制文件大小,让更多复杂功能得以实现。调试工具完善 IAR集成了强大的调试工具,支持CC2530的片上调试功能(On-Chip Debugging)。通过与TI的调试硬件(如CC Debugger)配合,开发者可以实时查看和控制程序运行状态,进行断点设置、变量监控和性能分析。多功能集成 IAR提供了丰富的功能模块,如静态分析、运行时调试和内存分析工具。这些功能特别适合复杂协议栈(如ZigBee)的开发,帮助开发者迅速定位和解决问题。IAR与Keil的区别Keil也是一款非常流行的嵌入式开发工具,但在开发CC2530时,IAR相比Keil具有以下显著区别:官方适配支持 TI官方的ZigBee协议栈和示例项目主要为IAR设计,Keil并没有直接支持这些协议栈。因此,使用Keil开发CC2530需要进行额外的移植工作,而IAR则可以开箱即用。编译器优化效果 IAR的编译器在优化代码大小方面普遍优于Keil,这对于资源有限的CC2530尤为重要。在存储和性能受限的情况下,IAR可以更高效地利用芯片资源。协议栈复杂度支持 ZigBee协议栈本身较为复杂,对编译器和开发环境的要求较高。IAR对复杂嵌入式协议的支持更为成熟,而Keil的侧重点更多在通用8051开发。工具链兼容性 IAR与CC2530配套的调试工具(如CC Debugger)无缝集成,调试体验更流畅。Keil在支持TI调试硬件方面不够完善,可能需要第三方工具或插件进行适配。IAR是CC2530开发的首选环境,其强大的优化能力、完善的调试功能和与ZigBee协议的高兼容性,使得开发者能够更加高效地完成项目。而Keil尽管也支持8051平台,但在CC2530开发中的表现和适配性稍逊一筹。2.3 IAR新建工程的步骤三、代码设计代码的含义看中文注释,这里不再单独写文字介绍代码含义。3.1 main.c/**************************************************************************** * 文 件 名: main.c * 描 述: MQ-2气体传感器,当测量浓度大于设定浓度时,LED1会闪烁,MQ-2上的DD-LED * 也会长亮。如果另外一个IO接蜂鸣器就可报警了,自己DIY吧! ****************************************************************************/ #include <ioCC2530.h> ​ typedef unsigned char uchar; typedef unsigned int uint; ​ #define LED1 P1_0 //定义P1.0口为LED1控制端 #define DATA_PIN P0_5 //定义P0.5口为传感器的输入端 ​ /**************************************************************************** * 名 称: DelayMS() * 功 能: 以毫秒为单位延时 16M时约为535,系统时钟不修改默认为16M * 入口参数: msec 延时参数,值越大,延时越久 * 出口参数: 无 ****************************************************************************/ void DelayMS(uint msec) { uint i,j; for (i=0; i<msec; i++) for (j=0; j<535; j++); } ​ /**************************************************************************** * 名 称: InitGpio() * 功 能: 设置LED灯和MQ2相应的IO口 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitGpio(void) { P1DIR |= 0x01; //P1.0定义为输出口 P0DIR &= ~0x20; //P0.6定义为输入口 } ​ void main(void) { uint i=0; InitGpio(); //设置LED灯和MQ2相应的IO口 ​ while(1) //无限循环 { LED1 = 1; //熄灭P1.0口灯 if(DATA_PIN == 0) //当浓度高于设定值时 ,执行条件函数 { DelayMS(10); //延时抗干扰 if(DATA_PIN == 0) //确定 浓度高于设定值时 ,执行条件函数 { for (i=0; i<10; i++) { LED1 = ~LED1; //闪烁LED1,提示用户 DelayMS(100); } } } } } ​四、总结通过将MQ2烟雾传感器与CC2530主控芯片相结合,本项目成功实现了对环境中烟雾浓度的实时检测和数据输出。MQ2传感器的数字输出模式使得烟雾检测过程更加简单可靠,CC2530通过读取传感器的高低电平信号,准确判断是否存在烟雾,并通过串口将结果实时传输到PC端进行显示和分析。该系统的设计充分利用了CC2530的低功耗特性,使其适用于长期稳定运行的环境监测应用。通过串口调试助手,可以实时查看烟雾检测的状态,便于开发和调试。同时,MQ2传感器提供了灵敏度调节功能,使得系统可以根据具体需求进行优化,适应不同场景下的烟雾检测。项目的硬件组成与功能实现展示了物联网设备开发的基本思路,系统结构清晰,功能明确,具有较好的可扩展性。未来,系统可以通过添加更多传感器或拓展无线通信模块,进一步提升检测范围和系统的智能化水平。这为智能家居、工业安全和环境监控等领域的应用提供了有效的技术支持。
  • [技术干货] 基于STM32设计的姿态感应刹车灯
    一、项目介绍由于自行车本身没有带指示灯,比如刹车指示灯等,所以自行车的安全性并不是很好,如果人们在骑自行车时紧急刹车,后车无法及时判断前方自行车的行为,容易造成交通事故。本项目为自行车骑行者提供一种智能化的安全提示系统,采用ADXL345陀螺仪、STM32F103C8T6主控芯片及四枚LED灯,通过实时监测自行车的加速度变化,实现自动刹车灯功能。本项目实现了通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能。当自行车上安装了该设备后,ADXL345通过IIC通信协议将X,Y,Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片,并结合STM32高级定时器的PWM功能,输出不同占空比的脉冲,控制不同的LED灯输出多种亮度等级,从而控制不同的LED的开关以及明暗,并且通过不同亮度的红光和绿光混合,能够得到黄色的LED灯光。这样,在自行车急刹或者加速时,实时地控制LED灯的亮度和颜色,让后方车辆能够更清楚地了解前方自行车的行为,从而做出快速的反应,保障骑行者以及后车的安全。同时,该系统也能够提高自行车的可见性,并且对于追求低碳环保的人群来说,让自行车既能低碳环保,又能够锻炼身体。整个项目的成品构造也很简单,一个盒子,一块锂电池,一个ADXL345陀螺仪模块、一个C8T6单片机、4颗高亮度LED灯即可。二、设计思路2.1 项目目标本项目通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能,使得自行车在急刹或者加速时,实时地控制LED灯的亮度和颜色,提高其可见性,降低交通事故的风险。同时,该系统还能够使自行车既能低碳环保,又能够锻炼身体。2.2 项目硬件构成(1)自行车:作为安装系统的物体,需要有一个固定的位置来安装ADXL345陀螺仪和四枚LED灯。(2)ADXL345陀螺仪:通过IIC通信协议与STM32F103C8T6主控芯片通信,并将X、Y、Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片。(3)四枚LED灯:使用不同亮度的红光和绿光混合,能够得到黄色的LED灯光。通过控制其亮度和颜色来提高自行车的可见性。(4)STM32F103C8T6主控芯片:根据接收到的ADXL345数据,结合STN32的高级定时器的PWM功能,输出不同占空比的脉冲,控制不同的LED灯输出多种亮度等级。2.3 项目功能实现(1)自行车加速度监测:ADXL345陀螺仪通过IIC通信协议与STM32F103C8T6主控芯片通信,实时地感知自行车的加速度变化。(2)LED灯亮度和颜色控制:STM32F103C8T6主控芯片运用高级定时器的PWM功能,能够输出不同占空比的脉冲,并控制不同的LED灯输出多种亮度等级,通过不同亮度的红光和绿光混合,能够得到黄色的LED灯光,提高自行车的可见性。(3)系统安装和调试:需要将ADXL345陀螺仪和四枚LED灯与STM32F103C8T6主控芯片连接起来,并进行系统测试和调试。2.4 项目的开发价值本项目的存在价值主要体现在提升自行车骑行安全性、增强自行车可见性以及推动低碳环保理念的传播等多个方面。安全性是本项目最核心的价值之一。在自行车骑行中,由于缺乏像汽车那样的刹车灯等警示系统,骑行者在急刹车或加速时,后方车辆往往难以及时做出反应,增加了交通事故的风险。通过该系统的实现,利用ADXL345陀螺仪实时检测自行车的运动状态,并通过PWM控制LED灯的亮度和颜色变化,能够在刹车或加速时,及时向后方车辆传递明显的信号,从而提高骑行者和其他交通参与者的安全性。增强可见性是另一个重要的价值点。特别是在夜间或低能见度条件下,骑行者往往容易被忽视,增加了与其他车辆发生碰撞的风险。该系统通过控制LED灯的亮度和颜色,不仅提升了自行车的视觉存在感,还能通过红绿光的混合形成黄色警示效果,使骑行者在夜间或复杂环境中更加容易被发现,大大减少了交通事故的发生几率。在如今提倡低碳环保的社会背景下,自行车作为绿色出行方式,正得到越来越多人的青睐。通过智能化的设计和系统的集成,项目不仅提升了自行车的安全性能,也进一步增强了自行车作为环保出行工具的吸引力。这种系统化的智能升级,不仅符合现代城市交通发展趋势,也符合绿色环保的理念,助力推动低碳出行方式的普及。本项目在保障骑行者安全的同时,也促进了智能硬件与绿色出行的结合,具有重要的实用价值和社会意义。三、系统测试3.1 功能样机安装与焊接绘制好电路原理图之后,按照原理图将自动刹车灯系统的各个模块安装在事先购买好的洞洞板上,然后用导线将他们连接在一起,最后再焊接在一起,做成完整的自动刹车灯电路板。3.2 ADXL345模块调试当上电后,将自动刹车灯电路的串口2外设引脚连接至PC端,将加速度解算后的实际值发送至PC端,通过PC端串口调试助手显示出具体数值,再观察数值是否符合常理。通过显示的数据信息,可以推测出ADXL345陀螺仪能够正常工作。3.3 实物调试最后阶段,将对自行车自动刹车灯进行实物调试,确定其基本功能能够正常实现。当系统上电后,左右各一枚LED发出低亮黄色灯光,如下图。静置30S后,所有LED均熄灭,如下图。当检测到震动后,重新亮起两盏黄色LED灯,如下图。当检测到刹车时,四枚LED灯均以高亮发出红色灯光,如下图。结合自行车自动刹车灯的功能需求和实物调试结果,可以发现,调试结果完全符合自动刹车灯的预期功能。四、代码设计4.1 主函数#include "stm32f10x.h" #include "usart.h" #include "led.h" #include "RTC_Time.h" #include <stdio.h> #include "delay.h" #include "sys.h" #include "stdlib.h" #include "stdio.h" #include "string.h" #include "adxl345.h" int main(void) { u32 flag=0; short x, y, z; float accelerated; LED_GPIO_Config();//初始化LED USART2_Config(); delay_init(); //延时函数初始化 PWM_LED_INIT(); //PWM PA8-9 LED_Init(); //PB7 LED-R PBout(7) = 1; ADXL345_Init(); //PB 10,11 ADXL345_Read_Average(&x, &y, &z, 20); ADXL345_AUTO_Adjust((char *)&x, (char *)&y, (char *)&z); TIM_SetCompare1(TIM1, 50); //设置TIMx捕获比较1寄存器(通道1)值(脉冲宽度) 占空比%20 TIM_SetCompare2(TIM1, 50); //设置TIMx捕获比较2寄存器(通道2)值(脉冲宽度) 占空比%20 while (1) { ADXL345_Read_Average(&x, &y, &z, 5); //读加速度值 accelerated=(x*3.9/1000*9.8); //加速度实际值 printf("X=%4.1f Y=%4.1f Z=%4.1f\r\n",accelerated,(y*3.9/1000*9.8),(z*3.9/1000*9.8)); while(flag>425) { TIM_SetCompare1(TIM1, 0); //通道2 占空比%0 TIM_SetCompare2(TIM1, 0); //通道2 占空比%0 ADXL345_Read_Average(&x, &y, &z, 5); accelerated=(x*3.9/1000*9.8); if(accelerated<-5||accelerated>5) { break; } } flag++; if(accelerated<-4) { //四个LED低电平导通 TIM_SetCompare1(TIM1, 0); //GREEN不亮 TIM_SetCompare2(TIM1, 1000); //RED高亮 PBout(7) = 0; flag=0; } if(accelerated>0) { PBout(7) = 1; TIM_SetCompare1(TIM1, 50); //RED低亮 TIM_SetCompare2(TIM1, 50); //GREEN低亮 } if(accelerated>5) { flag=0; } } }4.2 LED灯控制#include "led.h" #include "delay.h" void LED_GPIO_Config(void) { //定义一个GPIO_InitTypeDef 类型的结构体,名字叫GPIO_InitStructure GPIO_InitTypeDef GPIO_InitStructure; //使能GPIOC的外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //选择要用的GPIO引脚 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13; ///设置引脚模式为推免输出模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚速度为50MHZ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //调用库函数,初始化GPIO GPIO_Init(GPIOC, &GPIO_InitStructure); } void TIME_INIT() { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; //根据TIM_OCInitStruct中指定的参数初始化外设TIMx RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //TIM1定时器初始化 10ms TIM_TimeBaseInitStructure.TIM_Period = 999; TIM_TimeBaseInitStructure.TIM_Prescaler = 719; TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure); //TIM1的PWM配置 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_Pulse = 0;//设置初始PWM脉冲宽度为0 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //PWM输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//当定时器计数值小于CCR_Val时为低电平 //通道的使能 TIM_OC1Init(TIM1, &TIM_OCInitStructure); //通道1 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2Init(TIM1, &TIM_OCInitStructure); //通道2 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIM1重载寄存器ARR TIM_Cmd(TIM1, ENABLE); //使能 TIM_CtrlPWMOutputs(TIM1, ENABLE); //高级定时器必须加 } void PWM_LED_INIT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //GPIOA8,9,10是TIM1的通道1,2,3 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); TIME_INIT(); } void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); } ​4.3 adxl345.c#include "adxl345.h" #include "sys.h" #include "delay.h" #include "math.h" u8 ADXL345_Init(void) { IIC_Init(); //初始化IIC总线 if(ADXL345_RD_Reg(DEVICE_ID)==0XE5) //读取器件ID { ADXL345_WR_Reg(0X31,0X2B); //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(0X2C,0x0A); //数据输出速度为100Hz ADXL345_WR_Reg(0X2D,0x28); //链接使能,测量模式 ADXL345_WR_Reg(0X2E,0x00); //不使用中断 ADXL345_WR_Reg(0X1E,0x00); ADXL345_WR_Reg(0X1F,0x00); ADXL345_WR_Reg(0X20,0x00); return 0; } return 1; } //写ADXL345寄存器 //addr:寄存器地址 //val:要写入的值 //返回值:无 void ADXL345_WR_Reg(u8 addr,u8 val) { IIC_Start(); IIC_Send_Byte(ADXL_WRITE); //发送写器件指令 IIC_Wait_Ack(); IIC_Send_Byte(addr); //发送寄存器地址 IIC_Wait_Ack(); IIC_Send_Byte(val); //发送值 IIC_Wait_Ack(); IIC_Stop(); //产生一个停止条件 } //读ADXL345寄存器 //addr:寄存器地址 //返回值:读到的值 u8 ADXL345_RD_Reg(u8 addr) { u8 temp=0; IIC_Start(); IIC_Send_Byte(ADXL_WRITE); //发送写器件指令 temp=IIC_Wait_Ack(); IIC_Send_Byte(addr); //发送寄存器地址 temp=IIC_Wait_Ack(); IIC_Start(); //重新启动 IIC_Send_Byte(ADXL_READ); //发送读器件指令 temp=IIC_Wait_Ack(); temp=IIC_Read_Byte(0); //读取一个字节,不继续再读,发送NAK IIC_Stop(); //产生一个停止条件 return temp; //返回读到的值 } //读取ADXL的平均值 //x,y,z:读取10次后取平均值 void ADXL345_RD_Avval(short *x,short *y,short *z) { short tx=0,ty=0,tz=0; u8 i; for(i=0;i<10;i++) { ADXL345_RD_XYZ(x,y,z); delay_ms(10); tx+=(short)*x; ty+=(short)*y; tz+=(short)*z; } *x=tx/10; *y=ty/10; *z=tz/10; } //自动校准 //xval,yval,zval:x,y,z轴的校准值 void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval) { short tx,ty,tz; u8 i; short offx=0,offy=0,offz=0; ADXL345_WR_Reg(POWER_CTL,0x00); //先进入休眠模式. delay_ms(100); ADXL345_WR_Reg(DATA_FORMAT,0X2B); //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(BW_RATE,0x0A); //数据输出速度为100Hz ADXL345_WR_Reg(POWER_CTL,0x28); //链接使能,测量模式 ADXL345_WR_Reg(INT_ENABLE,0x00); //不使用中断 ADXL345_WR_Reg(OFSX,0x00); ADXL345_WR_Reg(OFSY,0x00); ADXL345_WR_Reg(OFSZ,0x00); delay_ms(12); for(i=0;i<10;i++) { ADXL345_RD_Avval(&tx,&ty,&tz); offx+=tx; offy+=ty; offz+=tz; } offx/=10; offy/=10; offz/=10; *xval=-offx/4; *yval=-offy/4; *zval=-(offz-256)/4; ADXL345_WR_Reg(OFSX,*xval); ADXL345_WR_Reg(OFSY,*yval); ADXL345_WR_Reg(OFSZ,*zval); } //读取3个轴的数据 //x,y,z:读取到的数据 void ADXL345_RD_XYZ(short *x,short *y,short *z) { u8 buf[6]; u8 i; IIC_Start(); IIC_Send_Byte(0X3A); //发送写器件指令 IIC_Wait_Ack(); IIC_Send_Byte(0x32); //发送寄存器地址(数据缓存的起始地址为0X32) IIC_Wait_Ack(); IIC_Start(); //重新启动 IIC_Send_Byte(0X3B); //发送读器件指令 IIC_Wait_Ack(); for(i=0;i<6;i++) { if(i==5)buf[i]=IIC_Read_Byte(0);//读取一个字节,不继续再读,发送NACK else buf[i]=IIC_Read_Byte(1); //读取一个字节,继续读,发送ACK delay_us(15); IIC_Start(); //重新启动 IIC_Send_Byte(0X3A); //发送写器件指令 IIC_Wait_Ack(); IIC_Send_Byte(0x33+i); //发送寄存器地址(数据缓存的起始地址为0X32) IIC_Wait_Ack(); IIC_Start(); //重新启动 IIC_Send_Byte(0X3B); //发送读器件指令 IIC_Wait_Ack(); } IIC_Stop(); //产生一个停止条件 *x=(short)(((u16)buf[1]<<8)+buf[0]); *y=(short)(((u16)buf[3]<<8)+buf[2]); *z=(short)(((u16)buf[5]<<8)+buf[4]); } //读取ADXL345的数据times次,再取平均 //x,y,z:读到的数据 //times:读取多少次 void ADXL345_Read_Average(short *x,short *y,short *z,u8 times) { u8 i; short tx,ty,tz; *x=0; *y=0; *z=0; if(times)//读取次数不为0 { for(i=0;i<times;i++)//连续读取times次 { ADXL345_RD_XYZ(&tx,&ty,&tz); *x+=tx; *y+=ty; *z+=tz; delay_ms(5); } *x/=times; *y/=times; *z/=times; } } //得到角度 //x,y,z:x,y,z方向的重力加速度分量(不需要单位,直接数值即可) //dir:要获得的角度.0,与Z轴的角度;1,与X轴的角度;2,与Y轴的角度. //返回值:角度值.单位0.1°. short ADXL345_Get_Angle(float x,float y,float z,u8 dir) { float temp; float res=0; switch(dir) { case 0://与自然Z轴的角度 temp=sqrt((x*x+y*y))/z; res=atan(temp); break; case 1://与自然X轴的角度 temp=x/sqrt((y*y+z*z)); res=atan(temp); break; case 2://与自然Y轴的角度 temp=y/sqrt((x*x+z*z)); res=atan(temp); break; } return res*1800/3.14; }
  • [技术干货] 基于STM32设计的大气气压检测装置
    1.1 项目开发背景随着科技的发展与人们生活水平的提高,对于环境监测的需求日益增长。特别是在户外探险、气象研究以及航空航海等领域,实时准确地获取大气气压数据显得尤为重要。大气气压的变化不仅直接影响到天气预报的准确性,而且对于了解气候变化趋势、保障飞行安全等方面也具有不可忽视的作用。因此,设计一款便携式、高精度的大气气压检测装置变得十分必要。这样的装置能够让用户无论身处何地都能快速掌握周围环境的大气状况,为科学研究和个人活动提供有力支持。本项目计划基于STM32微控制器平台来实现一个紧凑且高效的大气气压检测系统。选择STM32作为主控芯片的原因在于其拥有强大的处理能力、丰富的外设接口以及良好的低功耗特性,非常适合用来构建这类需要长时间运行同时又要求较高计算性能的应用。特别是选用型号为STM32F103RCT6的微控制器,它不仅具备足够的Flash存储空间和RAM来支持复杂的软件算法,还内置了多种通信接口,便于连接外部传感器和其他设备。在硬件设计上,将采用BMP180数字气压传感器来实现对大气压力的精确测量。BMP180以其小巧的体积、较低的成本以及较高的测量精度而闻名,能够满足本项目对于小型化和高性能的要求。此外,为了使用户可以直接查看测量结果而不必依赖额外的显示设备,还将集成一块0.96英寸大小、使用SPI协议进行通信的OLED显示屏。该屏幕具有清晰的显示效果,并且功耗极低,非常适合于便携式电子产品中使用。考虑到目标应用场景可能位于远离电源的地方,因此整个装置将由锂电池供电,确保即使是在野外也能正常工作。通过精心设计电路结构并优化软件逻辑以降低能耗,可以延长单次充电后的使用时间,使得这款大气气压检测装置更加实用可靠。综上所述,本项目的实施结合先进的嵌入式技术与环境监测需求,开发出一款易于携带、操作简便且功能强大的气压检测工具,从而更好地服务于科研人员及广大爱好者。1.2 设计实现的功能基于STM32设计的大气气压检测装置 ​ 功能支持: 1. 实时检测大气气压(BMP180) 2. 本地OLED显示屏显示(0.96寸SPI协议OLED显示屏) 3. 锂电池供电 4. 主控芯片选择STM32F103RCT6本项目设计的大气气压检测装置提供一种便捷且可靠的解决方案,以满足用户对于实时大气气压信息的需求。装置的核心功能是通过BMP180数字气压传感器实现对当前环境大气压力的持续监测。BMP180是一款高精度的气压传感器,它能够以非常高的分辨率测量绝对气压,并且具有温度补偿功能,这保证了无论外界条件如何变化,装置都能提供稳定而准确的压力读数。传感器通过I2C接口与STM32F103RCT6微控制器相连,允许控制器周期性地读取最新的气压值。为了使用户能够直观地看到这些数据,装置集成了一个0.96英寸的OLED显示屏。这块屏幕采用了SPI通信协议,与STM32微控制器直接交互,显示从BMP180获得的气压数值。不仅如此,显示屏还可以展示其他有用的信息,比如电池电量状态或简单的操作提示,增强用户体验。OLED技术的选择不仅因为它的高对比度和良好的可视角度,更重要的是其相对较低的工作电流有助于延长电池寿命。考虑到便携性的需求,整个装置采用了锂电池供电的设计。这意味着用户可以在没有固定电源的情况下自由移动,例如在户外活动或远足时使用该装置。为了进一步优化能源管理,系统中加入了智能休眠模式,在非活动期间自动减少能耗,当检测到用户操作或达到预设的时间间隔时再唤醒进行数据更新。此外,STM32F103RCT6微控制器本身支持多种低功耗模式,可根据实际需要灵活调整工作状态,从而有效延长电池续航时间。通过整合精准的气压传感技术、直观的数据显示界面以及高效的能源管理系统,这款基于STM32的大气气压检测装置不仅提供了必要的功能性,同时也考虑到了使用的便利性和经济性,适合广泛的应用场景。无论是专业研究人员还是业余爱好者,都能够从中获益,利用这一工具更加深入地理解和探索周围的大气环境。1.3 项目硬件模块组成本项目的硬件设计围绕着几个关键组件展开,首先是主控芯片STM32F103RCT6,这是一块高性能的32位ARM Cortex-M3内核微控制器,具有丰富的外设接口,包括多个USART、SPI、I2C等通信端口,非常适合用于处理传感器数据和控制显示设备。它负责协调整个系统的运作,执行数据采集、处理以及与用户交互等功能。接下来是BMP180数字气压传感器,作为核心传感元件,BMP180通过I2C接口与STM32微控制器连接。这款传感器能够测量范围从300hPa到1100hPa的气压值,适用于各种海拔高度下的气压监测。它还集成了温度传感器,可以提供经过温度补偿的气压读数,确保测量结果的准确性。BMP180的小尺寸和低功耗特点使其成为便携式应用的理想选择。为了向用户提供直观的数据反馈,装置配备了一块0.96英寸的OLED显示屏。这块屏幕采用SPI通信方式与STM32F103RCT6连接,支持全彩显示,能够清晰呈现气压数值及其他相关信息。OLED技术的特点是自发光,不需要背光灯,因此在不同光照条件下都具有出色的可视性。同时,它的工作电压较低,有利于保持整体设备的低功耗特性。电源部分选用了可充电锂电池作为能量来源,保证了装置的移动性和长时间工作的可能性。锂电池的选择考虑到了容量、重量和安全性等因素,确保既足够支持装置连续运行较长时间,又不会给用户带来过重负担。此外,为了更好地管理电池电量,电路中还加入了电池保护电路,防止过充、过放以及短路等情况发生,增强了设备的安全性和可靠性。除此之外,还包括一些辅助性的元器件,如稳压器、电容、电阻等,它们共同构成了稳定的电源供应和信号调理电路,确保各个模块能够协同工作,发挥最佳性能。这些基本电气组件虽然看似不起眼,但在整个系统中起着至关重要的作用,帮助维持稳定的运行环境,保证气压检测装置的长久可靠使用。1.4 设计思路本项目的设计思路源于对便携式环境监测设备市场需求的深刻理解,尤其是针对大气气压这一重要参数的实时监测。在设计初期,团队首先明确了目标用户群体,包括户外运动爱好者、气象学研究者以及任何需要了解当前气压状况的人士。基于此,确定了几个核心设计理念:高精度测量、直观的数据展示、长续航能力以及整体设备的小型化。为了实现高精度的大气气压测量,选择了BMP180作为主要传感器。这款传感器因其优异的性能和广泛的应用记录而被选中。BMP180不仅能提供高分辨率的气压数据,还能进行温度补偿,确保测量结果不受环境温度变化的影响。通过I2C接口将其与STM32F103RCT6微控制器相连接,简化了硬件布局的同时也提高了系统的集成度。考虑到用户体验的重要性,决定采用0.96英寸的OLED显示屏来即时显示测量数据。OLED屏不仅拥有高对比度和宽视角,还具备轻薄节能的特点,非常适合作为便携设备的一部分。通过SPI接口与STM32通信,可以方便地编程控制显示内容,让用户一目了然地看到气压数值及其它相关信息。为解决移动使用时的供电问题,选择了锂电池供电方案。这不仅是因为锂电池的能量密度高,能够提供足够的电力支持长时间的连续运行,也是因为现代锂电池技术成熟,具备良好的循环寿命和安全性。设计中特别关注了电源管理策略,通过软件控制微控制器进入低功耗模式来节省电量,并在硬件层面加入电池保护机制,以确保电池使用的安全和效率。在硬件设计上追求简约而不失功能性的原则,尽可能减少不必要的复杂性,确保最终产品易于制造且成本可控。与此同时,注重模块间的良好兼容性与扩展性,预留了额外的接口供未来可能的功能升级或与其他传感器的集成。通过上述各方面的综合考量与精心规划,开发出一款既满足专业级需求又能广泛应用于日常生活的便携式大气气压检测装置。这种设计不仅体现了技术创新,也充分考虑了用户的实际使用情境,力求在实用性与用户体验之间找到最佳平衡点。1.5 系统功能总结功能模块描述主控单元STM32F103RCT6微控制器,负责数据处理、控制其他硬件模块及系统运行。气压检测BMP180数字气压传感器,通过I2C接口与主控单元连接,提供高精度的大气气压测量。显示单元0.96英寸OLED显示屏,采用SPI通信协议,显示实时气压值以及其他相关信息如电池状态等。电源管理可充电锂电池供电,配合电池保护电路,确保安全可靠;支持低功耗模式以延长电池使用寿命。用户交互通过OLED显示屏提供直观的操作反馈;支持简单按键或触控(如果适用)来触发特定功能或设置。数据处理内置算法用于处理传感器数据,包括滤波、校准等,确保输出数据的准确性和稳定性。环境适应性结构设计紧凑耐用,适合户外使用;具备一定的防水防尘等级(具体IP等级根据设计定)。扩展接口预留通用IO口或其他通信接口,便于未来增加更多功能或与其他设备联动。1.6 完整代码设计下面是main.c的完整逻辑代码。#include "stm32f1xx_hal.h" #include "bmp180.h" // BMP180传感器驱动已准备好 #include "oled.h" // OLED显示驱动已准备好 #include "power_mgmt.h" // 电源管理模块已准备好 #include <string.h> ​ // 初始化HAL库 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_SPI1_Init(void); ​ int main(void) { // 初始化HAL库 HAL_Init(); ​ // 配置系统时钟 SystemClock_Config(); ​ // 初始化GPIO MX_GPIO_Init(); // 初始化I2C1 (用于BMP180) MX_I2C1_Init(); // 初始化SPI1 (用于OLED) MX_SPI1_Init(); ​ // 初始化BMP180传感器 if (BMP180_Init() != BMP180_OK) { // 初始化失败处理 while (1); } ​ // 初始化OLED显示屏 OLED_Init(); ​ // 初始化电源管理 PowerMgmt_Init(); ​ // 主循环 while (1) { // 读取气压数据 float pressure = 0.0; if (BMP180_ReadPressure(&pressure) == BMP180_OK) { // 显示气压数据 char buffer[20]; snprintf(buffer, sizeof(buffer), "%.2f hPa", pressure); OLED_DisplayText(0, 5, (uint8_t *)buffer); } ​ // 更新显示 OLED_UpdateDisplay(); ​ // 进入低功耗模式 PowerMgmt_EnterLowPowerMode(); } }
  • [技术干货] STM32单片机+MPU6050设计一个电子水平仪
    一、前言1.1 项目开发背景在现代电子技术的快速发展中,各种智能设备的精确度和便捷性不断提升,电子水平仪作为一种常见的测量工具,广泛应用于建筑、家居安装、机械制造等领域。传统的水平仪通常依赖机械原理,如气泡管或机械刻度盘,虽然简单直观,但在一些精度要求较高的场合,传统工具往往难以满足需求。因此,电子水平仪应运而生,凭借其数字化显示和高精度测量,逐渐取代了传统水平仪,成为更加智能化的测量工具。本项目基于STM32F103C8T6单片机设计一款电子水平仪。STM32F103C8T6作为一种性能强大的微控制器,具有较高的计算能力和丰富的外设接口,能够满足项目对实时数据处理和显示控制的需求。该单片机将与MPU6050传感器相结合,利用其内置的加速度计和陀螺仪,实现设备的倾斜角度测量。MPU6050传感器能够高精度地检测设备在三个轴向上的加速度信息,从而计算出设备在左右方向(X轴)和前后方向(Y轴)的倾斜角度。为了更直观地展示测量结果,本项目选用了一款高分辨率的OLED显示屏。该显示屏可以清晰地呈现实时的角度数据,并且提供了足够的分辨率来实现可视化的图形展示。通过中心点圆圈和滚动小球的设计,用户可以轻松识别设备当前的水平状态。这种可视化的反馈方式不仅更加直观,而且提升了用户体验,特别适用于需要频繁调整水平状态的场景。随着智能化技术的普及,越来越多的传统工具开始向数字化、智能化方向发展。电子水平仪作为数字工具的一种,其精度、稳定性和用户友好性成为了设计的核心目标。项目通过结合MPU6050传感器的高精度检测与STM32F103C8T6单片机的强大处理能力,提供了一种新型的、可视化的电子水平仪设计方案。这种方案不仅满足了基础的角度测量功能,还通过创新的显示方式,使得用户能够更加高效和精准地进行水平调整和测量。核心的部件:1.2 设计实现的功能基于STM32设计一款电子水平仪 ​ 功能要求: 1. 本地一个SPI协议接口的OLED显示屏,展示当前 设备左右方向的倾斜角度,设备前后方向的倾斜角度。 2. 能够通过一个中心点圆圈+一个滚动的小球展示可视化展示当前的水平状态。 3. 支持按键校准,校准水平仪的参数 硬件要求: 1. 单片机采用STM32F103C8T6 2. 水平状态监测采用MPU6050 3. 显示屏采用高分辨率的OLED显示屏 4. 供电采用可充电锂电池供电,方便便携式携带 5. 一个按钮,进行复位参数校准。(1) 倾斜角度测量通过 MPU6050 传感器,实时测量设备在 X 轴(左右方向)和 Y 轴(前后方向)的倾斜角度。系统能够精准地计算设备相对于水平的角度,并将其显示在 OLED 屏幕上,提供清晰的数值反馈,帮助用户了解设备当前的水平状态。(2) 实时水平状态可视化显示在 OLED 显示屏上,采用图形化方式展示设备的水平状态。通过中心圆圈和滚动的小球,用户可以直观地看到设备的水平偏差。小球会根据设备的倾斜方向和角度实时滚动,偏离水平时会向对应方向移动,水平时则停留在圆圈中心,增强用户体验。(3) 数据滤波与角度计算在数据处理方面,设计了合适的滤波算法,如卡尔曼滤波或简单平均滤波,用于去除传感器数据中的噪声和提高计算的准确性。通过这些算法,系统能够更加稳定和精准地输出设备的倾斜角度。(4) 校准功能系统提供校准功能,用户可以通过按下按钮来重置设备的零点,校准设备的水平状态。当按下按钮时,设备的当前角度被重置为零,确保在每次使用时都能从准确的水平状态开始。此功能特别适用于设备多次使用后的精度校正,保证每次测量的精度和可靠性。(5) OLED 显示角度数值在 OLED 屏幕上,实时显示设备的具体倾斜角度,分别显示 X 轴(左右方向)和 Y 轴(前后方向)的倾斜角度数值。通过直观的数字显示,用户可以准确了解当前设备的水平状态,并在需要时进行调整。(6) 便携性与充电功能该电子水平仪设计为便携式设备,配备了可充电锂电池,用户可以在不依赖外部电源的情况下,长时间使用设备。通过电池管理模块,支持 USB 充电接口,方便充电并延长使用时间。电池的可充电特性使得设备在户外、工地等环境下更加便捷。(7) 低功耗设计为了提高设备的使用时长,设计中采用了低功耗模式。STM32F103C8T6 单片机与 MPU6050 传感器均支持低功耗操作,系统在不进行操作时可以进入低功耗待机状态,减少能耗,延长电池使用时间。(8) 用户友好界面通过简洁直观的 OLED 显示屏界面,用户可以轻松获取设备的实时倾斜角度和水平状态。显示内容清晰、易于阅读,设计了视觉化的反馈方式,使得设备使用者能够快速理解设备的水平偏差并进行相应调整。1.3 项目硬件模块组成(1) STM32F103C8T6 单片机STM32F103C8T6 是本项目的核心控制单元,负责数据处理、控制显示屏和执行用户输入的操作。该单片机具备多种外设接口,如 I2C 和 GPIO,能够与 MPU6050 传感器和 OLED 显示屏进行通信。此外,它具有较强的运算能力,能够进行角度计算、校准功能以及实时显示更新。(2) MPU6050 传感器MPU6050 是集成了 3 轴加速度计和 3 轴陀螺仪的传感器,用于检测设备在 X 轴(左右方向)和 Y 轴(前后方向)的加速度,进而计算出设备的倾斜角度。通过 I2C 协议将数据传输给 STM32F103C8T6 单片机,用于后续角度计算和显示。(3) OLED 显示屏OLED 显示屏用于显示设备的倾斜角度和水平状态。高分辨率的 OLED 显示屏能清晰地呈现数值角度和可视化图形(如中心圆圈和滚动小球)。通过 I2C 连接 STM32F103C8T6 单片机,实时显示 X、Y 轴的倾斜角度以及水平状态的图形反馈。(4) 可充电锂电池可充电锂电池提供电子水平仪系统所需的电力,支持便携式使用。它通常提供 3.7V 的电压,满足 STM32F103C8T6、MPU6050 传感器和 OLED 显示屏的工作需求。电池可以通过充电电路进行充电,以便用户在外出时使用。(5) 电池充电管理模块为了方便充电,配备电池充电管理模块(TP4056)用于给可充电锂电池充电。该模块能够通过 Micro-USB 或其他充电接口连接电源,并在充电时提供电池保护,防止过充或过放。(6) 按键模块一个按键用于用户与电子水平仪的交互,具体功能包括校准或复位。按键可以触发 STM32F103C8T6 的GPIO引脚,在长按时启动水平仪的参数校准功能,重新设置设备的零点,确保在不同使用环境下仍能获得准确的测量结果。1.4 设计思路本项目的设计思路主要是通过结合硬件和软件的紧密配合,开发一款精准且便于携带的电子水平仪。该电子水平仪通过 STM32F103C8T6 单片机作为核心处理单元,利用 MPU6050 传感器获取设备的加速度数据,实时计算设备的倾斜角度,并通过高分辨率的 OLED 显示屏直观地呈现出来。设计的关键在于如何准确捕捉设备的水平状态并通过用户友好的方式展示出来,同时确保系统的便携性和易操作性。系统的核心是 STM32F103C8T6 单片机,作为高性能的微控制器,它具有多种外设接口和足够的运算能力,能够进行实时数据处理。通过 I2C 协议,单片机与 MPU6050 传感器进行通信,获取加速度计和陀螺仪数据。这些数据将用于计算设备的倾斜角度,并进一步进行校准和调整,确保在任何情况下都能提供精准的水平测量。在传感器数据处理方面,设计的关键是如何精确地计算设备的角度。MPU6050 传感器提供了 X、Y 和 Z 轴的加速度数据,我们将使用这些数据计算设备相对于水平面(X轴和Y轴的倾斜角度)的变化。为了减少噪声和提高测量精度,设计时引入了数据滤波算法,以保证角度计算的稳定性和准确性。OLED 显示屏作为用户与设备交互的界面,提供了丰富的显示功能。设计中通过实时显示当前设备的左右方向(X轴)和前后方向(Y轴)的倾斜角度,用户可以清晰地了解设备的水平状态。此外,为了增加可视化的体验,我们设计了一个中心点圆圈,并通过小球的滚动来展示设备的倾斜程度。当设备完全水平时,小球将停留在中心圆圈内,偏离水平时,小球会向对应的方向移动。这样直观的显示方式让用户能在瞬间理解设备的水平情况。为了确保设备能够适应不同的环境和使用场景,本设计还加入了校准功能。通过设置一个按键,用户可以在需要时对设备进行参数复位和重新校准。当按下按钮时,STM32 单片机会清除当前的角度偏差,并重置为零点,确保在多次使用过程中系统依然保持高精度。便携性是本项目的另一个重要设计方向。采用可充电锂电池为电源,配备电池管理模块,以支持系统在无外部电源的情况下长时间工作。电池的充电功能使得用户可以在野外或移动环境中随时使用,并且通过 USB 充电接口方便充电,解决了传统水平仪无法持续工作的问题。通过这些硬件和软件的结合,整个电子水平仪系统实现了精确、直观和便捷的功能。系统设计不仅具备高精度的水平测量功能,还通过简洁的用户界面和便携设计使得用户能够在各种环境下使用,提供了一个全新的测量工具,取代了传统的机械水平仪。1.5 系统功能总结功能编号功能描述实现方式(1)倾斜角度测量通过 MPU6050 传感器测量 X 轴和 Y 轴的倾斜角度,并进行计算显示。(2)实时水平状态可视化显示在 OLED 屏幕上展示中心点圆圈及滚动小球,直观展示设备的水平状态。(3)数据滤波与角度计算使用卡尔曼滤波或简单平均滤波去除噪声,计算设备的精确倾斜角度。(4)校准功能通过按键触发校准,重置设备角度为零,确保每次使用时从准确零点开始。(5)OLED 显示角度数值在 OLED 屏幕上实时显示设备的 X 轴和 Y 轴倾斜角度的数值。(6)便携性与充电功能配备可充电锂电池,支持 USB 充电,适合便携式使用,解决外部电源依赖问题。(7)低功耗设计系统支持低功耗模式,确保设备在待机时减少能耗,延长使用时间。(8)用户友好界面OLED 显示屏提供清晰直观的角度数值和图形化的反馈,简化操作和交互。1.6 开发工具的选择开发工具选择Keil,keil是一家世界领先的嵌入式微控制器软件开发商,在2015年,keil被ARM公司收购。因为当前芯片选择的是STM32F103系列,STMF103是属于ARM公司的芯片构架、Cortex-M3内核系列的芯片,所以使用Kile来开发STM32是有先天优势的,而keil在各大高校使用的也非常多,很多教科书里都是以keil来教学,开发51单片机、STM32单片机等等。1.7 MPU6050模块介绍MPU6050 是一款由 Invensense 公司生产的六轴传感器模块,它结合了三轴加速度计和三轴陀螺仪,广泛应用于运动追踪、姿态检测、电子稳定、虚拟现实等领域。MPU6050 采用 MEMS(微机电系统)技术,能够提供高精度的角度和加速度数据,适用于需要实时动态感知的应用。该传感器模块内置了一个三轴加速度计和一个三轴陀螺仪。三轴加速度计能够测量物体在 X、Y 和 Z 轴上的加速度变化,单位为“g”(地球重力加速度),可以感知物体的静态或动态加速度变化。三轴陀螺仪则用于测量物体在三个轴上的角速度,单位通常为“度/秒”(°/s),可提供物体旋转的速率信息。通过这些数据,MPU6050 可以检测物体的运动、旋转以及倾斜角度,并为其他系统提供准确的传感信息。MPU6050 的最大特点之一是它内置了一个数字运动处理单元(DMP,Digital Motion Processor),它能够对加速度计和陀螺仪的数据进行实时处理,从而减轻主处理器的计算负担。DMP 还可以进行传感器数据的滤波、姿态估算和融合处理,这使得 MPU6050 在传感器输出的稳定性和准确性上具有显著优势。此外,DMP 支持直接输出已经处理和融合的运动数据,减少了主控单元的数据处理量,从而提升了整体系统的性能。MPU6050 模块支持 I2C 通信协议,具有两线串行总线接口,便于与主控单元(如 STM32F103C8T6、Arduino 等)进行数据传输。其通信速率最高可达 400 kHz,因此可以在需要高频率数据采集的应用中提供实时数据反馈。通过该接口,开发者能够读取加速度计和陀螺仪的数据,还能够配置模块的工作模式、灵敏度等参数,以满足特定应用需求。在实际应用中,MPU6050 具有较高的灵敏度和较低的功耗,适合用于移动设备、机器人、无人机、车载系统等对体积、功耗有要求的场景。其内置的低通滤波器和数字处理单元,使得它能够有效地抑制噪声,提高测量数据的稳定性,尤其在动态环境下,能够准确地感知物体的运动状态和姿态变化。此外,MPU6050 还具有一些自检功能,可以通过内部自检机制判断传感器是否正常工作。模块中还有内置温度传感器,用于补偿温度对加速度计和陀螺仪的影响,确保测量精度不会受到环境温度变化的影响。MPU6050 以其小巧的体积、高精度的传感能力、内置数字运动处理单元(DMP)以及低功耗特点,成为许多运动监测和姿态检测系统中不可或缺的核心传感器。它不仅能够提供高质量的数据,还能减少对主控制单元的计算压力,使得整体系统更加高效、稳定。二、代码设计2.1 工作原理在电子水平仪中,MPU6050 传感器的主要作用是通过测量加速度和角速度来计算设备的倾斜角度。它集成了三轴加速度计和三轴陀螺仪,这两者协同工作,实现对设备在各个方向上的姿态和运动的监测。MPU6050 在水平仪中的工作原理如下:MPU6050 内部的三轴加速度计可以测量设备在三个方向(X、Y、Z轴)上的加速度。加速度计的基本工作原理是根据物体受到的力(如重力)产生的加速度来推算设备的运动状态。在一个理想的水平状态下,重力仅作用于Z轴(即垂直方向)。因此,设备的倾斜会导致加速度的分布发生变化,从而改变X轴和Y轴的加速度值。当设备倾斜时,重力的作用方向将不再完全指向 Z 轴,而是分布到 X 和 Y 轴上,产生一定的加速度。这些加速度值可以用来计算设备的倾斜角度。通过对 X 和 Y 轴加速度值的计算,可以推算出设备的俯仰角度(pitch)和滚转角度(roll)。例如,通过以下公式,可以计算出设备的俯仰角(pitch)和滚转角(roll):俯仰角(Pitch):$$\[ \text{pitch} = \arctan\left(\frac{accelX}{\sqrt{accelY^2 + accelZ^2}}\right) \]$$滚转角(Roll):$$\[ \text{roll} = \arctan\left(\frac{-accelY}{\sqrt{accelX^2 + accelZ^2}}\right) \]$$通过这些计算,可以获取设备的实时倾斜角度。陀螺仪工作原理MPU6050 内部的三轴陀螺仪可以测量设备的旋转速率,也就是角速度。陀螺仪通过检测设备在各个轴上的旋转速率(单位:度/秒或 rad/s)来捕捉设备的动态变化。与加速度计不同,陀螺仪主要检测旋转的角速度,能反映设备在实时运动中的变化。在水平仪中,陀螺仪的工作原理通常用于跟踪设备的快速变化。例如,当设备发生快速旋转或倾斜时,陀螺仪的角速度数据可以帮助补充加速度计测量的数据,增强系统对动态变化的响应能力。特别是在静态情况下,加速度计能够提供较为稳定的角度测量,而在快速运动或旋转时,陀螺仪可以提供更快的反应数据。数据融合与姿态计算虽然加速度计和陀螺仪都能提供关于设备倾斜的不同信息,但它们各自存在局限性。加速度计受到重力和运动加速度的影响,可能会产生一定的噪声;而陀螺仪在长时间使用中可能会受到漂移的影响。因此,在水平仪中,通常会采用传感器融合算法,如互补滤波或卡尔曼滤波,来结合加速度计和陀螺仪的数据,从而提高系统的精度和稳定性。互补滤波: 这种方法结合了加速度计和陀螺仪的优势,通过加速度计提供的稳定低频信息和陀螺仪提供的高频旋转信息,实现一个平衡的结果。卡尔曼滤波:卡尔曼滤波是一种更复杂的算法,它能够基于信号的不确定性,计算出加速度计和陀螺仪数据的最优融合,提供更为精确和稳定的角度计算。在水平仪中,结合加速度计和陀螺仪的数据后,可以获得非常精确的设备俯仰和滚转角度,从而在 OLED 屏幕上显示出设备的水平状态,直观地向用户反馈设备是否处于水平状态。工作流程总结加速度计:用于检测设备在 X、Y 和 Z 轴上的加速度,并通过计算设备的俯仰角和滚转角来推算其在水平面上的倾斜角度。陀螺仪:用于检测设备在各个轴上的旋转速率,帮助系统在快速运动和变化时实时更新角度信息。数据融合:结合加速度计和陀螺仪的输出数据,通过传感器融合算法(如互补滤波或卡尔曼滤波),获取更为准确的设备角度数据。角度计算:根据加速度计和陀螺仪数据计算出设备的俯仰角和滚转角,从而实时监控和显示设备的倾斜状态,向用户反馈设备是否处于水平状态。2.2 MPU6050的驱动代码#include "mpu6050.h" #include "sys.h" #include "delay.h" #include <stdio.h> ​ /*--------------------------------------------------------------------IIC协议底层模拟时序--------------------------------------------------------------------------------*/ ​ /* 函数功能:MPU IIC 延时函数 */ void MPU6050_IIC_Delay(void) { DelayUs(2); } ​ /* 函数功能: 初始化IIC */ void MPU6050_IIC_Init(void) { RCC->APB2ENR|=1<<3; //先使能外设IO PORTB时钟 GPIOB->CRL&=0X00FFFFFF; //PB6/7 推挽输出 GPIOB->CRL|=0X33000000; GPIOB->ODR|=3<<6; //PB6,7 输出高 } ​ /* 函数功能: 产生IIC起始信号 */ void MPU6050_IIC_Start(void) { MPU6050_SDA_OUT(); //sda线输出 MPU6050_IIC_SDA=1; MPU6050_IIC_SCL=1; MPU6050_IIC_Delay(); MPU6050_IIC_SDA=0;//START:when CLK is high,DATA change form high to low MPU6050_IIC_Delay(); MPU6050_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } ​ /* 函数功能: 产生IIC停止信号 */ void MPU6050_IIC_Stop(void) { MPU6050_SDA_OUT();//sda线输出 MPU6050_IIC_SCL=0; MPU6050_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high MPU6050_IIC_Delay(); MPU6050_IIC_SCL=1; MPU6050_IIC_SDA=1;//发送I2C总线结束信号 MPU6050_IIC_Delay(); } ​ /* 函数功能: 等待应答信号到来 返 回 值:1,接收应答失败 0,接收应答成功 */ u8 MPU6050_IIC_Wait_Ack(void) { u8 ucErrTime=0; MPU6050_SDA_IN(); //SDA设置为输入 MPU6050_IIC_SDA=1;MPU6050_IIC_Delay(); MPU6050_IIC_SCL=1;MPU6050_IIC_Delay(); while(MPU6050_READ_SDA) { ucErrTime++; if(ucErrTime>250) { MPU6050_IIC_Stop(); return 1; } } MPU6050_IIC_SCL=0;//时钟输出0 return 0; } ​ /* 函数功能:产生ACK应答 */ void MPU6050_IIC_Ack(void) { MPU6050_IIC_SCL=0; MPU6050_SDA_OUT(); MPU6050_IIC_SDA=0; MPU6050_IIC_Delay(); MPU6050_IIC_SCL=1; MPU6050_IIC_Delay(); MPU6050_IIC_SCL=0; } ​ /* 函数功能:不产生ACK应答 */ void MPU6050_IIC_NAck(void) { MPU6050_IIC_SCL=0; MPU6050_SDA_OUT(); MPU6050_IIC_SDA=1; MPU6050_IIC_Delay(); MPU6050_IIC_SCL=1; MPU6050_IIC_Delay(); MPU6050_IIC_SCL=0; } ​ /* 函数功能:IIC发送一个字节 返回从机有无应答 1,有应答 0,无应答 */ void MPU6050_IIC_Send_Byte(u8 txd) { u8 t; MPU6050_SDA_OUT(); MPU6050_IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { MPU6050_IIC_SDA=(txd&0x80)>>7; txd<<=1; MPU6050_IIC_SCL=1; MPU6050_IIC_Delay(); MPU6050_IIC_SCL=0; MPU6050_IIC_Delay(); } } ​ /* 函数功能:读1个字节,ack=1时,发送ACK,ack=0,发送nACK */ u8 MPU6050_IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; MPU6050_SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { MPU6050_IIC_SCL=0; MPU6050_IIC_Delay(); MPU6050_IIC_SCL=1; receive<<=1; if(MPU6050_READ_SDA)receive++; MPU6050_IIC_Delay(); } if(!ack) MPU6050_IIC_NAck();//发送nACK else MPU6050_IIC_Ack(); //发送ACK return receive; } ​ ​ /*--------------------------------------------------------------------MPU6050底层驱动代码--------------------------------------------------------------------------------*/ ​ /* 函数功能:初始化MPU6050 返 回 值:0,成功 其他,错误代码 */ u8 MPU6050_Init(void) { u8 res; MPU6050_IIC_Init();//初始化IIC总线 MPU6050_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050 DelayMs(100); MPU6050_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050 MPU6050_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps MPU6050_Set_Accel_Fsr(0); //加速度传感器,±2g MPU6050_Set_Rate(50); //设置采样率50Hz MPU6050_Write_Byte(MPU_INT_EN_REG,0X00); //关闭所有中断 MPU6050_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式关闭 MPU6050_Write_Byte(MPU_FIFO_EN_REG,0X00); //关闭FIFO MPU6050_Write_Byte(MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效 res=MPU6050_Read_Byte(MPU_DEVICE_ID_REG); if(res==MPU6050_ADDR)//器件ID正确 { MPU6050_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考 MPU6050_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作 MPU6050_Set_Rate(50); //设置采样率为50Hz }else return 1; return 0; } ​ ​ /* 设置MPU6050陀螺仪传感器满量程范围 fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps 返回值:0,设置成功 其他,设置失败 */ u8 MPU6050_Set_Gyro_Fsr(u8 fsr) { return MPU6050_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围 } ​ /* 函数功能:设置MPU6050加速度传感器满量程范围 函数功能:fsr:0,±2g;1,±4g;2,±8g;3,±16g 返 回 值:0,设置成功 其他,设置失败 */ u8 MPU6050_Set_Accel_Fsr(u8 fsr) { return MPU6050_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围 } ​ ​ /* 函数功能:设置MPU6050的数字低通滤波器 函数参数:lpf:数字低通滤波频率(Hz) 返 回 值:0,设置成功 其他,设置失败 */ u8 MPU6050_Set_LPF(u16 lpf) { u8 data=0; if(lpf>=188)data=1; else if(lpf>=98)data=2; else if(lpf>=42)data=3; else if(lpf>=20)data=4; else if(lpf>=10)data=5; else data=6; return MPU6050_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器 } ​ /* 函数功能:设置MPU6050的采样率(假定Fs=1KHz) 函数参数:rate:4~1000(Hz) 返 回 值:0,设置成功 其他,设置失败 */ u8 MPU6050_Set_Rate(u16 rate) { u8 data; if(rate>1000)rate=1000; if(rate<4)rate=4; data=1000/rate-1; data=MPU6050_Write_Byte(MPU_SAMPLE_RATE_REG,data); //设置数字低通滤波器 return MPU6050_Set_LPF(rate/2); //自动设置LPF为采样率的一半 } ​ /* 函数功能:得到温度值 返 回 值:返回值:温度值(扩大了100倍) */ short MPU6050_Get_Temperature(void) { u8 buf[2]; short raw; float temp; MPU6050_Read_Len(MPU6050_ADDR,MPU_TEMP_OUTH_REG,2,buf); raw=((u16)buf[0]<<8)|buf[1]; temp=36.53+((double)raw)/340; return temp*100;; } ​ ​ /* 函数功能:得到陀螺仪值(原始值) 函数参数:gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号) 返 回 值:0,成功,其他,错误代码 */ u8 MPU6050_Get_Gyroscope(short *gx,short *gy,short *gz) { u8 buf[6],res; res=MPU6050_Read_Len(MPU6050_ADDR,MPU_GYRO_XOUTH_REG,6,buf); if(res==0) { *gx=((u16)buf[0]<<8)|buf[1]; *gy=((u16)buf[2]<<8)|buf[3]; *gz=((u16)buf[4]<<8)|buf[5]; } return res;; } ​ /* 函数功能:得到加速度值(原始值) 函数参数:gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号) 返 回 值:0,成功,其他,错误代码 */ u8 MPU6050_Get_Accelerometer(short *ax,short *ay,short *az) { u8 buf[6],res; res=MPU6050_Read_Len(MPU6050_ADDR,MPU_ACCEL_XOUTH_REG,6,buf); if(res==0) { *ax=((u16)buf[0]<<8)|buf[1]; *ay=((u16)buf[2]<<8)|buf[3]; *az=((u16)buf[4]<<8)|buf[5]; } return res;; } ​ /* 函数功能:IIC连续写 函数参数: addr:器件地址 reg:寄存器地址 len:写入长度 buf:数据区 返 回 值:0,成功,其他,错误代码 */ u8 MPU6050_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf) { u8 i; MPU6050_IIC_Start(); MPU6050_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 if(MPU6050_IIC_Wait_Ack()) //等待应答 { MPU6050_IIC_Stop(); printf("等待应答失败\r\n"); return 1; } MPU6050_IIC_Send_Byte(reg); //写寄存器地址 MPU6050_IIC_Wait_Ack(); //等待应答 for(i=0;i<len;i++) { MPU6050_IIC_Send_Byte(buf[i]); //发送数据 if(MPU6050_IIC_Wait_Ack()) //等待ACK { MPU6050_IIC_Stop(); printf("等待ACK失败\r\n"); return 1; } } MPU6050_IIC_Stop(); return 0; } ​ /* 函数功能:IIC连续写 函数参数: IIC连续读 addr:器件地址 reg:要读取的寄存器地址 len:要读取的长度 buf:读取到的数据存储区 返 回 值:0,成功,其他,错误代码 */ u8 MPU6050_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf) { MPU6050_IIC_Start(); MPU6050_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 if(MPU6050_IIC_Wait_Ack()) //等待应答 { MPU6050_IIC_Stop(); return 1; } MPU6050_IIC_Send_Byte(reg); //写寄存器地址 MPU6050_IIC_Wait_Ack(); //等待应答 MPU6050_IIC_Start(); MPU6050_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令 MPU6050_IIC_Wait_Ack(); //等待应答 while(len) { if(len==1)*buf=MPU6050_IIC_Read_Byte(0);//读数据,发送nACK else *buf=MPU6050_IIC_Read_Byte(1); //读数据,发送ACK len--; buf++; } MPU6050_IIC_Stop(); //产生一个停止条件 return 0; } ​ /* 函数功能:IIC写一个字节 函数参数: reg:寄存器地址 data:数据 返 回 值:0,成功,其他,错误代码 */ u8 MPU6050_Write_Byte(u8 reg,u8 data) { MPU6050_IIC_Start(); MPU6050_IIC_Send_Byte((MPU6050_ADDR<<1)|0);//发送器件地址+写命令 if(MPU6050_IIC_Wait_Ack()) //等待应答 { MPU6050_IIC_Stop(); return 1; } MPU6050_IIC_Send_Byte(reg); //写寄存器地址 MPU6050_IIC_Wait_Ack(); //等待应答 MPU6050_IIC_Send_Byte(data);//发送数据 if(MPU6050_IIC_Wait_Ack()) //等待ACK { MPU6050_IIC_Stop(); return 1; } MPU6050_IIC_Stop(); return 0; } ​ /* 函数功能:IIC读一个字节 函数参数: reg:寄存器地址 data:数据 返 回 值:返回值:读到的数据 */ u8 MPU6050_Read_Byte(u8 reg) { u8 res; MPU6050_IIC_Start(); MPU6050_IIC_Send_Byte((MPU6050_ADDR<<1)|0);//发送器件地址+写命令 MPU6050_IIC_Wait_Ack(); //等待应答 MPU6050_IIC_Send_Byte(reg); //写寄存器地址 MPU6050_IIC_Wait_Ack(); //等待应答 MPU6050_IIC_Start(); MPU6050_IIC_Send_Byte((MPU6050_ADDR<<1)|1);//发送器件地址+读命令 MPU6050_IIC_Wait_Ack(); //等待应答 res=MPU6050_IIC_Read_Byte(0);//读取数据,发送nACK MPU6050_IIC_Stop(); //产生一个停止条件 return res; }2.3 整体代码框架初始化硬件、读取传感器数据、计算倾斜角度并通过 OLED 显示屏显示结果。#include "stm32f10x.h" #include "mpu6050.h" #include "oled.h" #include "math.h" ​ // 常量定义 #define ALPHA 0.98 // 互补滤波的权重系数 #define DEG_TO_RAD(x) ((x) * 3.14159265358979 / 180.0) ​ // 全局变量定义 float pitch = 0.0f; // 俯仰角 float roll = 0.0f; // 滚转角 float pitch_prev = 0.0f; // 上一周期俯仰角 float roll_prev = 0.0f; // 上一周期滚转角 float gyroX = 0.0f, gyroY = 0.0f, gyroZ = 0.0f; // 陀螺仪数据 float accelX = 0.0f, accelY = 0.0f, accelZ = 0.0f; // 加速度计数据 float gyroXrate = 0.0f, gyroYrate = 0.0f, gyroZrate = 0.0f; // 角速度 ​ void delay_ms(uint32_t ms); void MPU6050_Init(void); void ReadMPU6050(void); void UpdateAngles(void); void Display(void); ​ int main(void) { // 初始化硬件 SystemInit(); // 初始化系统时钟 MPU6050_Init(); // 初始化MPU6050 OLED_Init(); // 初始化OLED显示屏 while (1) { // 读取MPU6050传感器数据 ReadMPU6050(); // 更新角度数据 UpdateAngles(); // 显示结果到OLED屏幕 Display(); } } ​ // 延时函数 void delay_ms(uint32_t ms) { uint32_t i; for(i = 0; i < ms * 1000; i++) { __NOP(); } } ​ // 初始化MPU6050传感器 void MPU6050_Init(void) { // 假设已经实现了 I2C 初始化和MPU6050的配置 MPU6050_InitI2C(); // I2C初始化 MPU6050_Config(); // 配置MPU6050 } ​ // 读取MPU6050传感器数据 void ReadMPU6050(void) { // 从MPU6050读取加速度和陀螺仪数据 accelX = (float)MPU6050_ReadAccelX(); // 读取X轴加速度数据 accelY = (float)MPU6050_ReadAccelY(); // 读取Y轴加速度数据 accelZ = (float)MPU6050_ReadAccelZ(); // 读取Z轴加速度数据 gyroX = (float)MPU6050_ReadGyroX(); // 读取X轴陀螺仪数据 gyroY = (float)MPU6050_ReadGyroY(); // 读取Y轴陀螺仪数据 gyroZ = (float)MPU6050_ReadGyroZ(); // 读取Z轴陀螺仪数据 // 将陀螺仪的角速度转换为角度变化 gyroXrate = gyroX * DEG_TO_RAD(1.0f); // 角速度转化为角度 gyroYrate = gyroY * DEG_TO_RAD(1.0f); gyroZrate = gyroZ * DEG_TO_RAD(1.0f); } ​ // 更新俯仰角和滚转角 void UpdateAngles(void) { // 加速度计计算角度(静态) float accel_pitch = atan2f(accelX, sqrtf(accelY * accelY + accelZ * accelZ)) * 180.0f / M_PI; float accel_roll = atan2f(accelY, sqrtf(accelX * accelX + accelZ * accelZ)) * 180.0f / M_PI; ​ // 陀螺仪计算角度(动态) pitch += gyroXrate * 0.01f; // 0.01f为采样时间间隔 roll += gyroYrate * 0.01f; ​ // 互补滤波(数据融合) pitch = ALPHA * (pitch_prev + gyroXrate * 0.01f) + (1 - ALPHA) * accel_pitch; roll = ALPHA * (roll_prev + gyroYrate * 0.01f) + (1 - ALPHA) * accel_roll; ​ // 更新上一周期角度 pitch_prev = pitch; roll_prev = roll; } ​ // 显示数据到OLED屏幕 void Display(void) { // 清屏 OLED_Clear(); // 显示俯仰角(pitch)和滚转角(roll) OLED_ShowString(0, 0, "Pitch: "); OLED_ShowFloat(60, 0, pitch, 2); // 显示俯仰角,保留2位小数 OLED_ShowString(0, 2, "Roll: "); OLED_ShowFloat(60, 2, roll, 2); // 显示滚转角,保留2位小数 ​ // 显示中心圆圈与小球可视化(此部分需根据具体显示库实现) OLED_DrawCircle(64, 32, 30); // 圆心 (64, 32),半径 30 int ball_x = (int)(64 + 30 * sin(DEG_TO_RAD(roll))); int ball_y = (int)(32 + 30 * sin(DEG_TO_RAD(pitch))); OLED_DrawCircle(ball_x, ball_y, 3); // 小球,半径3 }硬件初始化:MPU6050_Init():初始化 MPU6050 传感器。OLED_Init():初始化 OLED 显示屏。MPU6050 数据读取:ReadMPU6050() 从 MPU6050 读取加速度计和陀螺仪数据。数据读取后,转换为设备的角速度和加速度,并存储为 gyroXrate、gyroYrate、gyroZrate 和 accelX、accelY、accelZ。数据融合与角度计算:UpdateAngles() 使用互补滤波算法融合加速度计和陀螺仪数据,更新设备的俯仰角(pitch)和滚转角(roll)。计算的俯仰角和滚转角实时更新并用于后续显示。显示结果:Display() 函数清空 OLED 屏幕并显示俯仰角和滚转角。它还显示了一个可视化效果,其中包括一个圆圈和一个根据角度变化的小球。显示函数 OLED_ShowFloat() 和 OLED_DrawCircle() 用于显示浮动数字和绘制圆形。三、总结本项目设计并实现了一款基于 STM32F103C8T6 单片机的电子水平仪,采用 MPU6050 传感器进行姿态检测,并通过 OLED 显示屏实时展示设备的俯仰角和滚转角。通过应用互补滤波算法,项目有效地融合了加速度计和陀螺仪的数据,提供了高效、实时且精确的角度估算,满足了设备在动态和静态环境下的姿态检测需求。本系统设计具有高度的可扩展性,可以根据不同的应用场景进一步优化滤波算法、增加功能如按键校准、低功耗优化等。该电子水平仪不仅在电子设备的水平测量中具有广泛应用,还可以作为嵌入式系统设计中的经典实践,展示了如何结合传感器数据融合、实时显示和用户交互。
  • [技术干货] 基于STM32设计的智能桌面暖风机(华为云IOT)
    一、前言1.1 项目开发背景随着智能家居技术的迅猛发展,传统家用电器正逐步向智能化方向转型。暖风机作为冬季广泛使用的取暖设备,其智能化升级不仅能够提高用户的使用体验,还能通过物联网技术实现远程控制和数据监控,赋予其更高的使用价值和市场竞争力。在日常生活中,用户对暖风机的使用需求多样化,既需要实时了解室内环境温湿度数据,也希望能够通过简单的方式对暖风机的状态进行控制,如调整档位、开关设备等。同时,考虑到节能和高效的取暖效果,采用PTC陶瓷材料加热器作为核心发热元件,以其高效、稳定、安全的特点满足现代家庭对取暖设备的性能需求。语音识别技术的成熟为智能家居设备的交互方式带来了新的可能性。用户无需繁琐的按钮操作,仅通过语音指令即可实现对设备的控制,大幅提升了使用的便捷性和智能化水平。此外,物联网技术的发展使得设备可以通过网络与云平台实现数据交互,为设备提供远程监控、控制和数据分析的能力,这不仅能够提升用户体验,还为设备的运维与优化提供了可能。为了满足用户对智能暖风机的需求,本项目基于STM32F103C8T6主控芯片设计一款智能暖风机设备,集成环境温湿度实时检测、本地LCD显示、语音控制以及物联网功能。通过ESP8266模块连接华为云IoT物联网平台,实现设备状态的云端展示与远程控制。同时,设计Android手机APP和Windows上位机软件,提供多平台的交互支持,用户可以随时随地掌握设备运行状态并进行控制。这一设计不仅结合了物联网和智能控制技术,还符合现代用户对舒适、便捷、智能生活的追求,具有广阔的市场前景和应用价值。1.2 设计实现的功能本项目设计的智能暖风机支持实时检测并显示环境温度和湿度,通过集成传感器获取室内环境数据,并在本地LCD显示屏上实时展示。这些数据不仅帮助用户了解室内环境状况,还为设备的智能控制提供支持。暖风机具备多档位调节功能,用户可以根据需求选择不同的取暖模式。设备状态,包括开关状态、取暖档位以及当前时间等信息,均清晰显示在LCD屏上,方便用户随时掌握设备的运行情况。基于PTC陶瓷加热技术,暖风机能够提供稳定且高效的热量输出,同时通过内置风扇将热空气均匀分布,提升取暖效果。语音识别控制功能是本项目的一大亮点。用户无需传统的物理按键操作,只需通过语音指令即可完成设备的开关和档位调节。这不仅增强了设备的智能化和交互体验,还为老人和儿童等特殊群体提供了更加友好的使用方式。设备支持物联网功能,通过ESP8266-WIFI模块和MQTT协议连接至华为云IoT平台。实时上传环境数据和设备状态至云端,用户可通过Android手机APP或Windows上位机远程查看和控制设备。无论是家中还是外出,用户都能轻松掌握设备的运行状态并进行远程操作,从而实现智能化、便捷化的暖风机控制。智能暖风机的Android APP和Windows上位机软件基于Qt (C++)设计,具备友好的用户界面和稳定的交互功能。通过这些平台,用户可以实时监控设备数据,包括环境温湿度、设备档位和开关状态,并对设备进行远程开关操作。这种跨平台的支持确保了用户能够在多种设备上享受统一的控制体验。实现的功能详解如下:(1) 环境数据检测 支持实时监测环境温度和湿度,采用DHT11传感器(后续计划升级为SHT30)采集数据,为设备运行提供环境依据,并在LCD屏上直观显示。(2) 本地状态显示 通过LCD显示屏,实时展示设备的温湿度信息、开关状态、取暖档位以及当前时间,帮助用户随时掌握设备运行状态。(3) 语音识别控制 集成HLK-V20语音识别模块,支持用户通过语音指令对设备进行开关控制及档位调节,提供高效便捷的语音交互功能。(4) 红外遥控功能 支持通过遥控器使用NEC红外线协议对设备进行无线控制,包括开关操作和档位调整,为用户提供另一种便捷的控制方式。(5) 联网功能 通过ESP8266-01S模块和MQTT协议接入华为云IoT平台,设备可实时上传环境数据和运行状态,并接收来自云端的控制指令。(6) 远程控制功能 设计基于Qt (C++)开发的Android手机APP和Windows电脑上位机,用户可通过这些平台远程查看暖风机的状态(如开关状态、档位、温湿度)并实现控制操作,无论身在何处都能轻松掌控设备。(7) 多档位取暖调节 设备支持多档位调节功能,用户可根据室内温度或取暖需求选择不同档位,实现舒适化和节能化的取暖效果。(8) 高效取暖与安全保护 采用PTC陶瓷加热器提供稳定、高效的加热效果,结合内置风扇实现均匀热风输出。同时,通过PTC特性及过热保护设计,确保设备在使用中的安全性和可靠性。(9) 数据存储与云同步 设备将环境数据和运行状态上传至华为云IoT平台,便于用户通过云端查看历史记录,并为数据分析和优化提供支持。(10) 多方式控制 支持语音、遥控器、本地按键及远程APP多种控制方式,满足用户在不同场景下的操作需求,增强设备的适用性和用户体验。1.3 项目硬件模块组成(1) 主控模块 采用STM32F103C8T6作为主控芯片,负责协调各功能模块,包括环境数据处理、设备状态管理、语音控制、远程通信及显示等功能。(2) WIFI通信模块 使用ESP8266-01S模块,基于MQTT协议实现与华为云IoT平台的无线连接,支持数据上传和远程控制。(3) 语音识别模块 选用海凌科HLK-V20语音识别模块,用于识别语音指令,实现暖风机的开关控制和档位调整,提供智能语音交互功能。(4) 红外遥控模块 集成NEC红外线协议的接收模块,用于接收遥控器指令,实现暖风机的无线遥控操作,包括开关和档位调节。(5) 环境传感器模块 采用DHT11传感器(后续升级为SHT30)实时检测环境温湿度数据,为设备运行提供环境参数参考,并在LCD屏上显示。(6) 显示模块 使用LCD显示屏,实时显示设备状态,包括环境温湿度、暖风机开关状态、档位及当前时间,帮助用户直观了解设备运行情况。(7) 加热模块 采用PTC陶瓷加热器作为核心发热部件,利用其正温度系数特性提供安全、高效的加热效果,并配备内置风扇将热风均匀分布。(8) 按键控制模块 设备配备物理按键,用于手动操作暖风机开关和档位调节,作为语音和遥控控制的备选方案。(9) 电源模块 为整个系统提供稳定可靠的电源供应,包括主控芯片、WIFI模块、传感器、语音模块、显示屏及加热模块的电源需求,确保设备稳定运行。(10) 风道与散热模块 设计合理的风道结构,通过内置风扇加速热风扩散,优化散热效率,避免设备长时间运行时因过热而影响安全性和使用寿命。(11) 外壳及防护模块 采用耐高温材料制作外壳,结合散热设计和绝缘处理,确保设备运行安全,同时增强结构强度和美观性。1.4 设计思路硬件设计以STM32F103C8T6为核心处理单元,结合ESP8266-WIFI模块、语音识别模块(HLK-V20)和PTC陶瓷加热器等关键组件,实现设备的核心功能。STM32F103C8T6凭借其高性能和丰富的外设接口,能够满足传感器数据采集、LCD显示、语音指令处理及网络通信的多任务需求。传感器部分选用高精度温湿度传感器用于环境参数监测,将数据实时传输给MCU进行处理并显示在LCD屏上。语音控制模块通过HLK-V20芯片实现,对用户语音指令进行识别和处理,结合MCU实现暖风机的开关控制和档位调整。这种设计避免了传统按钮操作的繁琐,提升了设备的人机交互水平。PTC陶瓷加热器作为暖风机的核心部件,结合内置风扇,提供稳定高效的取暖效果,并充分利用其正温度系数特性,确保设备运行的安全性和节能性。其网络功能通过ESP8266模块和MQTT协议实现。设备与华为云IoT平台的连接使其具备数据上传和远程控制的能力。环境温湿度数据和设备运行状态会周期性上传至云平台,用户可以通过手机APP或Windows上位机软件随时查看和控制设备。采用MQTT协议能够保证数据传输的高效性和实时性,适应智能家居设备对低延时、高可靠性的要求。软件设计方面,本地端采用Qt (C++)开发用户控制应用,覆盖Android和Windows两个平台,提供统一的操作界面。用户通过APP或上位机软件,可以直观地查看设备运行状态,包括环境数据、档位信息和开关状态,并可进行远程开关和档位调节操作。APP和上位机的软件架构与华为云IoT平台深度集成,确保数据同步的实时性和准确性。在系统功能的实现中,采用模块化设计思路,各子模块(如传感器数据采集、语音控制、网络通信、APP控制等)独立开发并通过主控MCU进行协同管理。这种设计不仅提高了系统开发的效率和稳定性,还便于后续功能扩展和维护。整体设计注重硬件与软件的协同工作,将传感技术、语音交互和物联网技术融合,为用户提供便捷、安全、高效的智能取暖解决方案,同时展现了现代智能家居产品的功能集成和技术创新。1.5 系统功能总结本项目使用的相关开发工具,资料都已经上传到网盘,需要的可自行下载。cid:link_1功能类别具体功能描述环境数据监测温湿度检测实时监测环境温度和湿度,提供环境数据参考,并在LCD上显示。显示功能本地LCD显示实时显示环境温湿度、设备开关状态、取暖档位及当前时间,为用户提供清晰的运行状态信息。控制功能语音控制用户通过语音指令控制设备开关和档位调节,提升智能交互体验。红外遥控支持遥控器使用NEC红外线协议进行无线控制,实现开关和档位调整功能。按键控制设备支持物理按键手动操作,作为其他控制方式的补充方案。远程控制用户通过Android APP或Windows上位机进行远程操作,查看设备状态并控制开关及档位调整。联网功能云平台接入通过ESP8266模块和MQTT协议接入华为云IoT平台,实现数据上传和云端控制功能。数据同步与存储实时上传环境数据和设备状态至云端,支持历史数据存储及查看。取暖功能多档位调节提供多档取暖模式,用户可根据环境和需求选择适合的取暖档位。高效加热使用PTC陶瓷加热器提供稳定高效的加热效果,内置风扇实现热量均匀分布。安全功能过热保护通过过热保护和PTC正温度系数特性确保设备运行安全性,防止温度过高导致的风险。散热优化优化风道和外壳散热设计,延长设备使用寿命并保障安全。时间显示功能当前时间显示LCD屏支持显示当前时间,提升设备的功能性和实用性。多控制方式支持综合控制方式集成语音、遥控器、按键及远程APP多种控制方式,满足用户不同场景下的操作需求。远程管理功能跨平台支持Android手机APP和Windows上位机均可对设备进行状态查看和操作,提供统一且便捷的远程管理体验。二、部署华为云物联网平台华为云官网: cid:link_12打开官网,搜索物联网,就能快速找到 设备接入IoTDA。2.1 物联网平台介绍华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助我们快速构筑物联网解决方案。使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。2.2 开通物联网服务地址: cid:link_9点击立即创建。正在创建标准版实例,需要等待片刻。创建完成之后,点击实例名称。 可以看到标准版实例的设备接入端口和地址。在上面也能看到 免费单元的限制。开通之后,点击总览,也能查看接入信息。 我们当前设备准备采用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_7业务流程:(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_7对于设备而言,一般会订阅平台下发消息给设备 这个主题。设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。以当前设备为例,最终订阅主题的格式如下: $oc/devices/{device_id}/sys/messages/down 最终的格式: $oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down(4)主题发布格式对于设备来说,主题发布表示向云平台上传数据,将最新的传感器数据,设备状态上传到云平台。这个操作称为:属性上报。帮助文档地址:cid:link_3根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:发布的主题格式: $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_2MQTT协议的端口支持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_8打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。下面是打开的页面:填入设备的信息: (上面两行就是设备创建完成之后保存得到的)直接得到三元组信息。得到三元组之后,设备端通过MQTT协议登录鉴权的时候,填入参数即可。ClientId 663cb18871d845632a0912e7_dev1_0_0_2024050911 Username 663cb18871d845632a0912e7_dev1 Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac2372.7 模拟设备登录测试经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。(1)填入登录信息打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。(2)打开网页查看完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。点击详情页面,可以看到上传的数据:到此,云平台的部署已经完成,设备已经可以正常上传数据了。(3)MQTT登录测试参数总结MQTT服务器: 117.78.5.125 MQTT端口号: 183 //物联网服务器的设备信息 #define MQTT_ClientID "663cb18871d845632a0912e7_dev1_0_0_2024050911" #define MQTT_UserName "663cb18871d845632a0912e7_dev1" #define MQTT_PassWord "71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237" //订阅与发布的主题 #define SET_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down" //订阅 #define POST_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report" //发布 发布的数据: {"services": [{"service_id": "stm32","properties":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}2.8 创建IAM账户创建一个IAM账户,因为接下来开发上位机,需要使用云平台的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。地址: cid:link_5【1】获取项目凭证 点击左上角用户名,选择下拉菜单里的我的凭证项目凭证:28add376c01e4a61ac8b621c714bf459【2】创建IAM用户鼠标放在左上角头像上,在下拉菜单里选择统一身份认证。点击左上角创建用户。创建成功:【3】创建完成用户信息如下:主用户名 l19504562721 IAM用户 ds_abc 密码 DS123456782.9 获取影子数据帮助文档:cid:link_6设备影子介绍:设备影子是一个用于存储和检索设备当前状态信息的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的中文官网:QT5.12.6的下载地址:cid:link_10或者去网盘里下载:cid:link_11打开下载链接后选择下面的版本进行下载: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_43.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图标与名称【4】编译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五、总结本项目设计的智能暖风机集成了温湿度监测、语音交互、多档调节、物联网连接以及远程控制等多项智能化功能,为用户提供更加便捷、高效、安全的取暖体验。通过采用STM32F103C8T6作为主控芯片,结合PTC陶瓷加热技术和ESP8266物联网模块,系统在硬件性能与智能功能之间达到了良好的平衡。智能暖风机通过语音识别技术简化了用户操作,使得设备交互更加直观和友好,同时保留了物理按键的手动控制功能,满足不同用户的需求。设备能够实时检测环境温湿度信息,并将数据上传至华为云IoT平台,用户通过手机APP或电脑上位机软件可以随时查看设备运行状态或远程控制设备。这种多平台、多功能的设计极大地提升了用户的操作便利性和使用体验。此外,项目注重安全性和能效优化,通过PTC加热器的特性结合过热保护和散热优化设计,确保设备在长时间工作中的安全稳定运行。合理的模块化设计使系统功能易于扩展,为后续的功能优化和智能化升级提供了良好的基础。智能暖风机项目不仅展示了智能家居产品的技术优势,也为用户提供了一个舒适、智能化的取暖解决方案。未来,可以在此基础上进一步开发更多创新功能,使其在智能家电领域具有更大的应用前景和市场竞争力。
  • [技术干货] 基于物联网地下煤矿安全监测与预警
    一、前言1.1 项目介绍当前项目使用的相关软件工具已经上传到网盘:cid:link_1【1】项目开发背景随着全球对能源需求的持续增长,煤炭作为重要的传统能源之一,在许多国家和地区依然扮演着不可或缺的角色。然而,煤矿开采作业由于其特殊的地下环境,常常伴随着较高的安全风险,包括瓦斯爆炸、火灾、透水事故等。这些事故不仅会导致严重的人员伤亡和经济损失,还可能引发长期的环境问题。因此,提高煤矿的安全管理水平,减少事故发生率,成为行业发展中需要解决的问题。近年来,物联网(IoT)技术的发展为矿井安全管理提供了新的解决方案。通过部署各种传感器和智能设备,可以实现对矿井内环境参数的实时监测,及时发现潜在的风险因素,并采取有效的预防措施。基于此背景,本项目提出了一种基于物联网设计的地下煤矿安全监测与预警系统。该系统利用先进的传感技术和无线通信技术,构建一个智能化的安全监控网络,以增强矿井作业的安全性,提升应急响应速度,降低事故发生概率。项目将重点放在以下几个方面:通过温湿度传感器和气体传感器对矿井内的温度、湿度以及瓦斯浓度进行连续监测;引入人体检测传感器来监控人员活动情况,确保在紧急情况下能够迅速定位并救援被困人员;采用OLED显示屏在现场展示关键数据,同时通过NBIoT模块将数据上传至华为云物联网平台,实现远程监控;开发一套基于Qt的可视化大屏软件界面,方便管理人员随时查看矿井状况,并作出快速决策。【2】华为云IOT物联网平台华为云IoT物联网平台是华为公司提供的一种全栈式、安全可靠的云服务,它能够支持各种物联网场景和行业应用。(1)全面连接能力:华为云IoT平台支持多种网络协议(如MQTT, CoAP, HTTP等)以及广泛的设备接入方式,可以实现不同种类的终端设备与云端的稳定连接。(2)强大的数据处理能力:平台提供了丰富的数据处理功能,包括规则引擎、流式计算、消息路由等,能够快速对海量数据进行分析处理,并根据业务需求触发相应的动作或告警。(3)安全保障机制:通过采用端到端的安全架构设计,华为云IoT平台为用户提供多层次的安全防护措施,确保从设备端到云端的数据传输过程中的安全性。(4)灵活部署选项:除了公共云之外,还支持私有云及混合云等多种部署模式,使得企业可以根据自身实际情况选择最适合自己的解决方案。(5)开放生态系统:构建了一个开放的合作生态体系,不仅与其他华为产品和服务无缝集成,也兼容第三方系统和服务,便于开发者基于此平台开发出更多创新的应用和服务。(6)高效运维管理:提供了一套完善的设备管理工具集,帮助用户轻松完成设备生命周期内的所有操作,如注册、激活、配置更新、状态监控等。(7)全球服务能力:依托于华为在全球范围内的基础设施布局,该平台能够为企业提供跨国界的物联网服务支持。对于基于物联网的地下煤矿安全监测与预警系统来说,利用华为云IoT平台的优势,可以有效提升系统的稳定性、可靠性和安全性,同时简化了开发流程,加快了项目上线速度。此外,通过运用其强大的数据分析能力和灵活的服务定制特性,还可以进一步优化安全管理策略,提高应对突发事件的能力。【3】设计实现的功能(1)环境温湿度监测使用DHT11温湿度传感器实时检测矿井内的温度和相对湿度。当检测到的数值超过预设的安全阈值时,系统会触发蜂鸣器报警,提醒工作人员采取相应措施。(2)瓦斯浓度检测与自动通风控制通过MQ5气体传感器监测矿井内瓦斯(甲烷)的浓度。一旦瓦斯浓度达到危险水平,控制系统将激活继电器开关模块,自动启动通风风扇以降低有害气体浓度,并可能伴有声音警报。(3)人员存在检测利用红外热释电人体感应模块检测矿井内是否有人。如果检测到人员存在,系统将点亮指示灯,以此作为视觉提示,增强对现场人员活动的监控。(4)数据实时显示采用OLED显示屏来展示当前采集到的各项环境参数,包括但不限于温湿度、瓦斯浓度等,以便于现场工作人员及时了解矿井内的实际情况。(5)远程数据上传通过BC26 NBIOT模块将收集到的所有环境信息上传至华为云物联网平台,允许远程监控和数据分析,提高管理效率和响应速度。(6)可视化大屏界面开发了基于Qt框架的可视化大屏软件界面,运行在Windows电脑端。该界面可以接收并展示从设备上传的数据,为管理人员提供一个直观且易于操作的平台来进行数据查看和分析。【4】项目硬件模块组成(1)主控芯片 - STM32F103RCT6作为系统的核心处理器,负责处理来自各个传感器的数据、执行控制逻辑以及管理通信协议。(2)温湿度传感器 - DHT11用于实时监测矿井内的温度和相对湿度,并将数据传输给主控芯片。当环境参数超过设定的安全阈值时,触发报警机制。(3)瓦斯浓度检测模块 - MQ5气体传感器专门用于检测环境中甲烷等可燃气体的浓度。一旦检测到的瓦斯浓度达到危险水平,会通过控制系统激活通风设备以降低浓度,并触发警报。(4)人体检测传感器 - 红外热释电模块通过感应人体发出的红外辐射来判断区域内是否有人存在,增强现场的安全监控能力。(5)显示模块 - SPI接口OLED显示屏提供一个直观的用户界面,用来显示当前采集到的温湿度、瓦斯浓度等关键信息。(6)无线通信模块 - BC26 NBIOT模块负责将收集到的各种环境数据通过NBIoT网络上传至华为云物联网平台,实现远程监控和数据分析。(7)蜂鸣器报警在任何环境参数超出预设的安全范围时,蜂鸣器将被激活,发出声音警报以提醒工作人员采取紧急措施。(8)继电器开关模块 - 电磁继电器根据主控芯片发送的指令控制外部设备如通风风扇的工作状态,确保在必要时能够迅速响应。(9)风扇模块 - 矿用通风风扇当瓦斯浓度过高时,通过继电器控制自动启动,以快速降低矿井内有害气体的浓度,保障人员安全。(10)电源管理包括为控制电路供电的5V 2A稳压电源及为风扇等高功耗设备提供的市电供应,保证整个系统稳定可靠地运行。(11)指示灯 - LED指示灯用于视觉上提示系统状态或特定事件的发生,比如当检测到人员存在时点亮指示灯。1.2 设计思路本项目的设计思路基于对煤矿安全现状的深入分析,在利用物联网技术构建一个全面、智能且高效的地下煤矿安全监测与预警系统。首先,我们认识到矿井作业环境中存在的多种潜在风险因素,如瓦斯积聚、温湿度异常以及突发事故等,这些都可能直接威胁到矿工的生命安全。因此,设计之初就明确了系统需要具备实时监测环境参数的能力,并能够快速响应以降低风险。为了实现这一目标,系统集成了多种传感器来收集关键数据。DHT11温湿度传感器用于监测矿井内的温度和湿度变化,这是评估工作环境舒适度及防止因极端条件引发事故的重要指标。MQ5气体传感器则专注于检测瓦斯浓度,因为瓦斯是导致煤矿爆炸的主要原因之一。当这些传感器检测到的数据超过预设的安全阈值时,系统会立即启动报警机制,通过蜂鸣器发出声音警报,同时自动开启通风风扇以稀释有害气体,从而迅速减轻潜在危险。考虑到矿井内人员的安全管理同样重要,系统还加入了红外热释电人体感应模块,用以监测是否有人员在场。这不仅有助于提高现场的安全意识,还能在紧急情况下帮助救援队伍更快地定位被困人员。此外,OLED显示屏被用来在现场直观展示各种监测数据,确保所有工作人员都能及时了解当前的环境状况。为了让管理者能够远程监控矿井状态并进行数据分析,系统采用了BC26 NBIoT模块将采集的数据上传至华为云物联网平台。这种做法极大地增强了系统的灵活性和可扩展性,使得即使不在现场也能随时掌握最新情况。最后,为了提供更友好的用户体验,我们使用Qt框架开发了一款可视化大屏软件界面,该界面运行于Windows电脑端,可以清晰地呈现从设备上传来的所有信息,便于管理人员做出及时有效的决策。本项目通过集成先进的传感技术、无线通信技术和云计算平台,打造了一个多层次的安全监测体系。该体系不仅提升了煤矿作业的安全水平,也为实现智能化矿山管理奠定了坚实的基础。1.3 系统功能总结序号功能模块描述实现方式/硬件组件1温湿度监测检测矿井内温湿度情况,并在超过预设阈值时触发报警。DHT11温湿度传感器,蜂鸣器2瓦斯浓度检测监控环境中的瓦斯浓度,当浓度达到危险水平时自动开启通风设备。MQ5气体传感器,继电器控制的矿用通风风扇3人员存在监测检测矿井内是否有人员活动,提高安全响应速度。红外热释电人体感应模块,指示灯4数据显示显示实时采集到的各项环境参数。OLED显示屏(SPI协议)5数据上传将收集的数据通过无线网络上传至云端平台,支持远程监控和数据分析。BC26 NBIOT模块,华为云物联网平台6可视化界面在Windows电脑端提供一个用户友好的可视化大屏界面,用于展示和管理数据。Qt开发的图形用户界面软件7电源管理为系统提供稳定的电力供应,确保所有电子元件正常工作。5V 2A稳压电源供控制电路使用;市电供电给高功耗设备如风扇等二、部署华为云物联网平台华为云官网: cid:link_12打开官网,搜索物联网,就能快速找到 设备接入IoTDA。2.1 物联网平台介绍华为云物联网平台(IoT 设备接入云服务)提供海量设备的接入和管理能力,将物理设备联接到云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助我们快速构筑物联网解决方案。使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。2.2 开通物联网服务地址: cid:link_9点击立即创建。正在创建标准版实例,需要等待片刻。创建完成之后,点击实例名称。 可以看到标准版实例的设备接入端口和地址。在上面也能看到 免费单元的限制。开通之后,点击总览,也能查看接入信息。 我们当前设备准备采用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_7业务流程:(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_7对于设备而言,一般会订阅平台下发消息给设备 这个主题。设备想接收平台下发的消息,就需要订阅平台下发消息给设备 的主题,订阅后,平台下发消息给设备,设备就会收到消息。如果设备想要知道平台下发的消息,需要订阅上面图片里标注的主题。以当前设备为例,最终订阅主题的格式如下: $oc/devices/{device_id}/sys/messages/down 最终的格式: $oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down(4)主题发布格式对于设备来说,主题发布表示向云平台上传数据,将最新的传感器数据,设备状态上传到云平台。这个操作称为:属性上报。帮助文档地址:cid:link_3根据帮助文档的介绍, 当前设备发布主题,上报属性的格式总结如下:发布的主题格式: $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_2MQTT协议的端口支持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_8打开这个工具,填入设备的信息(也就是刚才创建完设备之后保存的信息),点击生成,就可以得到MQTT的登录信息了。下面是打开的页面:填入设备的信息: (上面两行就是设备创建完成之后保存得到的)直接得到三元组信息。得到三元组之后,设备端通过MQTT协议登录鉴权的时候,填入参数即可。ClientId 663cb18871d845632a0912e7_dev1_0_0_2024050911 Username 663cb18871d845632a0912e7_dev1 Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac2372.7 模拟设备登录测试经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。(1)填入登录信息打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。(2)打开网页查看完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。点击详情页面,可以看到上传的数据:到此,云平台的部署已经完成,设备已经可以正常上传数据了。(3)MQTT登录测试参数总结MQTT服务器: 117.78.5.125 MQTT端口号: 183 ​ //物联网服务器的设备信息 #define MQTT_ClientID "663cb18871d845632a0912e7_dev1_0_0_2024050911" #define MQTT_UserName "663cb18871d845632a0912e7_dev1" #define MQTT_PassWord "71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237" ​ //订阅与发布的主题 #define SET_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down" //订阅 #define POST_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report" //发布 ​ ​ 发布的数据: {"services": [{"service_id": "stm32","properties":{"DHT11_T":30,"DHT11_H":10,"BH1750":1,"MQ135":0}}]}2.8 创建IAM账户创建一个IAM账户,因为接下来开发上位机,需要使用云平台的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。地址: cid:link_5【1】获取项目凭证 点击左上角用户名,选择下拉菜单里的我的凭证项目凭证:28add376c01e4a61ac8b621c714bf459【2】创建IAM用户鼠标放在左上角头像上,在下拉菜单里选择统一身份认证。点击左上角创建用户。创建成功:【3】创建完成用户信息如下:主用户名 l19504562721 IAM用户 ds_abc 密码 DS123456782.9 获取影子数据帮助文档:cid:link_6设备影子介绍:设备影子是一个用于存储和检索设备当前状态信息的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的中文官网:QT5.12.6的下载地址:cid:link_10或者去网盘里下载:cid:link_11打开下载链接后选择下面的版本进行下载: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_43.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图标与名称【4】编译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五、总结本项目设计并实现一套基于物联网技术的地下煤矿安全监测与预警系统,以提高矿工工作环境的安全性。该系统通过集成多种传感器技术,能够实时监控矿井内的温湿度、瓦斯浓度及人员活动情况,并在检测到异常时及时发出警报,采取相应的安全措施。系统硬件核心采用STM32F103RCT6微控制器,结合DHT11温湿度传感器、MQ5气体传感器以及红外热释电人体感应模块,分别用于环境温湿度、瓦斯浓度和人员存在的监测。当环境参数超过预设的安全阈值时,系统将自动激活蜂鸣器报警,并通过控制继电器启动通风风扇以降低有害气体浓度。此外,OLED显示屏被用作现场显示终端,提供直观的数据展示。为了实现远程数据传输与管理,系统还集成了BC26 NBIOT模块,可以将收集到的信息上传至华为云物联网平台,便于管理者进行数据分析和决策支持。为提升用户体验,我们使用Qt框架开发了一款运行于Windows平台上的可视化大屏软件界面,能够实时展现来自地下煤矿的各类监测数据,使管理人员能够迅速掌握矿区状况并作出响应。整个系统的供电设计考虑了稳定性和安全性,其中控制电路部分由5V 2A稳压电源供应,而风扇等高功耗设备则直接接入市电,确保长时间可靠运行。本项目不仅增强了地下煤矿作业场所的安全保障能力,也为未来构建更加智能化、信息化的矿山管理体系奠定了基础。
  • [技术干货] SD NAND Flash 小容量存储解决方案及其STM32测试例程讲解
    前言随着移动存储技术的快速发展和便携式数字设备的广泛应用,Flash闪存作为非易失性存储解决方案,在各种电子设备中扮演着越来越重要的角色。本文为读者提供关于Flash闪存的基础知识以及一种特别推荐的小容量存储解决方案——SD NAND Flash的详细介绍。将从Flash闪存的基本概念出发,探讨其分类、特点,并深入解析NOR与NAND两种主要类型的闪存技术。重点介绍了一款SD NAND Flash产品,它不仅具有小巧的尺寸、出色的兼容性和稳定性,而且支持标准的SD 2.0协议,极大简化了开发流程。为了帮助开发者更好地理解和应用这一技术,展示了基于STM32微控制器平台实现的单块及多块数据传输测试方法,通过具体的代码示例来验证SD NAND Flash的读写性能。无论是对嵌入式系统感兴趣的技术人员还是寻找高效可靠存储方案的设计者,本文都将是一个有价值的参考资源。一、Flash闪存是什么?简介Flash闪存是一种非易失性(Non-Volatile)内存,在没有电流供应的条件下也能够长久地保持数据,其存储特性相当于硬盘。这项特性使得闪存得以成为各类便携型数字设备的存储介质的基础。各类DDR、SDRAM或者RDRAM都属于挥发性内存,只要停止电流供应内存中的数据便无法保持,因此每次电脑开机都需要把数据重新载入内存。分类NOR和NAND是市场上两种主要的非易失闪存技术。在1984年,东芝公司的发明人舛冈富士雄首次提出了快速闪存存储器的概念。与传统电脑内存不同,闪存的特点是非易失性(NVM),其记录速度也非常快。Intel是世界上第一个生产闪存并将其投放市场的公司。1988年,Intel推出了一款256K bit闪存芯片,并被称为NOR闪存。它结合了EPROM和EEPROM两项技术,并拥有一个SRAM接口。第二种闪存称为NAND闪存,由日立公司于1989年研制,被认为是NOR闪存的理想替代者。NAND闪存的写周期比NOR闪存短90%,保存与删除处理的速度相对较快。鉴于NAND出色的表现,它常常被应用于诸如CompactFlash、SmartMedia、SD卡等存储卡上。NAND闪存采用串行结构,读写操作是以页和块为单位进行的。这种结构最大的优点在于容量可以做得很大,成本较低,有利于大规模普及。特点Flash闪存是一种非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以在大多数情况下,在进行写入操作之前必须先执行擦除。NAND器件执行擦除操作相对简单,而NOR则要求在进行擦除前先将目标块内的所有位写为1。对于给定的一套写入操作(尤其是更新小文件时),更多的擦除操作需要在基于NOR的单元中进行。因此,设计师在选择存储解决方案时需要权衡各项因素,包括NOR的读速度稍快一些、NAND的写入速度更快以及NAND的擦除速度远快于NOR等。二、SD NAND FlashSD NAND(Secure Digital NAND)作为一种结合了NAND Flash技术和SD卡物理形式的存储解决方案,在现代电子设备中发挥着重要作用。这种存储技术的主要优势在于它既保留了NAND Flash存储介质的高性价比和大容量特性,又具备了SD卡的便携性和易于插入的便利性。因此,SD NAND在多种应用场合中找到了它的定位。SD NAND非常适合应用于便携式存储设备中。例如,在数码相机中,SD NAND作为存储介质,可以为用户提供大量的照片和视频存储空间。此外,在便携式媒体播放器中,SD NAND也因其小巧的外形和高容量而备受青睐。用户可以通过简单地插入或更换SD NAND卡来增加存储容量,而无需更改设备的硬件设计或内部结构。在嵌入式系统中,SD NAND同样表现出色。对于那些需要高密度存储空间并且对成本敏感的应用场景,如工业控制系统、智能家居设备以及汽车娱乐系统等,SD NAND提供了一个经济高效的选择。其灵活的存储扩展能力使得设备制造商可以根据最终产品的不同需求来调整存储容量,从而优化成本结构。移动设备也是SD NAND的重要应用领域之一。在智能手机和平板电脑中,用户可以通过插入SD NAND卡来扩展设备的存储空间,这对于那些经常拍摄大量照片或下载高清视频的用户来说尤其重要。SD NAND不仅为移动设备提供了额外的存储空间,而且由于其标准的SD卡接口,使得用户可以在不同品牌和型号的设备之间轻松地共享数据。SD NAND的优势还体现在其标准化接口上。SD NAND遵循SD卡协会制定的标准规范,这意味着它可以在任何支持SD卡接口的设备中使用,无需额外的适配器或复杂的驱动程序支持。这一点极大地简化了设备的硬件设计,并减少了因兼容性问题带来的开发障碍。SD NAND作为一种兼具成本效益和便携性的存储解决方案,在多种应用场景中展现出其独特的优势。无论是对于追求成本效益的设备制造商,还是希望获得更大存储容量的终端用户,SD NAND都提供了一个理想的选择。这里我以贴片式TF卡“CSNP32GCR01-AOW”型号为例介绍下面是芯片的实物图 这是官网申请的样品,焊接了转接板,可以直接插在SD卡卡槽上测试。 最终选型之后,设计PCB板时,设计接口,直接贴片上去使用,非常稳定,抖动也不会导致,外置卡TF卡这种容易松动的问题。概述SD NAND Flash是一种自带坏块管理的小容量闪存,尺寸小巧、简单易用,兼容性强且稳定可靠。标准SDIO接口,兼容SPI,可替代普通TF卡/SD卡,尺寸为6.2x8mm毫米。内置平均读写算法,读取速度达到23.5MB/S,写入速度为12.3MB/S。支持标准的SD 2.0协议,用户可以直接移植标准驱动代码,省去了驱动代码编程环节。引脚分配SD NAND接口定义了六个寄存器:OCR、CID、CSD、RCA、DSR和SCR。OCR、CID、CSD和SCR寄存器携带SDNAND/内容特定信息,而RCA、DSR寄存器则是存储实际配置参数的配置寄存器。数据传输模式默认模式支持可变时钟频率0-25MHz,最高12.5MB/秒接口速度(使用4条并行数据线)。高速模式支持可变时钟频率0-50MHz,最高25MB/秒接口速度(使用4条并行数据线)。通电图RDAT和RCMD(10K~100kΩ)是上拉电阻器,当SDNAND处于高阻抗状态时,保护CMD和DAT线路不受总线浮动的影响。建议VCC上有2.2uF电容,RCLK参考0~120Ω。参考设计提供了初始化、单数据块测试和多数据块测试的STM32例程,通过这些例程可以验证SD NAND Flash的读写功能。三、STM32测试例程(1)初始化初始化过程包括设置GPIO、配置SD_SPI、发送命令使SD卡进入空闲状态并获取卡类型信息。SD_Error SD_Init(void) { uint32_t i = 0; ​ /*!< Initialize SD_SPI */ GPIO_Configuration(); ​ /*!< SD chip select high */ SD_CS_HIGH(); ​ /*!< Send dummy byte 0xFF, 10 times with CS high */ /*!< Rise CS and MOSI for 80 clocks cycles */ for (i = 0; i <= 9; i++) { /*!< Send dummy byte 0xFF */ SD_WriteByte(SD_DUMMY_BYTE); } //获取卡的类型,最多尝试10次 i=0; do { /*------------Put SD in SPI mode--------------*/ /*!< SD initialized and set to SPI mode properly */ SD_GoIdleState(); ​ /*Get card type*/ SD_GetCardType(); }while(SD_Type == SD_TYPE_NOT_SD && i++ >10); //不支持的卡 if(SD_Type == SD_TYPE_NOT_SD) return SD_RESPONSE_FAILURE; return SD_GetCardInfo(&SDCardInfo); }(2)单数据块测试单数据块测试涉及填充缓冲区、写入一个512字节的数据块到地址0,然后从同一地址读取该数据块,最后比较写入和读出的数据以验证正确性。void SD_SingleBlockTest(void) { /*------------------- Block Read/Write --------------------------*/ /* Fill the buffer to send */ Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F); ​ if (Status == SD_RESPONSE_NO_ERROR) { /* Write block of 512 bytes on address 0 */ Status = SD_WriteBlock(Buffer_Block_Tx, 0x00, BLOCK_SIZE); /* Check if the Transfer is finished */ } ​ if (Status == SD_RESPONSE_NO_ERROR) { /* Read block of 512 bytes from address 0 */ Status = SD_ReadBlock(Buffer_Block_Rx, 0x00, BLOCK_SIZE); ​ } ​ /* Check the correctness of written data */ if (Status == SD_RESPONSE_NO_ERROR) { TransferStatus1 = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE); } if(TransferStatus1 == PASSED) { LED2_ON; printf("Single block 测试成功!\n"); ​ } else { LED1_ON; printf("Single block 测试失败,请确保SD卡正确接入开发板,或换一张SD卡测试!\n"); } }(3)多数据块测试多数据块测试类似单数据块测试,但涉及多个连续的数据块。这有助于评估批量数据处理的能力。void SD_MultiBlockTest(void) { /*--------------- Multiple Block Read/Write ---------------------*/ /* Fill the buffer to send */ Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 0x0); ​ if (Status == SD_RESPONSE_NO_ERROR) { /* Write multiple block of many bytes on address 0 */ Status = SD_WriteMultiBlocks(Buffer_MultiBlock_Tx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS); /* Check if the Transfer is finished */ } ​ if (Status == SD_RESPONSE_NO_ERROR) { /* Read block of many bytes from address 0 */ Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS); /* Check if the Transfer is finished */ } ​ /* Check the correctness of written data */ if (Status == SD_RESPONSE_NO_ERROR) { TransferStatus2 = Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE); } if(TransferStatus2 == PASSED) { LED2_ON; printf("Multi block 测试成功!"); ​ } else { LED1_ON; printf("Multi block 测试失败,请确保SD卡正确接入开发板,或换一张SD卡测试!"); } }(4)状态缓冲Buffercmp函数用于比较两个缓冲区的内容,确保写入和读出的数据一致。Fill_Buffer函数用于填充缓冲区,生成指定长度的数据。TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength) { while (BufferLength--) { if (*pBuffer1 != *pBuffer2) { return FAILED; } ​ pBuffer1++; pBuffer2++; } ​ return PASSED; } ​ void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset) { uint16_t index = 0; ​ /* Put in global buffer same values */ for (index = 0; index < BufferLength; index++) { pBuffer[index] = index + Offset; } }四、总结本文介绍了Flash闪存的基本概念、分类及其特点,并详细说明了SD NAND Flash产品的特性和STM32平台上的测试方法。通过这些介绍,读者可以更好地理解和应用这一类型的存储解决方案。
  • [技术干货] 基于华为云IOT设计的矿洞环境监测系统
    一、前言1.1 项目介绍【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,实现远程监控和控制功能。 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粉尘模块作为一种有效的颗粒物浓度监测工具,已经广泛应用于家庭、办公室、工厂等各种环境下的空气质量监测系统中,为人们提供了便捷的方式来监控和改善生活环境质量。二、部署华为云物联网平台华为云官网: cid:link_9打开官网,搜索物联网,就能快速找到 设备接入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_2024050911 Username 663cb18871d845632a0912e7_dev1 Password 71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac2372.7 模拟设备登录测试经过上面的步骤介绍,已经创建了产品,设备,数据模型,得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。(1)填入登录信息打开MQTT客户端软件,对号填入相关信息(就是上面的文本介绍)。然后,点击登录,订阅主题,发布主题。(2)打开网页查看完成上面的操作之后,打开华为云网页后台,可以看到设备已经在线了。点击详情页面,可以看到上传的数据:到此,云平台的部署已经完成,设备已经可以正常上传数据了。(3)MQTT登录测试参数总结MQTT服务器: 117.78.5.125 MQTT端口号: 183 //物联网服务器的设备信息 #define MQTT_ClientID "663cb18871d845632a0912e7_dev1_0_0_2024050911" #define MQTT_UserName "663cb18871d845632a0912e7_dev1" #define MQTT_PassWord "71b82deae83e80f04c4269b5bbce3b2fc7c13f610948fe210ce18650909ac237" //订阅与发布的主题 #define SET_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/messages/down" //订阅 #define POST_TOPIC "$oc/devices/663cb18871d845632a0912e7_dev1/sys/properties/report" //发布 发布的数据: {"services": [{"service_id": "stm32","properties":{"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】创建完成用户信息如下:主用户名 l19504562721 IAM用户 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的中文官网:QT5.12.6的下载地址:https://download.qt.io/archive/qt/5.12/5.12.6或者去网盘里下载:https://pan.quark.cn/s/145a9b3f7f53打开下载链接后选择下面的版本进行下载: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图标与名称【4】编译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单片机的矿山环境作业安全监测系统,以提高矿山作业的安全性和效率。系统集成了多种传感器,包括DHT11温湿度传感器、MQ5气体传感器和PM2.5传感器,用于实时监测矿山环境中的关键参数,如温度、湿度、瓦斯浓度和颗粒物含量。通过这些传感器,系统能够及时发现潜在的安全隐患,并采取必要的预防措施。在硬件设计方面,系统采用了STM32F103RCT6单片机作为核心控制器,配合蜂鸣器、继电器模块、OLED显示屏等组件,形成了一个完整的监测与控制系统。当检测到的环境参数超过预设的安全阈值时,系统能够自动触发报警,并通过控制风扇和雾化喷淋系统来降低瓦斯浓度和颗粒物含量,从而保障矿工的生命安全。此外,为了实现远程监控与管理,项目还引入了BC26(NBIOT)模块,将环境数据上传至华为云物联网平台,并开发了一款基于Qt框架的Android平台手机应用程序。该应用程序不仅能够实时显示环境参数,还能接收警报信息,并允许用户远程控制风扇和雾化降尘设备的开关状态,极大地提升了系统的实用性和灵活性。该矿山环境作业安全监测系统通过集成先进的传感技术和物联网技术,实现了对矿山环境的全方位监控,能够在危险发生之前提供预警,并采取有效的防护措施,对于提升矿山作业的安全管理水平具有重要意义。
  • [设备专区] AR502H容器版:制作编译环境基础镜像报错
    1.执行 build_sdk.sh 报如下图错误(dockhub网站内未能找到huawei-ec-iot/sdk:base镜像)2.镜像服务应该是正常的,可以下载nginx3.docker镜像拉取采用了国内代理
  • [技术干货] 图像分析处理技术:从基础到应用的未来趋势
    图像分析处理技术是计算机视觉领域的核心,涉及图像的获取、处理、分析和理解。随着人工智能和机器学习技术的飞速发展,图像分析处理技术在各行各业中扮演着越来越重要的角色。本文将探讨图像识别、图像分析以及图像处理技术的特点、应用场景和技术方案,并展望其未来的发展趋势与挑战。一、图像识别技术图像识别是图像分析处理技术的一个重要分支,它涉及到从图像中识别出特定的对象、场景或活动。这一技术的核心是模式识别,即通过算法识别图像中的模式并将其与已知的模式进行匹配。特点自动化:自动识别图像中的对象,无需人工干预。高效率:能够快速处理大量图像数据。高准确率:随着模型训练的深入,识别准确率可以非常高。可扩展性:可以应用于不同的图像识别任务,如面部识别、车牌识别等。应用场景面部识别:用于安全验证和个人身份确认。物体识别:在零售、物流等领域自动识别商品。场景识别:在自动驾驶中识别道路和交通标志。典型技术方案卷积神经网络(CNN):一种深度学习模型,特别适用于图像识别任务。支持向量机(SVM):一种监督学习模型,用于分类和识别。深度信念网络(DBN):由多个受限玻尔兹曼机堆叠而成的深度学习模型。二、图像分析技术图像分析不仅包括图像识别,还包括对图像内容的深入分析和理解。图像分析通常涉及到图像的预处理、特征提取、模式识别和决策制定。特点复杂性:分析过程涉及多个步骤,需要复杂的算法。多维度:不仅识别图像中的对象,还分析其属性和关系。适应性:能够适应不同的图像条件和环境。应用场景医疗图像分析:在放射学中分析X光片、CT扫描和MRI图像。卫星图像分析:用于地理信息系统(GIS)和环境监测。视频监控分析:在安全监控中分析视频流以检测异常行为。典型技术方案图像分割:将图像分割成多个区域或对象的技术。特征提取:从图像中提取关键特征,如边缘、角点等。机器学习算法:包括决策树、随机森林等,用于图像分析的分类和回归任务。三、图像处理技术图像处理技术是图像分析处理技术的基础,它涉及到对图像数据的修改、改善和转换,以满足特定的应用需求。特点多样性:处理方法多样,可以根据需求选择不同的技术。实时性:许多图像处理操作可以实时进行,适用于视频流等动态图像。可定制性:可以根据具体的应用场景定制处理流程。应用场景图像增强:提高图像的可见性,如对比度增强、亮度调整等。滤波:去除图像噪声,如高斯滤波、中值滤波等。图像变换:进行图像的几何变换,如旋转、缩放、裁剪等。典型技术方案图像滤波器:用于平滑图像或突出图像的某些特征。图像变换算法:如傅里叶变换、小波变换等,用于分析图像的频域特性。图像增强技术:包括直方图均衡化、锐化等,用于改善图像的视觉质量。四、技术对比虽然图像识别、图像分析和图像处理紧密相关,但它们各自有不同的侧重点和应用场景:图像识别:侧重于从图像中识别出特定的对象或场景;通常需要较高的计算资源,依赖于复杂的算法和模型。图像分析:不仅识别图像内容,还深入分析图像的特征和属性;侧重于理解和解释图像内容,可能涉及到复杂的决策过程。图像处理:更多关注图像质量的改善和信息的提取,不一定需要复杂的模型;更多是技术性的,关注图像数据的修改和转换。尽管存在差异,但这些技术经常相互融合,共同解决复杂的图像分析问题。例如,图像处理可以作为图像识别和分析的预处理步骤,而图像分析的结果又可以用于指导图像处理的方向。五、应用方向图像分析处理技术的应用领域非常广泛,以下是一些主要的应用方向:工业自动化在工业自动化中用于质量控制、机器人导航和装配线监控。通过图像识别和分析,机器可以自动检测产品缺陷、分类物品和执行精确的操作。医疗健康在医疗领域,图像分析处理技术用于诊断、治疗规划和手术辅助。例如,通过分析医学影像,医生可以更准确地识别疾病和制定治疗方案。安全监控安全监控是图像分析技术的另一个重要应用领域。通过实时视频分析,可以检测异常行为、入侵者和其他安全威胁。社交媒体与娱乐在社交媒体和娱乐行业,图像分析用于内容推荐、用户交互和增强现实(AR)体验。例如,通过面部识别技术,用户可以在社交媒体上创建有趣的滤镜和效果。交通管理图像分析在交通管理中用于交通流量监控、事故检测和交通违规识别。这有助于提高道路安全性和交通效率。农业监测在农业领域,图像分析用于作物监测、病虫害检测和产量预测。通过分析卫星图像和无人机拍摄的图像,农民可以更好地管理作物和资源。六、未来趋势与挑战图像分析处理技术正在快速发展,同时也面临着一些挑战。技术发展趋势更深层次的网络结构:随着计算能力的提升,更深的网络结构正在被开发,以提高识别和分析的准确性。端到端学习:从输入到输出的端到端学习正在成为趋势,减少了对中间特征工程的依赖。多模态学习:结合视觉信息和其他类型的数据(如文本、声音)进行多模态学习。面临的挑战数据隐私:随着图像数据的大量收集和分析,如何保护个人隐私成为一个重要问题。算法偏见:机器学习模型可能会学习到训练数据中的偏见,导致不公平的结果。可解释性:深度学习模型通常被认为是“黑箱”,提高模型的可解释性是一个挑战。潜在的解决方案隐私保护技术:如差分隐私和联邦学习,可以在不泄露个人数据的情况下进行学习。公平性算法:开发新的算法来减少模型的偏见,提高决策的公平性。模型解释性:研究新的技术来解释深度学习模型的决策过程。七、总结图像分析处理技术是当今科技领域中最活跃和最有前景的领域之一。从基础的图像处理到复杂的图像识别和分析,这些技术正在不断进步,并被应用于各种实际问题中。图像分析处理技术对于提高生产效率、改善生活质量、增强安全保障等方面发挥着重要作用。不同的技术方案针对不同的应用场景,显示了这一领域的多样性和创新性。随着技术的发展,我们也必须面对数据隐私、算法偏见和模型可解释性等挑战。图像分析处理技术将继续发展,新的技术、算法和应用将不断涌现,为社会带来更多的价值。
  • [问题求助] 求助,我使用的是esp8266,是我发送的格式有问题吗,下载到后面直接是400报错了
    是啥问题呢?使用的固件是1471
  • [技术干货] 基于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,并成功连接到移动网络。