• STM32实战项目——WIFI远程开关灯



    🎀 文章作者:二土电子

    🌸 关注文末公众号获取其他资料和工程文件!

    🐸 期待大家一起学习交流!


    前言
    其实WIFI开关灯在几个月前就想做了,但是对于没有云平台调试经验的我,一开始有些摸不着头脑,所以就搁置了。十一假期与老同学聊天时了解到他也在做一个远程开关灯的小项目,所以就重新开始了WIFI远程开关灯的小项目。

    本文使用到的AT固件,固件烧录工具,烧录方法以及调试上位机,全部在文末公众号中,关注并私信“ESP8266资料”,可以免费获取!

    本文设计的PCB工程文件可以关注文末公众号,私信“远程开关灯PCB”获取!

    一、项目简介

    本项目使用STM32F103C8T6作为主控芯片,搭配ESP8266,通过WIFI连接腾讯云来实现远程开关灯。腾讯云有自带的APP“腾讯连连”,但是目前苹果用户不能下载,不过他也有配套的小程序,十分友好。开关灯的功能由sg90舵机来实现。

    目前只完成了第一版的软件开发,将功能分成了两种,一种是只需要关灯,也就是收到云平台的指令,就关灯,开灯需要手动。另一种就是既可以远程关灯,也可以远程开灯。之所以分成两种功能,是因为博主的需求只是能够睡前关灯,不再摸黑找床就够了!

    二、硬件选型

    • 主控芯片:STM32F103C8T6
    • ESP8266:暂时使用的是正点原子的ESP8266,由于价格相对不太美丽,后续可能会更换。
    • 舵机:sg90

    对于ESP8266和sg90不甚了解的小伙伴不要慌,可以移步博主的“STM32外设系列专栏”查看!

    三、连接腾讯云测试

    其实上云的方法,除了需要了解掌握云平台的配置方法,其他与STM32外设专栏中介绍的,利用WIFI模块访问API并无太大的差别。在上云之前,我们需要先做好前期准备。

    3.1 AT固件烧录

    安可信提供了可连接腾讯云的AT固件,下载链接在评论区贴出!有需要资料的小伙伴可以直接关注文末公众号,私信发送“ESP8266资料”,获取本文全部资料。

    直连腾讯云AT固件
    获取到固件后,下一步就是使用固件烧录工具将固件烧录到我们的ESP8266中。这里需要用的USB转TTL,固件烧录工具以及烧录方法全部打包在公众号资料中,这里暂时不在做介绍。

    值得注意的是,我们在给正点原子的ESP8266模组烧录固件时,需要注意一下接线方式,这里说明一下

    ESP8266			USB-TTL
    
    VCC		-----	5V
    GND		-----	GND
    TXD		-----	RXD
    RXD		-----	TXD
    IO_0	-----	GND
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在烧录完固件后,再将IO_0置空,重新上电即可。

    3.2 云平台配置

    首先进入腾讯云平台,连接放在评论区。注册账号后进入到“实例管理”。

    进入腾讯云

    这里因为已经创建过,所以和最开始使用的小伙伴显示的有所不同,但是不影响介绍配置步骤。

    3.2.1 新建产品

    点击进入公共实例,点击“新建项目”,输入相关信息。

    新建项目

    新建完项目后,点击进入新建的项目,然后点击“新建产品”,按照下图选择并输入相关信息。

    新建产品

    3.2.2 配置产品

    首先是“物模型”,我们是需要实现开关灯,这里我们只配置一个简单的属性。点击“新建自定义功能”,按照下图配置并输入相关信息。

    新增自定义功能

    添加完成后点击下一步,进入“设备开发”,选择“基于模组开发”。

    设备开发

    选择模组时选择下面的模组

    选择模组

    点击下一步之后,进入“交互开发”。除了下图的“配网引导”需要按照下图选择,其他的可自行配置。

    配网引导

    配置完成后,来到“设备调试”,新建完设备后,云平台部分就配置完成。新建完设备后点击产品,进入后可以看到设备信息。设备信息中的“设备名称”、“产品ID”、“设备密钥”在后续会使用到。

    设备信息

    3.3 上位机调试

    上位机使用公众号资料中提供的上位机。用USB转TTL连接上ESP8266,打开上位机,`打开对应串口。输入上面的设备信息。

    上位机

    点击“直接连接WIFI”,输入要连接的WIFI名称和WIFI密码。等待连接上WIFI后,点击连接腾讯云。此时可以去云平台的设备调试中看一下设备是否处于在线状态。设备在线后,需要订阅主题,订阅主题时需要输入

    $thing/down/property/产品ID/设备名称
    
    • 1

    订阅完成后就可以在云平台进行控制。点击云平台上在线调试中的“发送”,串口就可以收到服务器发送的消息。
    上位机

    四、所需AT指令

    上面介绍了如何利用上位机来实现上云,并且收到云平台发送的指令。我们可以看到,实际上位机也是使用发送AT指令的方式实现的,所以我们在利用单片机+ESP8266上云时,模仿上位机去发送这些AT指令,一样可以上云。这里按发送顺序列举一下需要用到的几条AT指令。

    AT+CWJAP="WIFINAME","WIFIPASSWORD"   // 连接指定WIFI
    
    AT+TCDEVINFOSET=1,"PRODUCTID","DEVICENAME","DEVICEKEY"   // 发送设备信息
    
    AT+TCMQTTCONN=1,5000,240,1,0   // 配置MQTT参数
    
    AT+TCMQTTSUB="$thing/down/property/PRODUCTID/DEVICENAME",0   // 订阅主题
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    需要注意的是,每条AT指令后面都需要加换行和回车!

    五、程序编写

    5.1 ESP8266发送指令程序

    发送指令程序如下

    /*
     *==============================================================================
     *函数名称:Med_Esp8266_CheckLink
     *函数功能:检查ESP8266连接状态
     *输入参数:str:要发送的指令;
     *返回值:无
     *备  注:调用前先将需要发送的内容利用sprintf()函数转换成字符串
    					串口1发送指令,串口2返回信息
     *==============================================================================
     */
    void Med_Esp8266_SendCmd (u8 *str)
    {
    	while (!gSetSuccessFlag)
    	{
    		// 发送AT指令
    		USART_Send(UART1,str);
    		
    		// 这里延时4s,防止出现虚假上云现象
    		delay_ms(1000);
    		delay_ms(1000);
    		delay_ms(1000);
    		delay_ms(1000);
    		
    		gSendCunt = gSendCunt + 1;   // 发送次数加1
    		
    		// 检测接收内容
    		Med_Esp8266_Uartrece_Pares();
    		
    		if (gSendCunt > 10)
    		{
    			// 发送失败
    		}
    	}
    	
    	gSendCunt = 0;   // 清零发送次数
    	gSetSuccessFlag = 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    其实实质是利用串口1,将需要发送的字符串发送出去。关于串口发送程序,可以到“STM32速成笔记”专栏查看,这里就不再做详细介绍了。

    发送AT指令的完整程序如下

    /*
     *==============================================================================
     *函数名称:App_Esp8266_Init
     *函数功能:ESP8266初始化
     *输入参数:无
     *返回值:无
     *备  注:检测ESP8266连接状态,并连接指定WIFI
     *==============================================================================
     */
    void App_Esp8266_Init (void)
    {
    	// 连接指定WIFI
    	sprintf((char*)gString,"AT+CWJAP=\"%s\",\"%s\"\r\n",WIFINAME,WIFIPASSWORD);
    	Med_Esp8266_SendCmd(gString);
    }
    /*
     *==============================================================================
     *函数名称:App_Esp8266_Connect_Tencentcloud
     *函数功能:连接腾讯云
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void App_Esp8266_Connect_Tencentcloud (void)
    {
    	// 设置平台设备信息
    	sprintf((char*)gString,"AT+TCDEVINFOSET=1,\"%s\",\"%s\",\"%s\"\r\n",PRODUCTID,DEVICENAME,DEVICEKEY);
    	Med_Esp8266_SendCmd(gString);
    	
    	// 配置MQTT连接参数
    	sprintf((char*)gString,"AT+TCMQTTCONN=1,5000,240,1,0\r\n");
    	Med_Esp8266_SendCmd(gString);
    	
    	// 订阅MQTT主题信息
    	sprintf((char*)gString,"AT+TCMQTTSUB=\"$thing/down/property/%s/%s\",0\r\n",PRODUCTID,DEVICENAME);
    	Med_Esp8266_SendCmd(gString);
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    5.2 接收云平台信息

    其实针对云平台信息的接收很简单,是否收到云平台消息的标准是,接收到的字符串中是否有关键词“led”。接收判断程序如下

    /*
     *==============================================================================
     *函数名称:Med_SG90_Uartrece_Pares
     *函数功能:解析串口接收内容
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void Med_SG90_Uartrece_Pares (void)   // 串口接收内容解析函数
    {
    	u16 tempVar = 0;   // 临时循环变量
    	
    	if (gReceEndFlag  == 1)   // 如果接收完成
    	{
    		// 解析接收内容
    		for (tempVar = 0;tempVar < gReceCount;tempVar ++)
    		{	
    			// 腾讯云下发消息解析
    			if (gReceFifo[tempVar] == 'l' && gReceFifo[tempVar + 1] == 'e' && gReceFifo[tempVar + 2] == 'd')
    			{
    				// 解析开关灯指令
    				gRecCloudOrder = 1;
    				break;
    			}
    		}
    		
    		// 清空接收数组
    		for (gClearCount = 0;gClearCount < gReceCount;gClearCount ++)
    		{
    			gReceFifo[gClearCount] = ' ';
    		}
    			
    		gReceEndFlag = 0;   // 清除接收完成标志位
    		gReceCount = 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    关于如何解析接收字符串,如果看上面的程序还是不理解,可以到“STM32外设系列”专栏中WIFI篇查看。或者到“STM32实战项目”专栏中密码锁篇查看。

    5.3 舵机控制

    舵机使用TIM2的PWM通道2来控制,关于sg90的详细控制资料,可以到“STM32外设系列”专栏查看,程序工程可关注文末公众号私信获取。

    这里定义了一个函数,可以控制舵机旋转到指定角度。

    /*
     *==============================================================================
     *函数名称:Med_Sg90_Spin
     *函数功能:SG90旋转到指定角度
     *输入参数:angle:旋转到的指定角度
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void Med_Sg90_Spin (u16 angle)
    {
    	TIM_SetCompare2(TIM2,195 - angle / 9);   // 旋转到指定角度
    	delay_ms(500);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    上面介绍了,项目有两种不同的功能,可以利用宏定义开关。舵机根据宏定义开关的不同,可以实现不同的功能。舵机开关灯程序如下

    // 以下变量在其头文件中进行了全局声明
    u8 gRecCloudOrder = 0;   // 收到云平台指令标志位
    
    /*
     *==============================================================================
     *函数名称:App_Sg90_LedCtrl
     *函数功能:SG90开关灯
     *输入参数:无
     *返回值:无
     *备  注:根据需求选择宏定义开关
     *==============================================================================
     */
    #if CLOSE_AND_OPEN
    u8 gOpenCloseCtrlFlag = 0;   // 开关控制标志位
    #endif
    
    void App_Sg90_LedCtrl (void)
    {
    	Med_SG90_Uartrece_Pares();   // 接收串口内容并解析
    	
    	#if ONLY_CLOSE
    		if (gRecCloudOrder == 1)
    		{
    			Med_Sg90_Spin(CLOSEANGLE);   // 舵机旋转关灯
    			delay_ms(500);
    			Med_Sg90_Spin(99);   // 舵机归零
    			delay_ms(500);
    			gRecCloudOrder = 0;
    		}
    	#elif CLOSE_AND_OPEN
    		if (gRecCloudOrder == 1)
    		{
    			gOpenCloseCtrlFlag = gOpenCloseCtrlFlag + 1;
    			
    			// 范围限制
    			if (gOpenCloseCtrlFlag >= 3)
    			{
    				gOpenCloseCtrlFlag = 1;
    			}
    		}
    		if (gRecCloudOrder == 1 && gOpenCloseCtrlFlag == 1)
    		{
    			Med_Sg90_Spin(CLOSEANGLE);   // 舵机旋转关灯
    			delay_ms(500);
    			Med_Sg90_Spin(99);   // 舵机归零
    			delay_ms(500);
    			gRecCloudOrder = 0;
    		}
    		else if (gRecCloudOrder == 1 && gOpenCloseCtrlFlag == 2)
    		{
    			Med_Sg90_Spin(OPENANGLE);   // 舵机旋转开灯
    			delay_ms(500);
    			Med_Sg90_Spin(99);   // 舵机归零
    			delay_ms(500);
    			gRecCloudOrder = 0;
    		}
    	#endif
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    六、PCB设计

    本项目的第一版PCB已经设计完成,如有需要,可关注文末公众号,私信“远程开关灯PCB”获取,这里贴一下PCB的3D预览图。

    PCB的3D预览图

    七、优化方向

    • 未加入ESP8266连接异常检测程序。
    • 如果需要修改连接的WIFI,需要重新烧写程序。可以尝试使用HC-05来输入要连接的WIFI信息,如果小伙伴有其他好的办法,欢迎私信讨论或者评论区讨论。
    • PCB没有加入电源部分电路,后续考虑使用电池供电。
  • 相关阅读:
    [游戏设计心法]4-如何让玩家投入
    RocketMQ 数据持久化、高可用、高性能、读写原理、扩容总结
    Web3究竟红在哪里,它的出现能为人类社会带来什么?
    Gem5 for Ubuntu20.04
    排序算法详解
    软考高级架构师下篇-17安全架构设计理论与实践
    K8s:部署 CNI 网络组件+k8s 多master集群部署+负载均衡及Dashboard k8s仪表盘图像化展示管理
    Java大厂面试题第2季
    matplotlib你真的明白plt,fig和ax吗
    【AI视野·今日CV 计算机视觉论文速览 第255期】Wed, 27 Sep 2023
  • 原文地址:https://blog.csdn.net/qq_45217381/article/details/133696273