基于STM32单片机智能家居wifi远程监控系统机智云app设计
本文设计了一个基于STM32单片机的智能家居远程监控系统,通过WiFi连接机智云平台实现手机APP远程监测。系统集成了多种传感器模块,包括BMP280气压传感器、MQ135空气质量传感器、DHT11温湿度传感器和MQ7一氧化碳传感器,可实时检测环境参数并显示在OLED屏幕上。系统具备智能控制功能,根据光照强度自动调节LED灯和窗帘电机,当检测值超出阈值时触发蜂鸣器报警。文章详细介绍了各传感器电路设
·
基于STM32单片机智能家居wifi远程监控系统机智云app设计
1、系统功能介绍
-
1、系统检测环境中温湿度,气压,一氧化碳,空气质量,烟雾浓度和光照强度,并把测量的值显示在屏幕上,数据上报云平台可以通过手机APP实时查看。
-
2、通过光照强度传感器检测光照强度,当光照强度小于阈值,表明此时天黑了,自动点亮LED灯照明并且驱动步进电机顺时针旋转180度表示拉上窗帘。
-
3、如果光照强度高,表示是白天,熄灭LED灯,并驱动步进电机逆时针旋转180度,表示拉开窗帘。
-
4、系统设置有阈值,传感器监测数据不再阈值范围内启动蜂鸣器报警。
-
根据本篇文章完成毕业设计的开题报告、任务书、设计、毕业论文等
2、演示视频
3、系统电路介绍
3.1、BMP280气压检测电路设计
- BMP280 是 Bosch 推出的一款高精度数字气压和温度传感器,广泛应用于环境监测、气象站、海拔测量和物联网设备中。它支持 I²C 和 SPI 两种通信接口,供电电压范围通常为 1.71V~3.6V,推荐电压为 3.3V,部分模块通过集成稳压芯片和电平转换器可直接接 5V 系统。
- BMP280 内部集成高精度压力和温度传感器,其输出为 24 位 ADC 数字信号,通过 I²C 或 SPI 总线传输给主控 MCU。在设计中应注意电源滤波,推荐在 VCC 端并联 0.1μF 去耦电容,确保电源稳定,防止噪声干扰导致测量误差。
电路原理图
实物图:
3.2、MQ135空气质量检测电路设计
- MQ135 是一种常用的空气质量传感器,能够检测多种有害气体(如氨气、苯类化合物、烟雾、CO₂ 等)。它基于金属氧化物半导体气敏元件,电阻值会随着气体浓度变化,从而实现浓度检测。
- 在实际应用中,MQ135 需要一定的预热时间(通常 24 至 48 小时)以达到稳定工作状态,其输出信号与气体浓度呈非线性关系,实际测量必须通过标定曲线进行换算。电路布局时,应注意信号线加 RC 滤波并避免靠近高电流元件,以提高抗干扰性能。该电路方案因结构简单、成本低,广泛用于室内空气质量监测、智能家居控制和环境监测系统,配合 STM32 等微控制器,可实现实时空气检测、数据显示以及阈值报警功能。
电路原理图:
实物图:
3.3、DHT11温湿度采集电路设计
- DHT11 是一种集成了温湿度采集功能的数字传感器,具有低成本、易于使用的特点,广泛应用于环境监测和智能家居系统中。该传感器内部包括一个电容式湿度传感器和一个NTC温度传感器,通过单总线协议将采集到的温湿度数据以数字形式输出,避免了模拟信号传输中的干扰问题。其工作电压通常为 3.3V 至 5V,因而在 STM32 等 3.3V 系统中可以直接连接。
- DHT11 的通信方式基于单总线协议,MCU 通过控制数据线电平发起启动信号,然后等待传感器响应,并按固定时序读取 40 位数据,其中包括湿度和温度的整数及小数部分,以及校验和。由于该协议对时序要求较高,通常需在程序中使用精确延时函数或定时器进行处理。在电路上,数据线长度应尽量缩短,避免过长的连接线引入信号衰减和干扰。
电路原理图:
实物图:
3.4、MQ7一氧化碳检测采集电路设计
- MQ7 是一种基于金属氧化物半导体气敏元件的一氧化碳检测传感器,广泛应用于智能家居、环境安全和车载空气监测等领域。它通过检测气体与敏感材料接触时引起的电阻变化,间接获取气体浓度。MQ7 的工作原理要求周期性加热,采用不同的加热电压来实现检测和恢复,这一点在电路设计中需要特别注意。
- 信号接口方面,AO 端通过电压值反映气体浓度,MCU 可以利用 ADC 通道进行采集;DO 端在超过设定阈值时输出低电平,可直接用于报警。若系统采用 STM32 作为主控,需将 AO 接入 ADC 引脚,DO 接至 GPIO 并启用外部中断,实现实时报警功能。由于输出电压随气体浓度变化的非线性特性,软件上应采用标定曲线或插值算法对 ADC 数据进行浓度换算。
电路原理图:
实物图:
4、程序设计
4.1、BMP280驱动程序
void bmp280GetData(float* pressure,float* temperature,float* asl)
{
static float t;
static float p;
bmp280GetPressure();
t=bmp280CompensateT(bmp280RawTemperature)/100.0;
p=bmp280CompensateP(bmp280RawPressure)/25600.0;
presssureFilter(&p,pressure);
*temperature=(float)t; /*单位度*/
*pressure=(float)p ; /*单位hPa*/
*asl=bmp280PressureToAltitude(pressure); /*转换成海拔*/
}
#define CONST_PF 0.1902630958 //(1/5.25588f) Pressure factor
#define FIX_TEMP 25 // Fixed Temperature. ASL is a function of pressure and temperature, but as the temperature changes so much (blow a little towards the flie and watch it drop 5 degrees) it corrupts the ASL estimates.
// TLDR: Adjusting for temp changes does more harm than good.
/*
* Converts pressure to altitude above sea level (ASL) in meters
*/
static float bmp280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/)
{
if (*pressure>0)
{
return((pow((1015.7f/ *pressure),CONST_PF)-1.0f)*(FIX_TEMP+273.15f))/0.0065f;
}
else
{
return 0;
}
}
4.2、OLED驱动程序
/**********************************************
// IIC Write byte
**********************************************/
void OLED_Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
// OLED_SCLK_Clr();
m=m&0x80;
if(m==0x80)
{OLED_SDIN_Set();}
else OLED_SDIN_Clr();
da=da<<1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
/**********************************************
// IIC Write Command
**********************************************/
void OLED_Write_IIC_Command(unsigned char IIC_Command)
{
OLED_IIC_Start();
OLED_Write_IIC_Byte(0x78); //Slave address,SA0=0
OLED_IIC_Wait_Ack();
OLED_Write_IIC_Byte(0x00); //write command
OLED_IIC_Wait_Ack();
OLED_Write_IIC_Byte(IIC_Command);
OLED_IIC_Wait_Ack();
OLED_IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void OLED_Write_IIC_Data(unsigned char IIC_Data)
{
OLED_IIC_Start();
OLED_Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
OLED_IIC_Wait_Ack();
OLED_Write_IIC_Byte(0x40); //write data
OLED_IIC_Wait_Ack();
OLED_Write_IIC_Byte(IIC_Data);
OLED_IIC_Wait_Ack();
OLED_IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
OLED_Write_IIC_Data(dat);
}
else
{
OLED_Write_IIC_Command(dat);
}
}
void OLED_ShowCH1(u8 a,u8 b,u8 c,u8 d,u8 e)
{
}
void OLED_ShowCH2(u8 a,u8 b,u8 c,u8 d,u8 e)
{
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
unsigned char m,n;
for(m=0;m<8;m++)
{
OLED_WR_Byte(0xb0+m,0); //page0-page1
OLED_WR_Byte(0x00,0); //low column start address
OLED_WR_Byte(0x10,0); //high column start address
for(n=0;n<128;n++)
{
OLED_WR_Byte(fill_Data,1);
}
}
}
/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)
{
unsigned int m;
for(;Del_50ms>0;Del_50ms--)
for(m=6245;m>0;m--);
}
void Delay_1ms(unsigned int Del_1ms)
{
unsigned char j;
while(Del_1ms--)
{
for(j=0;j<123;j++);
}
}
//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
} //更新显示
}
void OLED_On(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
} //更新显示
}
4.3、DHT11驱动程序
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//读取40位数据
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0;
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
u8 DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PG端口时钟
GPIO_InitStructure.GPIO_Pin = DHT11_PIN; //PG11端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11_IO, &GPIO_InitStructure); //初始化IO口
GPIO_SetBits(DHT11_IO,DHT11_PIN); //PG11 输出高
DHT11_Rst(); //复位DHT11
return DHT11_Check();//等待DHT11的回应
}
5、资料下载
- 点击扫描下方二维码
更多推荐








所有评论(0)