基于stm32的智能晾衣杆(开源)
功能演示
基于stm32的智能晾衣杆
简介
这是最近别人让我帮他做的一个毕业设计,总体来说非常简单,半天都不需要就可以实现,我做完之后,打算开源在这里让大家进行学习,我们先看一下他的任务书吧:
- 按键结合液晶屏幕并通过按键设置光照强度和湿度阈值,实现按键切换功能。
- 通过光敏传感器采集当前的光照强度,显示到显示屏上面。
- 通过DHT11传感器采集温湿度,显示到显示屏上面。
- 液晶屏显示功能提醒词、系统的状态、已设置的参数等。
- 如果湿度大于设置阈值,蜂鸣器提醒可能下雨。
- 当湿度小于阈值并且光强大于阈值,也就是天晴,自动打开晾衣杆(LED)。
- 语音播报模块进行对应语音的播报。
- 联网,可以在手机app中查看环境状态以及手动控制。
硬件资料
序号 | 元器件 | 型号 | 数量 |
# | Description | Comment | Quantity |
1 | STM32F103C8T6最小系统板 | / | 1 |
2 | 0.96寸OLED屏幕 | / | 1 |
3 | esp8266 | esp8266 01s | 1 |
4 | 有源蜂鸣器 | 有源蜂鸣器 | 1 |
5 | 三极管 | SS8050 | 1 |
6 | 电阻 4.7K | R0603 | 1 |
7 | DHT11温湿度模块 | DHT11 | 1 |
8 | 语音播报模块 | JQ8900-16P | 1 |
9 | 麦克风 | 8欧3W喇叭 | 1 |
10 | 光敏传感器 | BH1750 | 1 |
11 | 按键 | TS665CJ | 4 |
12 | 继电器 | SRD-05VDC-SL-C | 1 |
13 | 三极管 | BFS17PE6327HTSA1 | 1 |
14 | 二极管 | 1N4148 | 1 |
15 | 电阻 200RF | R0603 | 2 |
16 | 排母 4P | PM254-1-04-Z-8.5 | 2 |
17 | 排母 3P | PM254-1-03-Z-8.5 | 1 |
18 | 排母 20P | PM254-1-20-Z-8.5 | 2 |
19 | 排母 8P | PM254-1-08-Z-8.6 | 2 |
20 | 排针 2P | 2.54mm 1*2P | 1 |
21 | 排母 2*2P | 2.54mm,2×4Doublerowfemale | 1 |
PCB以及原理图
硬件框图
软件分析
工程文件
Start:存放stm32配置的起始文件、内核相关文件、系统文件。
Library:存放stm32f103的标准库文件。
User:存放用户文件。
Hardware:存放硬件文件,包括蜂鸣器、LED、DHT11、BH1750、按键、OLED......
System:存放用户写的一些系统文件,例如延时、时钟配置、串口配置以及相关宏定义。
Gizwits以及Utils:与联网配置有关的文件。
软件流程
1、引用相关驱动的头文件、定义好相关的变量以及宏,声明好定义的函数。
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "bsp_buzzer.h"
#include "bsp_dht11.h"
#include "BH1750FVI.h"
#include "voice.h"
#include "Key.h"
#include "led.h"
#include "OLED.h"
#include "Timer.h"
#include "usart.h"
#include "gizwits_product.h"
#define Refresh_Sensor_time400 //400ms刷新一次传感器数值
uint8_t jiemian;//0:主界面 1:阈值设置界面
uint8_t jiemian_change=1;//界面刚刚切换的时候,为1,以防一个界面,重复刷新同样的内容
uint8_t Set_Choose;//阈值设置选项 0:光照强度 1:空气湿度
DHT11_Data_TypeDef DHT11_Data;//DTH11读取到的参数
u16 BH1750_Data;//光照强度
u8 key_num;//读取到的键值
u8 DHT11_threshold=50;//湿度阈值
u16 BH1750_threshold=2500;//光照阈值
u16 Sensor_time=Refresh_Sensor_time;
u8 Weather_state;//天气状况,0:晴天,1:阴天,2:下雨
u8 led;//0:晾衣杆关闭 1:晾衣杆打开
void Show_OLED(void);//屏幕显示
void Show_ZJM(void);//显示主界面
void Show_Set(void);//显示阈值设置界面
void Show_Sensor(void);//显示传感器数值
void Show_threshold(void);//显示阈值
void Key_Handle(void);//按键处理
void Weather_Judge(void);//判断天气
2、延时初始化,外设初始化(初始化定时器以及串口,方便之后进行使用)
delay_init();
//外设初始化
Timer2_Configuration();//定时刷新传感器数值
Timer_Init();//为机智云提供时钟
uart1_init(9600);
3、模块初始化
//模块初始化
Buzzer_Init();//蜂鸣器初始化
DHT11_Init();//DHT11初始化
BH1750_Init();//BH1750初始化
Key_Init();//按键初始化
OLED_Init();//oled初始化
voice_init();//语音模块初始化
LED_Init();//led初始化,模拟晾衣杆
4、上电初始化(初始化8s后进入系统,使得模块稳定)
lingsheng(3);//播报欢迎使用智能晾衣杆系统
OLED_ShowString(2,3,"initialing...");
for(int i=0;i<8;i++)
{
delay_ms(1000);
OLED_ShowNum(3,8,8-i,1);
}
OLED_Clear();
5、网络配置(调用机智云官方代码,初始化协议以及设置好配网模式)
/*机智云初始化*/
userInit();
gizwitsInit();
/*一件配网模式*/
gizwitsSetMode(2);
6、进入循环,不断执行循环中的代码,是这个项目中最重要的地方。
7、显示界面(根据对应的界面,显示对应的内容以及检测界面是否刚刚切换,避免同样的内容多次刷新显示,浪费cpu)
void Show_OLED(void)//屏幕显示
{
if(jiemian==0&&jiemian_change==1)
{
Show_ZJM();
jiemian_change=0;
}
else if(jiemian==0&&jiemian_change==0)
{
Show_Sensor();
}
else if(jiemian==1&&jiemian_change==1)
{
Show_Set();
jiemian_change=0;
}
else if(jiemian==1&&jiemian_change==0)
{
Show_threshold();
}
}
8、主界面(显示主界面的固定内容)
//智(0)能(1)晾(2)衣(3)杆(4)光(5)照(6)强(7)度(8)空(9)气(10)
//湿(11)度(12)阈(13)值(14)设(15)置(16)天(17)气(18)状(19)况(20)
//正(21)异(22)常(23) 晴(24)阴(25)下(26)雨(27)←(28)
void Show_ZJM(void)
{
OLED_Clear();//清屏
//智能晾衣杆
OLED_ShowF16x16(1,4,0);
OLED_ShowF16x16(1,6,1);
OLED_ShowF16x16(1,8,2);
OLED_ShowF16x16(1,10,3);
OLED_ShowF16x16(1,12,4);
//光照强度:
OLED_ShowF16x16(2,1,5);
OLED_ShowF16x16(2,3,6);
OLED_ShowF16x16(2,5,7);
OLED_ShowF16x16(2,7,8);
OLED_ShowChar(2,9,':');
//空气湿度:
OLED_ShowF16x16(3,1,9);
OLED_ShowF16x16(3,3,10);
OLED_ShowF16x16(3,5,11);
OLED_ShowF16x16(3,7,12);
OLED_ShowChar(3,9,':');
//天气状况:
OLED_ShowF16x16(4,1,17);
OLED_ShowF16x16(4,3,18);
OLED_ShowF16x16(4,5,19);
OLED_ShowF16x16(4,7,20);
OLED_ShowChar(4,9,':');
}
9、显示传感器的数值到屏幕上(根据设定的定时器,定时器刷新,避免轮询不断刷新,导致损坏传感器以及不现实的操作,并且判断出此时的天气状况)
void Show_Sensor(void)
{
if(Sensor_time==0)
{
//关闭定时器2,防止影响时序(其实不关也没事)
TIM_SetCounter(TIM2,0);
TIM_Cmd(TIM2, DISABLE);
DHT11_Read_TempAndHumidity(&DHT11_Data);//读取温湿度
BH1750_Data=bh_data_read();//读取光照强度
TIM_Cmd(TIM2,ENABLE);//开启定时器2
Sensor_time=Refresh_Sensor_time;
}
if(jiemian==0)//如果在主界面
{
/*显示传感器数值*/
OLED_ShowNum(2,10,BH1750_Data,4);//光照强度
OLED_ShowNum(3,10,DHT11_Data.humi_int,4);//空气湿度,显示个整数部分即可
/*判断此时天气状况*/
if(Weather_state==0)//晴天
{
OLED_ShowF16x16(4,10,24);
OLED_ShowF16x16(4,12,17);
}
else if(Weather_state==1)//阴天
{
OLED_ShowF16x16(4,10,25);
OLED_ShowF16x16(4,12,17);
}
else//雨天
{
OLED_ShowF16x16(4,10,26);
OLED_ShowF16x16(4,12,27);
}
}
}
10、显示设置界面(显示设置界面的固定内容,避免重复显示同样的内容,浪费cpu)
void Show_Set(void)//显示阈值设置界面
{
OLED_Clear();//清屏
//阈值设置
OLED_ShowF16x16(1,4,13);
OLED_ShowF16x16(1,6,14);
OLED_ShowF16x16(1,8,15);
OLED_ShowF16x16(1,10,16);
//光照强度:
OLED_ShowF16x16(2,1,5);
OLED_ShowF16x16(2,3,6);
OLED_ShowF16x16(2,5,7);
OLED_ShowF16x16(2,7,8);
OLED_ShowChar(2,9,':');
//空气湿度:
OLED_ShowF16x16(3,1,9);
OLED_ShowF16x16(3,3,10);
OLED_ShowF16x16(3,5,11);
OLED_ShowF16x16(3,7,12);
OLED_ShowChar(3,9,':');
}
11、显示湿度阈值以及光强阈值
void Show_threshold(void)//显示阈值
{
if(Set_Choose==0)//光照强度
{
OLED_ShowF16x16(2,14,28);//←
OLED_ShowString(3,14," ");
}
else//空气湿度
{
OLED_ShowF16x16(3,14,28);//←
OLED_ShowString(2,14," ");
}
OLED_ShowNum(2,10,BH1750_threshold,4);//光照强度阈值
OLED_ShowNum(3,10,DHT11_threshold,4);//空气湿度阈值
}
12、按键处理(不断轮询按键,如果检测到按键按下,根据此时的界面进行对应的处理)
void Key_Handle(void)//按键处理
{
key_num=Key_GetNum();
if(key_num==4&&jiemian==0)//切换到设置阈值界面
{
jiemian=1;
jiemian_change=1;
}
else if(key_num==4&&jiemian==1)//切换到主界面
{
jiemian=0;
jiemian_change=1;
}
else if(key_num==3&&jiemian==1)//阈值设置选项切换
{
Set_Choose=(Set_Choose==0)?1:0;
}
else if(key_num==2&&jiemian==1)//阈值减
{
if(Set_Choose==0)//光强 减50
{
BH1750_threshold-=50;
}
else //湿度 减1
{
DHT11_threshold-=1;
}
}
else if(key_num==1&&jiemian==1)//阈值加
{
if(Set_Choose==0)//光强 加50
{
BH1750_threshold+=50;
}
else //湿度 加1
{
DHT11_threshold+=1;
}
}
key_num=0;
}
13、判断天气状况(通过对比读取到的传感器数值和对应阈值,判断出此时的天气状况,然后进行对应处理)
void Weather_Judge(void)//判断天气
{
if(DHT11_Data.humi_int>DHT11_threshold)//下雨
{
Weather_state=2;
if(led==1)//关闭晾衣杆
{
led=0;
LED_TIP_OFF;
lingsheng(1);//下雨了,晾衣杆已关闭
}
}
else if(DHT11_Data.humi_int<DHT11_threshold&&BH1750_threshold<BH1750_Data)//晴天
{
Weather_state=0;
if(led==0)//打开晾衣杆
{
led=1;
LED_TIP_ON;
lingsheng(2);//大晴天,晾衣杆已打开
}
}
else
{
Weather_state=1;//阴天
}
}
14、刷新网络参数更新到手机app(将最新的数值刷新到网络协议参数,协议检测到数值发生变化之后,会通过相应的协议,上传到手机APP)
void userHandle(void)
{
currentDataPoint.valueDHT11_Data = DHT11_Data.humi_int;//Add Sensor Data Collection
currentDataPoint.valueBH1750_Data = BH1750_Data;//Add Sensor Data Collection
currentDataPoint.valueBH1750_threshold=BH1750_threshold;
currentDataPoint.valueDHT11_threshold=DHT11_threshold;
currentDataPoint.valueled=led;
}
15、联网,上传数据,接收下发数据(这里我们通过接收到手机app发送来的对应事件,进行对应事件的处理,我们这里的事件就是我们对应值的事件,我们在事件中,将网络参数更新到我们单片机中的对应值,实习手机app下发数据到我们的单片机,具体操作流程需要去查看机智云官方文件,文件中会有教你)
int32_t gizwitsHandle(dataPoint_t *currentData)
{
int8_t ret = 0;
#ifdef PROTOCOL_DEBUG
uint16_t i = 0;
#endif
uint8_t ackData[RB_MAX_LEN];
uint16_t protocolLen = 0;
uint32_t ackLen = 0;
protocolHead_t *recvHead = NULL;
char *didPtr = NULL;
uint16_t offset = 0;
#ifdef OTA_ENABLE
int8_t updatePieceResult = 0;
#endif
if(NULL == currentData)
{
// GIZWITS_LOG("GizwitsHandle Error , Illegal Param\n");
return -1;
}
/*resend strategy*/
gizProtocolAckHandle();
ret = gizProtocolGetOnePacket(&pRb, gizwitsProtocol.protocolBuf, &protocolLen);
if(0 == ret)
{
// GIZWITS_LOG("Get One Packet!\n");
#ifdef PROTOCOL_DEBUG
// GIZWITS_LOG("WiFi2MCU[%4d:%4d]: ", gizGetTimerCount(), protocolLen);
for(i=0; i<protocolLen;i++)
{
// GIZWITS_LOG("%02x ", gizwitsProtocol.protocolBuf[i]);
}
// GIZWITS_LOG("\n");
#endif
recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf;
switch (recvHead->cmd)
{
case CMD_GET_DEVICE_INTO:
gizProtocolGetDeviceInfo(recvHead);
break;
case CMD_ISSUED_P0:
// GIZWITS_LOG("flag %x %x \n", recvHead->flags[0], recvHead->flags[1]);
//offset = 1;
if(0 == gizProtocolIssuedProcess(didPtr, gizwitsProtocol.protocolBuf+sizeof(protocolHead_t)+offset, protocolLen-(sizeof(protocolHead_t)+offset+1), ackData, &ackLen))
{
gizProtocolIssuedDataAck(recvHead, ackData, ackLen,recvHead->flags[1]);
// GIZWITS_LOG("AckData : \n");
}
break;
case CMD_HEARTBEAT:
gizProtocolCommonAck(recvHead);
break;
case CMD_WIFISTATUS:
gizProtocolCommonAck(recvHead);
gizProtocolModuleStatus((protocolWifiStatus_t *)recvHead);
break;
case ACK_REPORT_P0:
case ACK_WIFI_CONFIG:
case ACK_SET_DEFAULT:
case ACK_NINABLE_MODE:
case ACK_REBOOT_MODULE:
gizProtocolWaitAckCheck(recvHead);
break;
case CMD_MCU_REBOOT:
gizProtocolCommonAck(recvHead);
// GIZWITS_LOG("report:MCU reboot!\n");
gizProtocolReboot();
break;
case CMD_ERROR_PACKAGE:
break;
case ACK_PRODUCTION_TEST:
gizProtocolWaitAckCheck(recvHead);
// GIZWITS_LOG("Ack PRODUCTION_MODE success \n");
break;
case ACK_GET_NTP:
gizProtocolWaitAckCheck(recvHead);
gizProtocolNTP(recvHead);
// GIZWITS_LOG("Ack GET_UTT success \n");
break;
case ACK_ASK_MODULE_INFO:
gizProtocolWaitAckCheck(recvHead);
gizProtocolModuleInfoHandle(recvHead);
// GIZWITS_LOG("Ack GET_Module success \n");
break;
#ifdef OTA_ENABLE
case ACK_BIGDATA_READY:
gizProtocolWaitAckCheck(recvHead);
break;
case ACK_D_STOP_BIGDATA_SEND:
gizProtocolWaitAckCheck(recvHead);
break;
case CMD_ASK_BIGDATA:
// GIZWITS_LOG("CMD_ASK_BIGDATA \n");
gizProtocolCommonAck(recvHead);
if(0 == Pro_W2D_UpdateCmdHandle((uint8_t *)gizwitsProtocol.protocolBuf + sizeof(protocolHead_t), protocolLen - sizeof(protocolCommon_t)))
{
romUpdate.otaBusyModeFlag = 1;
// GIZWITS_LOG("System In OTA Mode BusyFlag = %d \n", romUpdate.otaBusyModeFlag);
// //GIZWITS_LOG("CMD_ASK_BIGDATA\n");
}
else
{
// GIZWITS_LOG("Update Ask Handle Failed \n");
Pro_D2W_UpdateSuspend();
}
break;
case CMD_BIGDATA_SEND:
gizProtocolCommonAck(recvHead);
updatePieceResult = Pro_W2D_UpdateDataHandle((uint8_t *)gizwitsProtocol.protocolBuf + sizeof(protocolHead_t), protocolLen - sizeof(protocolCommon_t),HEX);
if(0 != updatePieceResult)
{
romUpdate.otaBusyModeFlag = 0;
// GIZWITS_LOG("CMD_BIGDATA_SEND , Piece Handle Faild . System OTA Mode Over BusyFlag = %d \n",romUpdate.otaBusyModeFlag);
Pro_D2W_UpdateSuspend();
// GIZWITS_LOG("System Go On \n");
}
break;
case CMD_S_STOP_BIGDATA_SEND:
gizProtocolCommonAck(recvHead);
romUpdate.otaBusyModeFlag = 0;
// GIZWITS_LOG("System OTA Mode Over BusyFlag = %d \n",romUpdate.otaBusyModeFlag);
break;
#endif
default:
gizProtocolErrorCmd(recvHead,ERROR_CMD);
// GIZWITS_LOG("ERR: cmd code error!\n");
break;
}
}
else if(-2 == ret)
{
//Check failed, report exception
recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf;
gizProtocolErrorCmd(recvHead,ERROR_ACK_SUM);
// GIZWITS_LOG("ERR: check sum error!\n");
return -2;
}
switch(gizwitsProtocol.issuedFlag)
{
case ACTION_CONTROL_TYPE:
gizwitsProtocol.issuedFlag = STATELESS_TYPE;
gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)&gizwitsProtocol.gizCurrentDataPoint, sizeof(dataPoint_t));
memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent,0x0,sizeof(gizwitsProtocol.issuedProcessEvent));
break;
case WIFI_STATUS_TYPE:
gizwitsProtocol.issuedFlag = STATELESS_TYPE;
gizwitsEventProcess(&gizwitsProtocol.wifiStatusEvent, (uint8_t *)&gizwitsProtocol.wifiStatusData, sizeof(moduleStatusInfo_t));
memset((uint8_t *)&gizwitsProtocol.wifiStatusEvent,0x0,sizeof(gizwitsProtocol.wifiStatusEvent));
break;
case ACTION_W2D_TRANSPARENT_TYPE:
gizwitsProtocol.issuedFlag = STATELESS_TYPE;
gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)gizwitsProtocol.transparentBuff, gizwitsProtocol.transparentLen);
break;
case GET_NTP_TYPE:
gizwitsProtocol.issuedFlag = STATELESS_TYPE;
gizwitsEventProcess(&gizwitsProtocol.NTPEvent, (uint8_t *)&gizwitsProtocol.TimeNTP, sizeof(protocolTime_t));
memset((uint8_t *)&gizwitsProtocol.NTPEvent,0x0,sizeof(gizwitsProtocol.NTPEvent));
break;
case GET_MODULEINFO_TYPE:
gizwitsProtocol.issuedFlag = STATELESS_TYPE;
gizwitsEventProcess(&gizwitsProtocol.moduleInfoEvent, (uint8_t *)&gizwitsProtocol.wifiModuleNews, sizeof(moduleInfo_t));
memset((uint8_t *)&gizwitsProtocol.moduleInfoEvent,0x0,sizeof(moduleInfo_t));
break;
default:
break;
}
#ifdef OTA_ENABLE
if (romUpdate.otaBusyModeFlag == 0)
{
gizDevReportPolicy(currentData);
}
#else
gizDevReportPolicy(currentData);
#endif
return 0;
}
具体源码
main. c
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "bsp_buzzer.h"
#include "bsp_dht11.h"
#include "BH1750FVI.h"
#include "voice.h"
#include "Key.h"
#include "led.h"
#include "OLED.h"
#include "Timer.h"
#include "usart.h"
#include "gizwits_product.h"
#define Refresh_Sensor_time400 //400ms刷新一次传感器数值
uint8_t jiemian;//0:主界面 1:阈值设置界面
uint8_t jiemian_change=1;//界面刚刚切换的时候,为1,以防一个界面,重复刷新同样的内容
uint8_t Set_Choose;//阈值设置选项 0:光照强度 1:空气湿度
DHT11_Data_TypeDef DHT11_Data;//DTH11读取到的参数
u16 BH1750_Data;//光照强度
u8 key_num;//读取到的键值
u8 DHT11_threshold=50;//湿度阈值
u16 BH1750_threshold=2500;//光照阈值
u16 Sensor_time=Refresh_Sensor_time;
u8 Weather_state;//天气状况,0:晴天,1:阴天,2:下雨
u8 led;//0:晾衣杆关闭 1:晾衣杆打开
void Show_OLED(void);//屏幕显示
void Show_ZJM(void);//显示主界面
void Show_Set(void);//显示阈值设置界面
void Show_Sensor(void);//显示传感器数值
void Show_threshold(void);//显示阈值
void Key_Handle(void);//按键处理
void Weather_Judge(void);//判断天气
int main(void)
{
delay_init();
//外设初始化
Timer2_Configuration();//定时刷新传感器数值
Timer_Init();//为机智云提供时钟
uart1_init(9600);
//模块初始化
Buzzer_Init();//蜂鸣器初始化
DHT11_Init();//DHT11初始化
BH1750_Init();//BH1750初始化
Key_Init();//按键初始化
OLED_Init();//oled初始化
voice_init();//语音模块初始化
LED_Init();//led初始化,模拟晾衣杆
lingsheng(3);//播报欢迎使用智能晾衣杆系统
OLED_ShowString(2,3,"initialing...");
for(int i=0;i<8;i++)
{
delay_ms(1000);
OLED_ShowNum(3,8,8-i,1);
}
OLED_Clear();
/*机智云初始化*/
userInit();
gizwitsInit();
/*一件配网模式*/
gizwitsSetMode(2);
while(1)
{
/*显示界面*/
Show_OLED();
/*按键处理*/
Key_Handle();
/*判断天气状况*/
Weather_Judge();
/*刷新网络参数更新到手机app*/
userHandle();
/*联网,上传数据,接收下发数据*/
gizwitsHandle((dataPoint_t *)¤tDataPoint);
}
}
void Key_Handle(void)//按键处理
{
key_num=Key_GetNum();
if(key_num==4&&jiemian==0)//切换到设置阈值界面
{
jiemian=1;
jiemian_change=1;
}
else if(key_num==4&&jiemian==1)//切换到主界面
{
jiemian=0;
jiemian_change=1;
}
else if(key_num==3&&jiemian==1)//阈值设置选项切换
{
Set_Choose=(Set_Choose==0)?1:0;
}
else if(key_num==2&&jiemian==1)//阈值减
{
if(Set_Choose==0)//光强 减50
{
BH1750_threshold-=50;
}
else //湿度 减1
{
DHT11_threshold-=1;
}
}
else if(key_num==1&&jiemian==1)//阈值加
{
if(Set_Choose==0)//光强 加50
{
BH1750_threshold+=50;
}
else //湿度 加1
{
DHT11_threshold+=1;
}
}
key_num=0;
}
void Show_OLED(void)//屏幕显示
{
if(jiemian==0&&jiemian_change==1)
{
Show_ZJM();
jiemian_change=0;
}
else if(jiemian==0&&jiemian_change==0)
{
Show_Sensor();
}
else if(jiemian==1&&jiemian_change==1)
{
Show_Set();
jiemian_change=0;
}
else if(jiemian==1&&jiemian_change==0)
{
Show_threshold();
}
}
//智(0)能(1)晾(2)衣(3)杆(4)光(5)照(6)强(7)度(8)空(9)气(10)
//湿(11)度(12)阈(13)值(14)设(15)置(16)天(17)气(18)状(19)况(20)
//正(21)异(22)常(23) 晴(24)阴(25)下(26)雨(27)←(28)
void Show_ZJM(void)
{
OLED_Clear();//清屏
//智能晾衣杆
OLED_ShowF16x16(1,4,0);
OLED_ShowF16x16(1,6,1);
OLED_ShowF16x16(1,8,2);
OLED_ShowF16x16(1,10,3);
OLED_ShowF16x16(1,12,4);
//光照强度:
OLED_ShowF16x16(2,1,5);
OLED_ShowF16x16(2,3,6);
OLED_ShowF16x16(2,5,7);
OLED_ShowF16x16(2,7,8);
OLED_ShowChar(2,9,':');
//空气湿度:
OLED_ShowF16x16(3,1,9);
OLED_ShowF16x16(3,3,10);
OLED_ShowF16x16(3,5,11);
OLED_ShowF16x16(3,7,12);
OLED_ShowChar(3,9,':');
//天气状况:
OLED_ShowF16x16(4,1,17);
OLED_ShowF16x16(4,3,18);
OLED_ShowF16x16(4,5,19);
OLED_ShowF16x16(4,7,20);
OLED_ShowChar(4,9,':');
}
void Show_Set(void)//显示阈值设置界面
{
OLED_Clear();//清屏
//阈值设置
OLED_ShowF16x16(1,4,13);
OLED_ShowF16x16(1,6,14);
OLED_ShowF16x16(1,8,15);
OLED_ShowF16x16(1,10,16);
//光照强度:
OLED_ShowF16x16(2,1,5);
OLED_ShowF16x16(2,3,6);
OLED_ShowF16x16(2,5,7);
OLED_ShowF16x16(2,7,8);
OLED_ShowChar(2,9,':');
//空气湿度:
OLED_ShowF16x16(3,1,9);
OLED_ShowF16x16(3,3,10);
OLED_ShowF16x16(3,5,11);
OLED_ShowF16x16(3,7,12);
OLED_ShowChar(3,9,':');
}
void Show_Sensor(void)
{
if(Sensor_time==0)
{
//关闭定时器2,防止影响时序(其实不关也没事)
TIM_SetCounter(TIM2,0);
TIM_Cmd(TIM2, DISABLE);
DHT11_Read_TempAndHumidity(&DHT11_Data);//读取温湿度
BH1750_Data=bh_data_read();//读取光照强度
TIM_Cmd(TIM2,ENABLE);//开启定时器2
Sensor_time=Refresh_Sensor_time;
}
if(jiemian==0)//如果在主界面
{
/*显示传感器数值*/
OLED_ShowNum(2,10,BH1750_Data,4);//光照强度
OLED_ShowNum(3,10,DHT11_Data.humi_int,4);//空气湿度,显示个整数部分即可
/*判断此时天气状况*/
if(Weather_state==0)//晴天
{
OLED_ShowF16x16(4,10,24);
OLED_ShowF16x16(4,12,17);
}
else if(Weather_state==1)//阴天
{
OLED_ShowF16x16(4,10,25);
OLED_ShowF16x16(4,12,17);
}
else//雨天
{
OLED_ShowF16x16(4,10,26);
OLED_ShowF16x16(4,12,27);
}
}
}
void Show_threshold(void)//显示阈值
{
if(Set_Choose==0)//光照强度
{
OLED_ShowF16x16(2,14,28);//←
OLED_ShowString(3,14," ");
}
else//空气湿度
{
OLED_ShowF16x16(3,14,28);//←
OLED_ShowString(2,14," ");
}
OLED_ShowNum(2,10,BH1750_threshold,4);//光照强度阈值
OLED_ShowNum(3,10,DHT11_threshold,4);//空气湿度阈值
}
void Weather_Judge(void)//判断天气
{
if(DHT11_Data.humi_int>DHT11_threshold)//下雨
{
Weather_state=2;
if(led==1)//关闭晾衣杆
{
led=0;
LED_TIP_OFF;
lingsheng(1);//下雨了,晾衣杆已关闭
}
}
else if(DHT11_Data.humi_int<DHT11_threshold&&BH1750_threshold<BH1750_Data)//晴天
{
Weather_state=0;
if(led==0)//打开晾衣杆
{
led=1;
LED_TIP_ON;
lingsheng(2);//大晴天,晾衣杆已打开
}
}
else
{
Weather_state=1;//阴天
}
}
总结
其实你只要学过一点stm32,以上资料完全够你手动复刻,去购买我硬件清单的对应模块,然后找到商家要驱动代码,移植到你的工程,然后调用相应的函数到我给你的main.c里面,关于网络配置这一块,读者需要自己去查阅机智云官方的指导书进行学习,不过其实这个项目将联网这几个函数删掉也完全可以,联网只是为了让这个项目高级那么一点罢了,只要看懂我这些,自己去找对应模块代码移植,这个项目就可以轻而易举的复刻出来了,希望我这篇文章可以帮助到你,如果需要完整的工程,可以私信我。
原文地址:https://blog.csdn.net/m0_74676415/article/details/143643001
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!