STM32项目分享:智能家居(机智云)升级版

描述

项目成品图片:


 

机智云


 

01

项目简介


 

1.功能详解


 

STM32智能家居(机智云)升级版

功能如下:


 

检测功能:监测环境温湿度、烟雾浓度、一氧化碳、空气质量、光照强度、大气压强

显示功能:将检测到的数据显示在OLED上
 

控制功能:系统可以控制LED灯、步进电机(窗户)
 

手动模式:机智云APP远程控制LED灯和步进电机。
 

自动模式:系统检测到烟雾浓度/一氧化碳/空气质量超出阈值时、蜂鸣报警并开窗通风;光线低于阈值时,自动开启LED灯
 

阈值调节:按键调节系统阈值
 

手机APP:通过ESP8266 WIFI模块连接网络,接入机智云服务器,实现数据上报和控制下发


 

2.材料清单

STM32F103C8T6单片机

OLED 屏幕
 

DHT11温湿度传感器
 

光敏电阻
 

MQ-2烟雾传感器
 

MQ-7一氧化碳传感器
 

MQ-135空气质量传感器
 

ESP8266-01S(WIFI模块)
 

步进电机
 

有源蜂鸣器

 


 

02


 

原理图设计


 

机智云


 

03

PCB硬件设计


 

   PCB图

机智云机智云


 

04

程序设计


 

  •  
  •  
  •  

