【本文正在参加2023年第一期优质创作者激励计划】
1.项目功能
本次项目采用腾讯物联网平台+微信小程序腾讯连连实现远程控制。本地采集温度数据和湿度数据,设置温湿度报警阈值,超过设定值即可通过蜂鸣器报警。微信小程序可远程控制开发板的硬件设备。OLED屏幕实时显示采集到的数据显示,采用两页显示方式,第一页显示实时时间,第二页显示环境温湿度数据,可通过按键切换。板子上电即可自动完成WIFI连接,在WIFI密码修改的情况下课实现手机一键配网,从而实现腾讯云平台接入。连接成功后屏幕界面默认显示当前实时时间。时间校准可现在网络校时或串口校时。
1.1 硬件模块
1.温湿度模块DHT11完成环境温湿度采集; 2.ESP8266 WIFI模块完成腾讯云平台接口; 3.0.96寸OLED屏幕显示实时数据信息; 4.按键实现界面切换(温湿度界面和时间显示界面切换); 5.LED灯配合微信小程序实现远程控制; 6.蜂鸣器报警提示;
1.2 效果展示
2.物联联网平台
物联网平台也被称为应用支撑平台或者智能管理平台。它是一个中间层,主要位于物联网设备层和物联网网关(和数据)层之间。采用的通讯协议为MQTT。 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大的优点在于可以以极少的代码和有限的带宽,为远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,MQTT在物联网、小型设备、移动应用等方面有广泛的应用。MQTT属于应用层协议。最新版本为MQTT v5.0标准。本次连接腾讯云物联网平台主要以MQTT标准协议3.1版本为主。 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件。
2.1 腾讯云平台配置
1.注册腾讯云账号,登陆云平台
- 搜索物联网平台,登录物联网平台。
2.创建项目
1.进入物联网控制台 2.创建项目 3.创建产品
3.创建产品功能
连接物理网平台的三个参数:设备名字、产品ID、设备秘钥
//设备名,产品ID,设备秘钥修改为自己所创建产品参数
#define DeviceName "Smart_123"//设备名
#define ProductID "LA57WL612"//产品ID
#define DeviceSceret "9JHiCQ5668uZlVDuQ2ZnQ=="//设备秘钥
4.创建工程,连接腾讯物联网平台
用户名和密钥生成:
//服务器IP:{PRODUCT_ID}.iotcloud.tencentdevices.com ---PRODUCT_ID对应产品ID
#define SERVER_IP "LA57WL612.iotcloud.tencentdevices.com"//服务器IP
#define SERVER_PORT 1883 //端口号
//客户端ID:{产品ID}{设备名}
#define ClientID "LA57WL612Smart_123"
//用户名和秘钥可使用秘钥生成工具完成
#define Username "LA57WL612Smart_123;12010126;R05S3;1621619622"
#define Password "9ebe0d0069ac4dd1e9e98664abc9f726c13b5a150190afdfa7b3c12240ff1e73;hmacsha256"//密文
//订阅主题:$thing/down/property/{ProductID}/{DeviceName} ---{ProductID}产品ID,{DeviceName}设备名
#define SET_TOPIC "$thing/down/property/LA57WL612/Smart_123"//订阅
5.主题订阅
//订阅主题:$thing/down/property/{ProductID}/{DeviceName} ---{ProductID}产品ID,{DeviceName}设备名
#define SET_TOPIC "$thing/down/property/LA57WL612/Smart_123"//订阅
//发布主题:$thing/up/property/{ProductID}/{DeviceName}
#define POST_TOPIC "$thing/up/property/LA57WL612/Smart_123"//发布
2.2 配置ESP8266WIFI
ESP8266是一款高性能的WIFI串口模块,内部集成MCU能实现单片机之间串口通信,是目前使用最广泛的一种WIFI模块之一。可以简单理解为一个WIFI转串口的设备,不用知道太多WIFI相关知识,只需要知道串口怎么使用就可以。 ESP8266 支持 softAP 模式,station 模式,softAP + station 共存模式三种。利用 ESP8266 可以实现十分灵活的组网方式和网络拓扑。(SoftAP:即无线接入点,是一个无线网络的中心节点。通常使用的无线路由器就是一个无线接入点。Station:即无线终端,是一个无线网络的终端端。) 本次采用模式为TCP+STA方式:
#define WIFI_NAME "wbyq"//WIFI名
#define WIFI_PASSWORD "asdfghjkl23"//wifi密码
char mqtt_message[200];//上报数据缓存区
int main()
{
int i=0;
u8 stat=0;
u32 time=0;
u16 cnt=0;
float temp;
Beep_Init();//蜂鸣器初始化
Led_Init();//LED初始化
Key_Init();//按键初始化
Usartx_Init(USART1,115200,72);
Usartx_Init(USART3,115200,36);
TIMx_Init(TIM2,72,20000);//通过定时器2辅助串口接收数据,20ms
TIMx_Init(TIM4,72,20000);//通过定时器2辅助串口接收数据,20ms
DS18B20_Init();
// RTC_Init();//RTC初始化
printf("初始化完成\r\n");
while(1)
{
stat=Esp8266_STA_TCPclinet_Init((u8 *)WIFI_NAME,(u8 *)WIFI_PASSWORD,(u8 *)SERVER_IP,SERVER_PORT);
if(stat==0)break;
Delay_Ms(500);
printf("stat=%d\r\n",stat);
}
printf("服务器连接成功\r\n");
while(1)
{
MQTT_Init();
stat=MQTT_Connect(ClientID,Username,Password);
if(stat==0)break;
Delay_Ms(500);
printf("正在连接....\r\n");
}
printf("连接成功\r\n");
stat=MQTT_SubscribeTopic(SET_TOPIC,0,1);
if(stat)printf("订阅失败\r\n");
else printf("订阅成功\r\n");
while(1)
{
if(usart3_flag)
{
for(i=0;i<usart3_cnt;i++)
{
printf("%c",usart3_rx_buff[i]);
}
usart3_cnt=0;
usart3_flag=0;
}
Delay_Ms(1);
time++;
cnt++;
if(time>=5000)
{
time=0;
MQTT_SentHeart();//发送心跳包
}
if(cnt>=1000)
{
cnt=0;
temp=DS18B20_GetTemp()*0.0625;
sprintf(mqtt_message,"{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"LED1\":1,\"temp\":%.2f,\"L\":356}}",temp);//温度
MQTT_PublishData(POST_TOPIC,mqtt_message,0);
}
}
}
2.3 设备上报数据格式
{
"method":"report",//上报设备属性
"clientToken":"123",//消息配对标识
"timestamp":1212121221, //可不填,默认为系统时间
"params":{
"power_switch":1, //设备属性power_switch
"color":1, //设备属性color
"brightness":32 //设备属性brightness
}
}
至此,云服务器创建成功,WIFI模式配置完成,云端接入成功。
3.无源蜂鸣器控制
无源蜂鸣器利用电磁感应现象,为音圈接入交变电流后形成的电磁铁与永磁铁相吸或相斥而推动振膜发声,接入直流电只能持续推动振膜而无法产生声音,只能在接通或断开时产生声音。通过2K~5k的方波信号实现驱动。 本次采用定时器3通道1实现无源蜂蜜器驱动。
/***********************************
**
**函数功能:定时器器PWM输出
**TIM3通道引脚:
** 没有重映射 部分重映射 完全重映射
** TIM3_CH1 PA6 PB4 PC6
** TIM3_CH2 PA7 PB5 PC7
**形参:
** chx --要开启的通道(1 --通道1,2--通道2, 3 --表示开启通道1和通道2)
** psc --预分频系数
** ar --重装载值(即周期时间)
** ccr --占空比
** 注意:本示例采用部分重映射功能
**作者:IT_阿水
************************************/
void TIM3_PWM_Out(u8 chx,u16 psc,u16 ar,u16 ccr)
{
/*1.开时钟*/
RCC->APB2PCLKEN|=1<<4;//PB
RCC->APB2PCLKEN|=1<<0;//AFIO
AFIO->RMP_CFG&=~(0x3<<10);
AFIO->RMP_CFG|=0X3<<10;//完全重映像
/*2.配置GPIO*/
GPIOC->PL_CFG&=0xF0FFFFFF;
GPIOC->PL_CFG |=0x0B000000;//通用复用推挽输出模式
/*3.定时器配置*/
RCC->APB1PCLKEN|=1<<1;//TIM3
RCC->APB1PRST|=1<<1;//开启复位时钟
RCC->APB1PRST&=~(1<<1);//取消复位
TIM3->CTRL1|=1<<7;
TIM3->PSC=psc-1;//预分频
TIM3->AR=ar;//重装载值
/*输出PWM配置*/
if(chx&0x1)
{
TIM3->CCMOD1&=~(0x3<<0);//输出
TIM3->CCMOD1|=1<<2;//快速使能
TIM3->CCMOD1|=1<<3;//预加载
TIM3->CCMOD1|=0x6<<4;//PWM0
TIM3->CCDAT1=ccr;//占空比,有效电平时间
TIM3->CCEN|=1<<0;//开启CH1
}
if(chx&1<<1)//CH2
{
TIM3->CCMOD1&=~(0x3<<8);//输出
TIM3->CCMOD1|=1<<10;//快速使能
TIM3->CCMOD1|=1<<11;//预加载
TIM3->CCMOD1|=0x6<<12;//PWM0
TIM3->CCDAT2=ccr;//占空比,有效电平时间
TIM3->CCEN|=1<<4;//开启CH2
}
TIM3->CTRL1|=1<<0;//开启定时器
}
4.DTH11温湿度传感器
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。
//从DHT11读取一次数据
//temp:温度值-20~60℃
//humi:湿度值5~95%RH
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5]={0};
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];
*humi=buf[1];
*temp++=buf[2];
*temp=buf[3];
}
}else return 1;
return 0;
}
5.RTC电子钟
RTC,英文全称:Real-time clock,中文名称:实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。实时时钟芯片是日常生活中应用最为广泛的消费类电子产品之一。它为人们提供精确的实时时间,或者为电子系统提供精确的时间基准,目前实时时钟芯片大多采用精度较高的晶体振荡器作为时钟源。 本次采用的是芯片自带电子钟,配置好后直接即可读取时间信息,非常方便。
/*读取RTC时间和日期*/
void RTC_GetDate(RTC_TIME *RTC_Time)
{
u32 date=RTC->DATE;
u32 tsh=RTC->TSH;
RTC_Time->year=((date>>20)&0xf)*10+ ((date>>16)&0xf);
RTC_Time->mon=((date>>12)&0x1)*10+ ((date>>8)&0xf);
RTC_Time->day=((date>>4)&0x3)*10+(date&0xf);
RTC_Time->week=((date>>13)&0x7);
//时间,注意,+-优先级 高于 &的优先级
RTC_Time->hour=((tsh>>20)&0x3)*10+((tsh>>16)&0xf);
RTC_Time->min=((tsh>>12)&0x7)*10+((tsh>>8)&0xf);
RTC_Time->sec=((tsh>>4)&0x7)*10+(tsh&0xf);
// printf("%d/%d/%d -- %d:%d:%d \r\n",RTC_Time->year,RTC_Time->mon,RTC_Time->day, \
RTC_Time->hour,RTC_Time->min,RTC_Time->sec);
}
附件链接:https://ost.51cto.com/resource/2567
本文作者:IT_阿水