STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。
使用 STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。

一、硬件设计
微控制器:选择 STM32F4 系列微控制器,如 STM32F407ZGT6,具有高性能和丰富的外设资源。
传感器模块:
温度和湿度传感器(如 DHT22 ):用于监测室内环境温湿度。
光照传感器(如 BH1750 ):检测环境光照强度。
人体红外传感器(如 HC-SR501 ):感知人体活动。
烟雾传感器(如 MQ-2 ):监测烟雾浓度,预防火灾。
门窗磁传感器:检测门窗开关状态。
通信模块:
Wi-Fi 模块(如 ESP8266 ):实现与云服务器的无线通信,上传传感器数据和接收控制指令。
蓝牙模块(如 HC-05 ):用于本地设备与手机等终端的短距离通信。
执行器模块:
继电器:控制灯光、插座等设备的开关。
电机驱动模块:控制窗帘电机、风扇等设备。

显示模块:
TFT 彩色液晶显示屏:实时显示系统状态和传感器数据。
存储模块:
EEPROM 芯片(如 AT24C02 ):存储系统配置和一些关键数据。
电源管理模块:
采用高效率的降压稳压芯片(如 LM2596 ),将输入电源转换为适合各个模块的工作电压。
配备电池管理电路,支持备用电池供电,确保系统在市电断电时仍能正常工作一段时间。

二、软件设计
系统初始化:
初始化 STM32 时钟、GPIO 、ADC 、SPI 、I2C 等外设。
初始化 Wi-Fi 模块和蓝牙模块,连接到预设的网络和配对设备。
初始化传感器和执行器的相关引脚。
传感器数据采集:
定期读取温度、湿度、光照、人体红外、烟雾等传感器的数据,并进行数据校准和滤波处理。
通过 ADC 采集模拟量传感器的数据,如烟雾浓度。
数据处理与决策:
根据传感器数据判断环境状态,如是否有人、温度是否过高、烟雾是否超标等。
基于预设的规则和逻辑,决定执行相应的控制动作,如打开灯光、启动风扇、发送报警信息等。
通信协议实现:
使用 TCP/IP 协议与云服务器进行通信,上传传感器数据,并接收服务器下发的控制指令。
通过蓝牙协议与本地手机等设备进行通信,实现近场控制和数据查看。
用户界面设计:
在 TFT 显示屏上设计友好的用户界面,实时显示传感器数据、系统状态和操作提示。
处理触摸屏输入,实现用户交互操作。
存储管理:
将系统配置信息(如 Wi-Fi 密码、设备 ID 等)存储在 EEPROM 中,确保断电不丢失。
记录关键的操作日志和传感器数据历史,以便后续查询和分析。
异常处理与系统自恢复:
监测系统运行状态,如电源电压、程序运行状态等。
当出现异常情况(如传感器故障、通信中断、内存溢出等)时,采取相应的处理措施,如重启相关模块、发送故障报警等,并尝试自动恢复系统正常运行。