#include "stm32f10x.h"                  // Device header#include "oled.h"#include "adcx.h"#include "bmp280.h"#include "sensormodules.h"#include "dht11.h"#include "key.h"#include "tim2.h"#include "tim3.h"#include "flash.h"#include "motor.h"#include "led.h"#include "usart.h"#include "iwdg.h"
SensorModules sensorData;//声明传感器模块的结构体变量SensorThresholdValue Sensorthreshold;//声明传感器阈值结构体变量
#define KEY_Long111
#define KEY_11#define KEY_22#define KEY_33#define KEY_44
#define FLASH_START_ADDR0x0801f000//写入的起始地址
uint8_t motorFlag = 0;uint8_t oledPages = 1;//系统显示页面uint8_t model;//系统模式
typedef enum {DISPLAY_PAGE1 = 1,DISPLAY_PAGE2,SETTINGS_PAGE} OLED_PAGES;
/**  * @brief  显示菜单1的固定内容  * @param  无  * @retval 无  */void OLED_Menu1(void){//显示“温度:  C”OLED_ShowChinese(1,1,48);OLED_ShowChinese(1,2,49);OLED_ShowChar(1,5,':');OLED_ShowChar(1,8,'C');
//显示“湿度:   %”OLED_ShowChinese(1,5,50);OLED_ShowChinese(1,6,51);OLED_ShowChar(1,13,':');OLED_ShowChar(1,16,'%');
//显示”光照强度:  Lux“OLED_ShowChinese(2, 1, 8);OLED_ShowChinese(2, 2, 9);OLED_ShowChinese(2, 3, 10);OLED_ShowChinese(2, 4, 11);OLED_ShowChar(2, 9, ':');OLED_ShowString(2, 14, "Lux");
//显示“大气压强: ”OLED_ShowChinese(3, 1, 12);OLED_ShowChinese(3, 2, 13);OLED_ShowChinese(3, 3, 14);OLED_ShowChinese(3, 4, 15);OLED_ShowChar(3, 9, ':');OLED_ShowString(3, 14, "hPa");
//显示“系统模式:”OLED_ShowChinese(4, 1, 28);OLED_ShowChinese(4, 2, 29);OLED_ShowChinese(4, 3, 30);OLED_ShowChinese(4, 4, 31);OLED_ShowChar(4, 9, ':');}
/**  * @brief  显示菜单2的固定内容  * @param  无  * @retval 无  */void OLED_Menu2(void){//显示“烟雾浓度:  ppm”OLED_ShowChinese(1, 1, 20);OLED_ShowChinese(1, 2, 21);OLED_ShowChinese(1, 3, 22);OLED_ShowChinese(1, 4, 23);OLED_ShowChar(1, 9, ':');OLED_ShowString(1,13,"ppm");
//显示“一氧化碳:  ppm”OLED_ShowChinese(2, 1, 16);OLED_ShowChinese(2, 2, 17);OLED_ShowChinese(2, 3, 18);OLED_ShowChinese(2, 4, 19);OLED_ShowChar(2, 9, ':');OLED_ShowString(2,13,"ppm");
//显示“空气质量:  ppm”OLED_ShowChinese(3, 1, 24);OLED_ShowChinese(3, 2, 25);OLED_ShowChinese(3, 3, 26);OLED_ShowChinese(3, 4, 27);OLED_ShowChar(3, 9, ':');OLED_ShowString(3,13,"ppm");}
/**  * @brief  显示菜单1的传感器数据  * @param  无  * @retval 无  */void SensorDataDisplay1(void){//显示温度数据OLED_ShowNum(1, 6, sensorData.temp, 2);
//显示湿度数据OLED_ShowNum(1, 14, sensorData.humi, 2);
//显示光照强度数据OLED_ShowNum(2, 10, sensorData.lux, 4);
//显示大气压强数据OLED_ShowNum(3, 10, 1020, 4);

//显示系统状态数据if (!model){OLED_ShowChinese(4, 6, 36);OLED_ShowChinese(4, 7, 37);}else{OLED_ShowChinese(4, 6, 32);OLED_ShowChinese(4, 7, 33);}}
/**  * @brief  显示菜单2的传感器数据  * @param  无  * @retval 无  */void SensorDataDisplay2(void){
//显示烟雾浓度数据OLED_ShowNum(1, 10, sensorData.smoke, 3);
//显示一氧化碳数据OLED_ShowNum(2, 10, sensorData.CO, 3);
//显示空气质量数据OLED_ShowNum(3, 10, sensorData.AQI, 3);}
/**  * @brief  显示系统阈值设置界面1  * @param  无  * @retval 无  */void OLED_SetInterfacevoid(void){//显示“光照阈值”OLED_ShowChinese(1, 2, 8);OLED_ShowChinese(1, 3, 9);OLED_ShowChinese(1, 4, 42);OLED_ShowChinese(1, 5, 43);OLED_ShowChar(1, 11, ':');
//显示“烟雾阈值”OLED_ShowChinese(2, 2, 20);OLED_ShowChinese(2, 3, 21);OLED_ShowChinese(2, 4, 42);OLED_ShowChinese(2, 5, 43);OLED_ShowChar(2, 11, ':');
//显示“一氧化碳阈值”OLED_ShowString(3, 3, "CO");OLED_ShowChinese(3, 4, 42);OLED_ShowChinese(3, 5, 43);OLED_ShowChar(3, 11, ':');
//显示“空气质量阈值”OLED_ShowString(4, 3, "AQI");OLED_ShowChinese(4, 4, 42);OLED_ShowChinese(4, 5, 43);OLED_ShowChar(4, 11, ':');
//显示光照阈值数值OLED_ShowNum(1, 12, Sensorthreshold.luxValue, 4);
//显示烟雾阈值数值OLED_ShowNum(2, 12, Sensorthreshold.smokeValue, 3);
//显示一氧化碳阈值数值OLED_ShowNum(3, 12, Sensorthreshold.COValue, 3);
//显示空气质量阈值数值OLED_ShowNum(4, 12, Sensorthreshold.AQIValue, 3);}
/**  * @brief  记录阈值界面下按KEY1的次数  * @param  无  * @retval 返回次数  */uint8_t SetSelection(void){static uint8_t count = 1;if(KeyNum == KEY_1){KeyNum = 0;count++;if (count > 4){count = 1;}}return count;}
/**  * @brief  显示阈值界面的选择符号  * @param  num 为显示的位置  * @retval 无  */void OLED_Option(uint8_t num){switch(num){case 1:OLED_ShowChar(1,1,'>');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,' ');break;case 2:OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,'>');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,' ');break;case 3:OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,'>');OLED_ShowChar(4,1,' ');break;case 4:OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,'>');break;default: break;}}
/**  * @brief  对阈值界面的传感器阈值进行修改  * @param  num 为当前用户需要更改的传感器阈值位置  * @retval 无  */void ThresholdModification(uint8_t num){switch (num){case 1:if (KeyNum == KEY_3){KeyNum = 0;Sensorthreshold.luxValue += 10;if (Sensorthreshold.luxValue > 2000){Sensorthreshold.luxValue = 0;}}else if (KeyNum == KEY_4){KeyNum = 0;Sensorthreshold.luxValue -= 10;if (Sensorthreshold.luxValue > 2000){Sensorthreshold.luxValue = 2000;}}break;
case 2:if (KeyNum == KEY_3){KeyNum = 0;Sensorthreshold.smokeValue += 10;if (Sensorthreshold.smokeValue > 500){Sensorthreshold.smokeValue = 0;}}else if (KeyNum == KEY_4){KeyNum = 0;Sensorthreshold.smokeValue -= 10;if (Sensorthreshold.smokeValue > 500){Sensorthreshold.smokeValue = 500;}}break;case 3:if (KeyNum == KEY_3){KeyNum = 0;Sensorthreshold.COValue += 10;if (Sensorthreshold.COValue > 500){Sensorthreshold.COValue = 0;}}else if (KeyNum == KEY_4){KeyNum = 0;Sensorthreshold.COValue -= 10;if (Sensorthreshold.COValue > 500){Sensorthreshold.COValue = 500;}}break;case 4:if (KeyNum == KEY_3){KeyNum = 0;Sensorthreshold.AQIValue += 10;if (Sensorthreshold.AQIValue > 500){Sensorthreshold.AQIValue = 0;}}else if (KeyNum == KEY_4){KeyNum = 0;Sensorthreshold.AQIValue -= 10;if (Sensorthreshold.AQIValue > 500){Sensorthreshold.AQIValue = 500;}}break;default: break;}}
/**  * @brief  根据标志位控制步进电机的运行  * @param  无  * @retval 无  */void MotorOperation(void){if (motorFlag == 1){MOTOR_Direction_Angle(1, 0, 90, 1);MOTOR_STOP();motorFlag = 0;}else if (motorFlag == 2){MOTOR_Direction_Angle(0, 0, 90, 1);MOTOR_STOP();motorFlag = 0;}
}
/**  * @brief  传感器数据扫描  * @param  无  * @retval 无  */void SensorScan(void){DHT11_Read_Data(&sensorData.humi, &sensorData.temp);Get_Average_LDR_LUX(&sensorData.lux);Get_Average_MQ2_PPM(&sensorData.smoke);Get_Average_MQ7_PPM(&sensorData.CO);Get_Average_MQ135_PPM(&sensorData.AQI);sensorData.hPa = (uint32_t)BMP280_Get_Pressure();}

