基于华为云IoT设计的智能门锁丨【我的华为云体验之旅】

DS小龙哥 发表于 2021/12/15 19:11:44 2021/12/15
【摘要】 近几年物联网发展非常迅猛、周边各种设备都已经接入互联网,远程集成控制。例如: 智慧交通、森林防火、智慧小区、智慧停车场、智慧牧业、智慧农业等等。为了降低用户的成本、门槛,各大厂商平台也都开发了自己的物联网IOT云平台,方便用户接入快速搭建自己的应用场景。这篇文章就介绍如何使用华为物联网云平台实现智能锁的应用场景构建,硬件采用STM32F103ZET6 + ESP8266+步进电机实现。

1. 前言

近几年物联网发展非常迅猛、周边各种设备都已经接入互联网,远程集成控制。例如: 智慧交通、森林防火、智慧小区、智慧停车场、智慧牧业、智慧农业等等。为了降低用户的成本、门槛,各大厂商平台也都开发了自己的物联网IOT云平台,方便用户接入快速搭建自己的应用场景。

2. 设备硬件与功能介绍

这篇文章就介绍如何使用华为物联网云平台实现智能锁的应用场景构建,硬件采用STM32F103ZET6 + ESP8266+步进电机实现。在华为云IOT物联网平台构建智能锁项目,配置好云端,设备端通过ESP8266连接华为物联网平台,实现数据上报,交互,实现远程开锁、关锁、获取锁的状态等功能,不用担心忘记出门关锁,也不用担心忘记带钥匙无法开门的情况。

ESP8266是物联网解决方案里比较热门的WIFI设备,支持串口+AT指令控制,任意支持串口的单片机都可以使用ESP8266快速实现联网。

image-20211215173859997

步进电机采用常规28BYJ-48来模拟当做门锁的电机,驱动板采用ULN2003。

image-20211215173730289

3. 创建云端设备

登录官网: https://www.huaweicloud.com/

直接搜索物联网,打开页面。

image-20211215174453102

选择设备接入:

image-20211215174521654

选择免费试用:

image-20211215174550243

在产品页面,点击右上角创建产品:

image-20211215174642960

填上产品信息:

image-20211215174937965

得到产品ID,保存好ID,点击查看详情:

产品ID为:61b9ba3a2b2aa20288c1e7f1.

image-20211215175007908

点击设备页面,注册设备:

image-20211215175814693

填充信息进行注册:

image-20211215180006268

保存设备密匙和设备ID,点击保存关闭会自动下载文件保存,后面生成密码和登录账号需要使用

image-20211215180041077

关闭后就看到创建好的设备了:

image-20211215180732602

点击产品页面,选择刚才创建的产品:

image-20211215180939201

选择自定义模型—创建数据模型服务:

image-20211215181036122

image-20211215181144359

选择新增属性,创建设备的属性

image-20211215181424235

4. 创建MQTT登录账号和密匙

设备创建完成接来下生成MQTT登录账号、密匙,方便设备登录云端平台。

官网工具地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

image-20211215181625067

打开刚才创建设备时,下载的密匙文件,把内容复制出来对应的填进去,生成即可。

image-20211215181747129

5. 拼接主题订阅与发布的格式

官方文档介绍: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html

image-20211215182442581

在产品页面可以,看到主题的全部格式:

image-20211215183137006

总结的格式如下:

格式: $oc/devices/{device_id}/sys/messages/down
//订阅主题: 平台下发消息给设备
$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down


格式: $oc/devices/{device_id}/sys/properties/report
//设备上报数据
$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report

上属性的数据格式:
//上报的属性消息 (一次可以上报多个属性,在json里增加就行了)
{"services": [{"service_id": "lock","properties":{"门锁":1}}]}

上面属性里的服务ID和属性里的名称,在设备页面,影子设备页面查看。

image-20211215184220051

6. MQTT客户端模拟设备登录云端

下面使用MQTT客户端模拟设备登录服务器测试,看设备创建的是否OK。

服务器的IP地址是: 121.36.42.100

端口号是: 1883

打开MQTT客户端软件,按照提示,输入相关参数后,点击连接,然后再点击订阅主题,发布主题即可:

image-20211215184435114

查看云端服务器的情况: 可以看到设备已经在线了,并且收到上传的数据。

image-20211215184612394

修改一下锁的状态,上报属性再查看:

image-20211215184712687

发现云端的状态也已经改变,现在设备上报已经OK。

image-20211215184735239

接下来测试命令下发,实现远程开锁关锁的功能:

打开产品页面,新增加命令:

image-20211215185156127

image-20211215185232075

image-20211215185302157

命令添加成功:

image-20211215185325872

在设备页面,选择同步命令下发:

image-20211215185445720

image-20211215185523035

点击确定后,查看MQTT客户端,发现已经收到数据了:

image-20211215185612755

$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497/sys/commands/request_id=88e2626f-290d-405e-962d-51554445a8fd{"paras":{"lock":1},"service_id":"lock","command_name":"lock"}

设备端解析收到的数据,就可以完成多步进电机的控制,完成开锁关锁。

7. STM32+ESP8266连接云端

2021-12-16_095526

image-20211215190612026

工程是keil5工程,代码非常多,下面只贴出了main函数里的模型代码。如需要完整的代码,在下面评论区留言。

main函数代码如下:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include "bluetooth.h"
#include "esp8266.h"
#include "mqtt.h"

//华为物联网服务器的设备信息
#define MQTT_ClientID "61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510"
#define MQTT_UserName "61b9ba3a2b2aa20288c1e7f1_QQ1126626497"
#define MQTT_PassWord "385ce91dfe7da5b7431868d5d87e7998163c493344040935d5a00024d6324242"