#include "stm32f4xx.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
// Wi-Fi 相关
#include "wifi.h"
// 传感器相关
#include "dht22.h"
#include "bh1750.h"
#include "hc_sr501.h"
#include "mq2.h"
#include "door_window_sensor.h"
// 显示相关
#include "tft_display.h"
// 存储相关
#include "eeprom.h"
// 传感器引脚定义
#define DHT22_DATA_PIN GPIO_Pin_0
#define DHT22_PORT GPIOA
#define BH1750_SDA_PIN GPIO_Pin_1
#define BH1750_SCL_PIN GPIO_Pin_2
#define BH1750_PORT GPIOA
#define HC_SR501_PIN GPIO_Pin_3
#define HC_SR501_PORT GPIOB
#define MQ2_PIN GPIO_Pin_4
#define MQ2_PORT GPIOC
#define DOOR_WINDOW_SENSOR_PIN GPIO_Pin_5
#define DOOR_WINDOW_SENSOR_PORT GPIOD
// 执行器引脚定义
#define RELAY_PIN GPIO_Pin_6
#define RELAY_PORT GPIOE
// 通信引脚定义(假设用于与 Wi-Fi 模块通信的 UART)
#define USART_TX_PIN GPIO_Pin_9
#define USART_TX_PORT GPIOA
#define USART_RX_PIN GPIO_Pin_10
#define USART_RX_PORT GPIOA
// 显示引脚定义(假设用于 TFT 显示屏的 SPI 接口)
#define TFT_SCK_PIN GPIO_Pin_13
#define TFT_SCK_PORT GPIOB
#define TFT_MISO_PIN GPIO_Pin_14
#define TFT_MISO_PORT GPIOB
#define TFT_MOSI_PIN GPIO_Pin_15
#define TFT_MOSI_PORT GPIOB
#define TFT_CS_PIN GPIO_Pin_12
#define TFT_CS_PORT GPIOB
#define TFT_RST_PIN GPIO_Pin_11
#define TFT_RST_PORT GPIOB
// 初始化所有 GPIO 引脚
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE, ENABLE);
// DHT22 数据引脚配置
GPIO_InitStruct.GPIO_Pin = DHT22_DATA_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(DHT22_PORT, &GPIO_InitStruct);
// BH1750 I2C 引脚配置
GPIO_InitStruct.GPIO_Pin = BH1750_SDA_PIN | BH1750_SCL_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(BH1750_PORT, &GPIO_InitStruct);
// HC-SR501 引脚配置
GPIO_InitStruct.GPIO_Pin = HC_SR501_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(HC_SR501_PORT, &GPIO_InitStruct);
// MQ-2 引脚配置
GPIO_InitStruct.GPIO_Pin = MQ2_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_Init(MQ2_PORT, &GPIO_InitStruct);
// 门窗磁传感器引脚配置
GPIO_InitStruct.GPIO_Pin = DOOR_WINDOW_SENSOR_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(DOOR_WINDOW_SENSOR_PORT, &GPIO_InitStruct);
// 继电器引脚配置
GPIO_InitStruct.GPIO_Pin = RELAY_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(RELAY_PORT, &GPIO_InitStruct);
// USART 引脚配置
GPIO_InitStruct.GPIO_Pin = USART_TX_PIN | USART_RX_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(USART_TX_PORT, &GPIO_InitStruct);
// TFT 显示屏引脚配置
GPIO_InitStruct.GPIO_Pin = TFT_SCK_PIN | TFT_MISO_PIN | TFT_MOSI_PIN | TFT_CS_PIN | TFT_RST_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(TFT_SCK_PORT, &GPIO_InitStruct);
}
// 初始化 USART 用于与 Wi-Fi 模块通信
void USART_Init(void)
{
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = USART_TX_PIN | USART_RX_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(USART_TX_PORT, &GPIO_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
}
// 初始化系统
void System_Init(void)
{
GPIO_Init();
USART_Init();
// 初始化其他硬件模块
DHT22_Init();
BH1750_Init();
HC_SR501_Init();
MQ2_Init();
DoorWindowSensor_Init();
TFT_Init();
EEPROM_Init();
// 连接 Wi-Fi 网络
WiFi_Connect(WIFI_SSID, WIFI_PASSWORD);
}
// 读取 DHT22 传感器数据
void ReadDHT22(float *temperature, float *humidity)
{
DHT22_ReadData(temperature, humidity);
}
// 读取 BH1750 光照传感器数据
float ReadBH1750(void)
{
return BH1750_ReadLightIntensity();
}
// 读取 HC-SR501 人体红外传感器数据
uint8_t ReadHC_SR501(void)
{
return HC_SR501_ReadState();
}
// 读取 MQ-2 烟雾传感器数据
float ReadMQ2(void)
{
return MQ2_ReadSmokeConcentration();
}
// 读取门窗磁传感器数据
uint8_t ReadDoorWindowSensor(void)
{
return DoorWindowSensor_ReadState();
}
// 控制继电器
void ControlRelay(uint8_t state)
{
if (state)
{
GPIO_SetBits(RELAY_PORT, RELAY_PIN);
}
else
{
GPIO_ResetBits(RELAY_PORT, RELAY_PIN);
}
}
// 上传数据到云服务器
void UploadDataToCloud(float temperature, float humidity, float lightIntensity, uint8_t isPersonDetected, float smokeConcentration, uint8_t isDoorOpen)
{
char dataBuffer[256];
sprintf(dataBuffer, "{"
"\"temperature\": %.2f,"
"\"humidity\": %.2f,"
"\"light_intensity\": %.2f,"
"\"is_person_detected\": %d,"
"\"smoke_concentration\": %.2f,"
"\"is_door_open\": %d"
"}",
temperature, humidity, lightIntensity, isPersonDetected, smokeConcentration, isDoorOpen);
WiFi_SendData(dataBuffer);
}
// 主函数
int main(void)
{
float temperature, humidity;
float lightIntensity;
uint8_t isPersonDetected;
float smokeConcentration;
uint8_t isDoorOpen;
System_Init();
while (1)
{
ReadDHT22(&temperature, &humidity);
lightIntensity = ReadBH1750();
isPersonDetected = ReadHC_SR501();
smokeConcentration = ReadMQ2();
isDoorOpen = ReadDoorWindowSensor();
// 在 TFT 显示屏上显示数据
TFT_DisplayData(temperature, humidity, lightIntensity, isPersonDetected, smokeConcentration, isDoorOpen);
// 控制继电器
if (isPersonDetected)
{
ControlRelay(1);
}
else
{
ControlRelay(0);
}
// 上传数据到云服务器
UploadDataToCloud(temperature, humidity, lightIntensity, isPersonDetected, smokeConcentration, isDoorOpen);
// 延迟一段时间
HAL_Delay(5000);
}
}

相关文章:
STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。
使用 STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。 一、硬件设计 微控制器:选择 STM32F4 系列微控制器,如 STM32F407ZGT6,具有高性能和丰富的外设资源。 传感器模块&#x…...
Kettle配置数据源错误“Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found”解决记录
问题描述 错误提示:“Driver class ‘org.gjt.mm.mysql.Driver’ could not be found, make sure the ‘MySQL’ driver (jar file) is installed.” 原因分析: 根据错误提示是缺少了相关的数据源连接jar包。 解决方案: 安装对应的Mysql…...
二分搜索的三种方法
首先总的说一下二分搜索。如果区间具有二分性,这个二分性不仅仅是指区间是有序的,而是我们可以通过某一种性质将整个区间分成左区间和右区间。我们通过二分的方法去不断缩小查找的区间,最终让区间内没有元素,这个时候的我们就得到…...
使用python编写工具:快速生成chrome插件相关文件结构
本文将详细分析一段用 wxPython 编写的 Python 应用程序代码。该程序允许用户创建一些特定文件并将它们保存在指定的文件夹中,同时也能够启动 Google Chrome 浏览器并打开扩展页面,自动执行一些操作。 C:\pythoncode\new\crxiterationtaburl.py 全部代码…...
内存、显存和GPU在Transformer架构中承担什么计算任务
目录 内存、显存和GPU在Transformer架构中承担什么计算任务 一、内存、显存和GPU的区别 二、在Transformer架构中的计算任务 内存、显存和GPU在Transformer架构中承担什么计算任务 是计算机系统中重要的组成部分,它们在Transformer架构中承担着不同的计算任务。以下是对这…...
【计算机网络】TCP协议特点3
心跳机制 什么是心跳机制 心跳机制是在计算机系统、网络通信和许多其他技术领域广泛应用的一种机制,用于检测两个实体之间的连接是否仍然活跃,或者设备是否还在正常运行。就是每隔一段时间发送一个固定的消息给服务端,服务端回复一个固定…...
移植LVGL8.2以及移植过程的理解
一、LVGL刷新显示(画点 OR 区域刷新颜色) 原来LCD的区域填充,由于没用到DMA就是普通的遍历区域块的坐标,需要传入的坐标就是显示区域的x轴起始与x轴尾部。y轴的起始与y轴的尾部。 怎么实现呢? SPI不加DMA实现区域填充…...
动态规划-背包问题——1049.最后一块石头的重量II
1.题目解析 题目来源 1049.最后一块石头的重量II——力扣 测试用例 2.算法原理 首先需要将该问题转化为0-1背包问题后再做分析 1.状态表示 根据数学中的知识我们知道将一个数字分为两个子数后求这两个子数的最小差值,那么就要求这两个子数尽可能接近于原数字的一…...
【C++学习(37)】并发性模式:如生产者-消费者、读写锁等。 架构模式:如MVC、MVVM等。属于23 种设计模式吗? RAII 的关系?
并发性模式(如生产者-消费者、读写锁等)和架构模式(如 MVC、MVVM 等)并不属于 Gang of Four(GoF) 提出的 23 种经典设计模式 中。这些模式是其他领域中的设计模式,虽然它们和 GoF 的设计模式有交集,尤其是在程序架构和资源管理方面,但并不直接包含在 GoF 的 23 种设计…...
[Mysql] Mysql的多表查询----多表关系(下)
4、操作 方式二:创建表之后设置外键约束 外键约束也可以在修改表时添加,但是添加外键约束的前提是:从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。 语法: alter table <从表名> add constr…...
命名空间(namespace)详解(一)
域 在学习命名空间之前,我们首先要了解几种常见的域 一、域的种类 1、类作用域 类作用域是指定义在类内部的成员(包括数据成员和成员函数)的可见性和访问权限的范围 代码示例: #define _CRT_SECURE_NO_WARNINGS 1#include &…...
HarmonyOS ArkTs 解决流式传输编码问题
工作日志 日期:2024-11-15 标题:HarmonyOS ArkTs 解决流式传输编码问题 问题描述 问题:在处理流式数据的 HTTP 请求时,服务器返回的数据存在编码问题,导致数据无法正确地解码为字符串。部分数据在解码后出现了乱码…...
NPOI 实现Excel模板导出
记录一下使用NPOI实现定制的Excel导出模板,已下实现需求及主要逻辑 所需Json数据 对应参数 List<PurQuoteExportDataCrInput> listData [{"ItemName": "电缆VV3*162*10","Spec": "电缆VV3*162*10","Uom":…...
【OpenGL】OpenGL简介
文章目录 OpenGL概述OpenGL的本质OpenGL相关库核心库窗口管理glutfreeglutglfw 函数加载glewGLAD OpenGL概述 OpenGL(Open Graphics Library) 严格来说,本身并不是一个API,它是一个由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了…...
shell命令笔记
一、shell基本基础知识 1. shell命令中捕获上一个命令执行是否成功,通过判断 $? 是否为0,为0则表示成功,其他错误码则表示执行失败。 2. sheel命令中,变量赋值时默认都是字符串类型。赋值时须注意单引号与双引号的区别…...
qml显示OpenCV mat图片
文章目录 方式一QQuickPaintedItem 类介绍主要特点使用方法示例代码在 QML 中使用主要方法和属性注意事项编写OpenCV mat显示代码方式二本篇博客介绍在Qt6.5.3 qml项目里介绍如何显示OpenCV mat图片。视频:https://edu.csdn.net/learn/40003/654043?spm=3001.4143 在qml里显示…...
类与对象(2)---类的6个默认成员函数
1.类的6个默认成员函数 任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。 2.构造函数 2.1构造函数特性 构造函数的主要任务是初始化对象。 它有如下特…...
华为云租户网络-用的是隧道技术
1.验证租户网络是vxlan 2.验证用OVS 2.1控制节点VXLAN 本端ip(local ip)192.168.31.8 2.2计算节点VXLAN 本端ip(local ip)192.168.31.11 计算节点用的是bond0做隧道网络 2.3查看bond文件是否主备模式...
手搓神经网络(MLP)解决MNIST手写数字识别问题 | 数学推导+代码实现 | 仅用numpy,tensor和torch基本计算 | 含正反向传播数学推导
手写数字识别(神经网络入门) 文章目录 手写数字识别(神经网络入门)实验概述实验过程数据准备模型实现线性变换层前向传播反向传播更新参数整体实现 激活函数层(ReLU)前向传播反向传播整体实现 Softmax层&am…...
esp32c3安装micropython环境
esp32c3竟然支持micropython环境,真的太让人高兴了。主要是python开发比较友好,开发速度要快于C和C, 可以用来快速创意验证。 下载 首先到官网:MicroPython - Python for microcontrollers 点击“download”进入下载页面&#…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