int main(void){ADCX_Init();    Timer2_Init(9,14398);Uart2_Init(9600);Uart1_Init(115200);IWDG_Init();
OLED_Init();Bmp_Init();DHT11_Init();Key_Init();MOTOR_Init();LED_Init();Buzzer_Init();
Sensorthreshold.luxValue = FLASH_R(FLASH_START_ADDR);//从指定页的地址读FLASHSensorthreshold.smokeValue = FLASH_R(FLASH_START_ADDR+2);//从指定页的地址读FLASHSensorthreshold.COValue = FLASH_R(FLASH_START_ADDR+4);//从指定页的地址读FLASHSensorthreshold.AQIValue = FLASH_R(FLASH_START_ADDR+6);//从指定页的地址读FLASH
GENERAL_TIM_Init();userInit();//完成机智云初始赋值gizwitsInit();//开辟一个环形缓冲区while (1){
IWDG_ReloadCounter();//使能重装载寄存器计数SensorScan();//获取传感器数据

switch (oledPages){case DISPLAY_PAGE1:OLED_Menu1();//显示主页面1固定信息SensorDataDisplay1();//显示传感器1数据MotorOperation();
/*按键按下时进入主页面2*/if (KeyNum == KEY_2){KeyNum = 0;oledPages = DISPLAY_PAGE2;OLED_Clear();}
/*按键按下时切换模式*/if (KeyNum == KEY_1){KeyNum = 0;
model = !model;if (!model){LED_OFF();Buzzer_OFF();}}
/*按键按下时进入阈值设计界面*/if (KeyNum == KEY_Long1){KeyNum = 0;oledPages = SETTINGS_PAGE;OLED_Clear();}break;
case DISPLAY_PAGE2:OLED_Menu2();SensorDataDisplay2();MotorOperation();
/*按键按下时进入主页面2*/if (KeyNum == KEY_2){KeyNum = 0;oledPages = DISPLAY_PAGE1;OLED_Clear();}break;
case SETTINGS_PAGE:OLED_SetInterfacevoid();//显示阈值设置界面的固定内容OLED_Option(SetSelection());//实现阈值设置页面的选择功能ThresholdModification(SetSelection());//实现阈值调节功能
//判断是否退出阈值设置界面if (KeyNum == KEY_2){KeyNum = 0;oledPages = DISPLAY_PAGE1;//跳转到主界面OLED_Clear();//清屏
//存储修改的传感器阈值至flash内FLASH_W(FLASH_START_ADDR, Sensorthreshold.luxValue, Sensorthreshold.smokeValue, Sensorthreshold.COValue, Sensorthreshold.AQIValue);}break;default: break;}
userHandle();//更新机智云数据点变量存储的值gizwitsHandle((dataPoint_t *)¤tDataPoint);//数据上传至机智云}}
 


 

05

实验效果


 

机智云机智云


 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分