//订阅与发布的主题
#define SET_TOPIC  "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down"  //订阅
#define POST_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report"  //发布

char mqtt_message[200];//上报数据缓存区

int main()
{
   u32 time_cnt=0;
   u32 i;
   u8 key;
   LED_Init();
   BEEP_Init();
   KEY_Init();
   USART1_Init(115200);
   TIMER1_Init(72,20000); //超时时间20ms
   USART2_Init(9600);//串口-蓝牙
   TIMER2_Init(72,20000); //超时时间20ms
   USART3_Init(115200);//串口-WIFI
   TIMER3_Init(72,20000); //超时时间20ms
   USART1_Printf("正在初始化WIFI请稍等.\n");
   if(ESP8266_Init())
   {
      USART1_Printf("ESP8266硬件检测错误.\n");  
   }
   else
   {
      //非加密端口
      USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("CMCC-Cqvn","99pu58cb","121.36.42.100",1883,1));
  
   }
   
    //2. MQTT协议初始化	
    MQTT_Init(); 
    //3. 连接华为服务器        
    while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord))
    {
        USART1_Printf("服务器连接失败,正在重试...\n");
        delay_ms(500);
    }
    USART1_Printf("服务器连接成功.\n");
    
    //3. 订阅主题
    if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
    {
        USART1_Printf("主题订阅失败.\n");
    }
    else
    {
        USART1_Printf("主题订阅成功.\n");
    }        
    
    while(1)
    {    
        key=KEY_Scan(0);
        
        //这里通过按下按键实现开始和关锁,并且向云端服务器更新状态,同步
        if(key==2)
        {
            time_cnt=0;
            sprintf(mqtt_message,"{\"services\": [{\"service_id\": \"lock\",\"properties\":{\"门锁\":1}}]}");
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            USART1_Printf("发送状态1\r\n");
        }
        else if(key==3)
        {
            time_cnt=0;
            sprintf(mqtt_message,"{\"services\": [{\"service_id\": \"lock\",\"properties\":{\"门锁\":0}}]}");
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            USART1_Printf("发送状态0\r\n");
        }  

        if(USART3_RX_FLAG)
        {
            USART3_RX_BUFFER[USART3_RX_CNT]='\0';
            for(i=0;i<USART3_RX_CNT;i++)
            {
                USART1_Printf("%c",USART3_RX_BUFFER[i]);
            }
            
            //在这里编写解析华为云端下发的命令,完成开锁关锁
            //...................
            
            USART3_RX_CNT=0;
            USART3_RX_FLAG=0;
        }

        //定时发送心跳包,保持连接
        delay_ms(10);
        time_cnt++;
        if(time_cnt==500)
        {
            MQTT_SentHeart();//发送心跳包
            time_cnt=0;
        }
    }
}

步进电机代码: 模拟门锁

#include "motor.h"

#define uint unsigned int
	
//步进电机正反转数组1
uint16_t phasecw[4] ={0x0200,0x0100,0x0080,0x0040};// D-C-B-A   
uint16_t phaseccw[4]={0x0040,0x0080,0x0100,0x0200};// A-B-C-D.


void Delay_xms(u32 x)
{
 uint i,j;
 for(i=0;i<x;i++)
  for(j=0;j<112;j++);
}

void MotorStop(void)  
{  
    MOTOR_1=0;
    MOTOR_2=0;
    MOTOR_3=0;
    MOTOR_4=0;
}

void Moto_Init(void)
{
    RCC->APB2ENR|=1<<4;
    GPIOC->CRL&=0x00FFFFFF;
    GPIOC->CRL|=0x33000000;
    GPIOC->CRH&=0xFFFFFF00;
    GPIOC->CRH|=0x00000033;
	
// IN4: PC9   d
// IN3: PC8   c
// IN2: PC7   b
// IN1: PC6   a
}

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
{
  GPIOx->ODR = PortVal;
}


void Motorcw(int speed)  //一个脉冲
{  
    uint8_t i;  
  
    for(i=0;i<4;i++)  
    {  
        GPIO_Write(GPIOC,phasecw[i]);  
        ;  
    }
	
}


void Motorccw(int speed)  
{  
    uint8_t i;  
    for(i=0;i<4;i++)  
    {  
        GPIO_Write(GPIOC,phaseccw[i]);  
        Delay_xms(speed);  
    } 

}


//由于   *一个脉冲*   *输出轴*  转0.08789度(电机实转0.08789*64=5.625度),即步进角为5.625度。则转完A-B-C-D为  *8个脉冲*  
//,即0.08789*8=0.70312度。若称A-B-C-D为一个周期,则j为需要的转完angle角度所需的周期数。
//步进电机正转角度函数
void Motorcw_angle(int angle,int speed)
{
	int i,j;
	j=(int)(angle/0.70312);
	for(i=0;i<j;i++)
	{
		Motorcw(speed);
	}
	MotorStop();
}



//步进电机反转角度函数
void Motorccw_angle(int angle,int speed)
{
	int i,j;
	j=(int)(angle/0.70312);
	for(i=0;i<j;i++)
	{
		Motorccw(speed);
	}
	MotorStop();
}


//步进电机反转圈函数
void Motorccw_ring(int ring ,int speed)
{
	int i;
	for(i=0;i<ring;i++)
	{
	Motorccw_angle(360,speed);
	}
	
}

//步进电机正转圈函数
void Motorcw_ring(int ring,int speed) //步进电机正转角度函数
{
	
	int i;
	for(i=0;i<ring;i++)
	{
        Motorcw_angle(360,speed);
	}
}

【我的华为云体验之旅】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/306271

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。