基于esp8266的远程开关控制系统(SOC方案实现远程测控系统)
实现功能:
1.控制一个大功率LED灯和一个继电器
2.控制RGB灯珠,实现颜色调节
3.实时获取温湿度(DHT11)
4.一个按键短按控制大功率LED灯珠亮和灭(同时上报状态),长按实现SOFTAP模式;一个按键控制继电器的开和关(同时上报状态),长按实现AIRLINK模式。
硬件准备:
1.ESP12F(32Mbit)一个
2.DHT11一个
3.RGB_LED一个(由于是3V共阴,所以暂时不加限流电阻)
4.电容电阻排针若干(参考电路图)
5.微动开关3个(复位,继电器,LED灯控制)
6.万用板一块
7. 5V继电器一个(可以用模块。也可以直接搭建继电器电路)
8.3.3V稳压一个1117
GPIO接线对应
GPIO12----RGB_LED红
GPIO13----RGB_LED绿
GPIO14----RGB_LED蓝
制作教程:
首先进入开发者中心:https://dev.gizwits.com/zh-cn/developer/进行账号的注册和登陆。认证之类的自己按照实际情况去认证。此处不在详述,不会可以加Q问我:1083791810tencent://message/?uin=1083791810&Site=fdfdf&Menu=yes
登陆认证过后进入个人项目或者公司项目,都是一样的,看你认证的是个人还是公司。在公司下面创建产品以后就只能在公司目录下浏览产品信息。
教程从这儿开始,首先点击右上角创建新产品。
按照如图所示设置好产品参数,产品分类随便选相应的就行,乱选不会影响产品;产品名称就是给产品取个名字,可以是中文和英文,此处为了教学,我就写一个远程测控;技术方案选择wifi/移动网络方案;通讯方式选择wifi(此处因为是soc方案,所以直接用wifi);数据传输方式选择定长(定长就是把所有数据点一次全部传输,变长就是只传输变化那部分,个人建议在数据点不多的情况下最好选用定长,在数据点很多的时候才考虑变长),按照如图设置好之后直接点击保存。就完成了产品的创建,会自动跳转到产品页面。
接下来我们需要给产品添加数据点,数据点是网络传输的标识,同一个产品中每个数据点标识名都必须是唯一的,比如有多个开关,每个开关都必须给予唯一的标识名,而且标识名必须是英文,数字,或者2个的组合。数据点需要设置三个参数,标识名,读写类型,数据类型,按照下图1 2操作可以增加数据点
关于三个参数按照以下规定:(对于不理解数据点的可以加QQ问我,先阅读看不懂再问)
标识名:
用于应用层传输,客户端或业务云开发时需要使用。命名规则遵循标准的开发语言变量名命名规范,支持英文字母、数字和下划线,以英文字母开头。
读写类型:(比如一个继电器的开关量需要在APP上进行开关操作,就设置可写,不需在APP上操作就只读,设置只读之后APP就只能观察状态而不能控制,温度湿度就是只读的,判断温湿度是否不在规定值就是报警,判断DHT11是不是正常接线就是故障)
① 只读:表示该数据点非控制,数据只支持从设备上报。
② 可写:表示该数据点可控制。设备端可上报该数据点数据;云端/客户端可对该数据点数据做出下发控制。
③ 报警:表示该数据点非控制,数据只支持从设备上报,数据类型需为布尔值。
④ 故障:表示该数据点非控制,数据只支持从设备上报,数据类型需为布尔值。云端会对设备上报的该数据点做统计,可在“运行状态”查看。
数据类型:(比如继电器的开关,就是布尔值,温湿度就是数值)
① 布尔值:表示两个状态:0,或1。如开关状态等,建议使用布尔数据类型。例如打开关闭继电器,打开关闭大功率LED。
② 枚举类型:可定义一个有限的取值集合。当定义的某个功能(元器件)有固定的若干个值。例如设置RGB为关闭,自定义组合,红色,绿色,蓝色,黄色,紫色,粉色,白色。
③ 数值:填写数值范围,数值可为负数/小数,机智云自动将数值转换为正数。例如温湿度,RGB色度调节控制等。
④ 扩展:填写数据长度,数据内容由用户自定义。对于上述功能点无法满足的复杂功能可采用。机智云不建议使用此类型数据,设备上报该数据点的数据,机智云无法识别。
根据以上内容,我们开始创建数据点,首先建立大功率LED的数据点,此处我们就用switch_led表示,由于要在APP操作其开关,就选择可写,开关量直接用布尔值。备注没有作用的,可以写了防止遗忘。
设置好参数之后点击确定,然后按照如图箭头所示可以编辑这个数据点,为什么要进行编辑,因为我们希望在APP上看到他是中文的方式显示而不是数据点名称显示。
点击编辑之后标识名不用改,改显示名称,数据点创建错了也可以在这儿进行调整修改。此处我修改成电灯。
修改好之后点击确定。同样的方法创建继电器的数据点,标识名switch_relay,显示为插座,可写,创建好之后如下图
接着我们创建一个颜色控制的枚举可控数据点,用来快速控制RGB灯的颜色。枚举范围一定要是英文输入下的逗号。数据点标识名为color_controls,可写,枚举,枚举范围:关闭,自定义,红色,绿色,蓝色,黄色,紫色,粉色,白色,显示名称:RGB控制
接下来创建3个RGB自由调节的可写数值数据点:标识名分别为:LED_R,LED_G,LED_B,可写,数据类型:数值,数据范围0-254,分别率为1. 显示名称红色(R)l绿色(G)蓝色(B),创建好之后如图所示。
接下来温湿度显示,范围就取正常的DHT11可控范围。温度范围0-50.湿度0-100,设置好后如下图所示,创建完之后点击最上面的应用
显示名称:温度(℃)标识名:temperature读写类型:只读 数据类型:数值 数据范围:0 – 50 分辨率:1增量:0备注: DHT11测量温度
显示名称:湿度(%) 标识名:humidity 读写类型:只读 数据类型:数值 数据范围:0 - 100分辨率:1增量:0备注: DHT11测量湿度
关于对分别率和精度的理解可以参考这段说明,在定义数值型数据点的时候,取值范围可以使用包括小数、负数等非uint类型数值,熟悉嵌入式开发的开发者会知道,这些数值在设备端都是不被支持的。
机智云为了让设备功能定义更加简单直接、所见即所得,研究出来一套算法,用于将用户输入的数值转换成设备能够识别的uint类型,这套算法的核心公式是:y=kx m。
y表示“显示值”,就是用户可见的最终数值,也是数据点定义时输入的值。包括Ymin(最小值) 和 Ymax(最大值)。
x表示“传输值”,就是实际指令间传输使用的数值,云端/客户端接收到的值。一定是uint格式。也包括 Xmin 和 Xmax。
k表示“分辨率”,就是用户输入的分辨率一值,确定了每个取值的步进。
m表示“取值偏移量”或“增量”,算法通过m值将y值偏移到满足x值uint格式的要求,m值默认等于Ymin,确保Xmin=0 。
以下用一个电子温度计举例说明换算过程 数据点内容:取值范围:-30(Ymin)~ 50(Ymax),分辨率:0.1
根据公式:y=kx+m,m默认等于Ymin -30
Xmin =(-30 30) / 0.1 = 0
Xmax = (50 30)/ 0.1 = 800
所有数据点如下表格所示,到这儿所有的数据点就创建完毕,可以从以下表中进行复制粘贴。
设备共享的开启:设备共享开启之后,可以通过APP进行分享,具体开启方法是电机基本设置,修改。设备分享功能:后面点一下开启,弹出框选择开启,就完成设备分享功能。
接下来我们需要生成SOC的代码。生成之前我们先去基本信息里面复制Product Secret,点击显示完整密钥,输入登录密码,查看就能复制了,复制之后保存一会儿会用到。
复制好之后点击左侧的MCU开发,然后选择SOC方案,32M,粘贴刚才复制的Product Secret,然后点击下面的生成代码包,等到进度条完成之后,代码就生成了,下载代码所生成,到这儿,所有的云端工作就已经完成了。接下来就是代码的修改。
接下来是代码的修改,修改代码和编译代码用的是乐鑫的专用IDE,没有开发环境或者需要这个开发环境的可以去群438373554 https://jq.qq.com/?_wv=1027&k=5nxGDB1的群文件进行下载,安装遇到问题可以QQ联系我,
安装软件之后打开软件,在软件的左侧导航右键,导入项目(Import),
选择Makefile项目,然后点击下一步
选择BROWSE按钮,载入Makefile所在的根目录(这个目录很重要,一定要是解压过后的Makefile所在的根目录,目录下面包含了APP,BIN ID等多个文件夹,如果选错,将不能正确导入项目。)
选择好目录之后,需要选择编译器这儿我们用Cygwin GCC编译器,然后点击Finish就能成功导入项目。
成功导入的项目如图所示,到这儿我们的项目已经成功导入到了软件之中,我们接下来要进行代码修改。
首先我们先要修改根目录下面的Makefile文件,双击打开文件,找到文件的的22行,我们需要修改其内容,其目的是对应我们单片机的flash的通讯方式。将
BOOT?=none
APP?=0
SPI_SPEED?=40
SPI_MODE?=QIO
SPI_SIZE_MAP?=0
内容修改为:
BOOT?=new
APP?=1
SPI_SPEED?=40
SPI_MODE?=QIO
SPI_SIZE_MAP?=6
修改完成之后保存关闭。
接下来我们创建一个布尔数组来保存继电器和大功率LED的开关状态,我们需要在gizwits_product.h文件里面定义,然后再gizwits_product.c里面进行全局定义,方便其他文件进行调用。
在gizwits_product.h文件里面添加代码extern bool STA[2]; //继电器和大功率LED标志位
在gizwits_product.c里面添加代码bool STA[2]={0}; //用于存储状态,初始化为关闭状态
接下来我们需要修改按键,实现2个按键对应的功能,打开user_main.c文件。需要对长短按键进行修改,首先我们原理图用的是GPIO0和GPIO2引脚,GPIO0对应的是LED开关控制和SOFTAP(长按),GPIO2对应的是继电器开关控制和AIRLINK(长按)。
找到user_main.c里面的按键重定义,在第45行附近:
#defineKEY_0_IO_MUX PERIPHS_IO_MUX_GPIO0_U
#defineKEY_0_IO_NUM 0
#defineKEY_0_IO_FUNC FUNC_GPIO0
#defineKEY_1_IO_MUX PERIPHS_IO_MUX_MTMS_U
#defineKEY_1_IO_NUM 14
#defineKEY_1_IO_FUNC FUNC_GPIO14
将其内容修改为:
#defineKEY_0_IO_MUX PERIPHS_IO_MUX_GPIO0_U
#defineKEY_0_IO_NUM 0
#defineKEY_0_IO_FUNC FUNC_GPIO0
#defineKEY_1_IO_MUX PERIPHS_IO_MUX_GPIO2_U
#defineKEY_1_IO_NUM 2 ///<
#defineKEY_1_IO_FUNC FUNC_GPIO2
PERIPHS_IO_MUX_GPIO2_U和FUNC_GPIO2是在头文件eagle_soc.h当中240行左右。
修改完定义之后我们需要修改长短按键的内容,将功能修改成我们之前设定好的。
GPIO0-----短按L E D开关控制,长按SOFTAP模式
GPIO2-----短按继电器开关控制,长按AIRLINK模式
将下面的内容:
LOCALvoid ICACHE_FLASH_ATTR key1ShortPress(void)
{
GIZWITS_LOG("#### KEY1 short press,Production Mode\n");
gizwitsSetMode(WifI_PRODUCTION_TEST);
}
LOCAL void ICACHE_FLASH_ATTR key1LongPress(void)
{
GIZWITS_LOG("#### key2 short press,soft ap mode \n");
gizwitsSetMode(WIFI_SOFTAP_MODE);
}
LOCAL void ICACHE_FLASH_ATTR key2ShortPress(void)
{
GIZWITS_LOG("#### key2 short press,soft ap mode \n");
gizwitsSetMode(WIFI_SOFTAP_MODE);
}
LOCAL void ICACHE_FLASH_ATTR key2LongPress(void)
{
GIZWITS_LOG("#### key2 long press,airlink mode\n");
gizwitsSetMode(WIFI_AIRLINK_MODE);
}
修改为:
LOCAL void ICACHE_FLASH_ATTR key1ShortPress(void)
{
STA[0]=!STA[0];//说明一下,此处的取反就是短按一次开关状态改变一次
if(STA[0]) GIZWITS_LOG("####GPIO0-ShortPress,High-power-LED ON \n");
elseGIZWITS_LOG("#### GPIO0-ShortPress,High-power-LED OFF \n");
}
LOCAL void ICACHE_FLASH_ATTR key1LongPress(void)
{
GIZWITS_LOG("#### GPIO0-LongPress,soft apmode \n");
gizwitsSetMode(WIFI_SOFTAP_MODE);
}
LOCAL void ICACHE_FLASH_ATTR key2ShortPress(void)
{
STA[1]=!STA[1]; //说明一下,此处的取反就是短按一次开关状态改变一次
if(STA[1]) GIZWITS_LOG("####GPIO2-ShortPress,Relay ON \n");
elseGIZWITS_LOG("#### GPIO2-ShortPress,Relay OFF \n");
}
LOCAL void ICACHE_FLASH_ATTR key2LongPress(void)
{
GIZWITS_LOG("####GPIO2-LongPress,airlink mode\n");
gizwitsSetMode(WIFI_AIRLINK_MODE);
}
到此按键部分就修改完成了,接下来我们修改继电器和大功率的控制部分,要作为输出IO,首先就要对其进行初始化。在这儿可以新建一个初始化函数或者直接在初始化按键的函数里面进行初始化。
找到按键初始化函数LOCAL void ICACHE_FLASH_ATTR keyInit(void)
在函数末尾增加以下内容:
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4);//配置大功率LED管脚为输出
GPIO_DIS_OUTPUT(GPIO_ID_PIN(4));
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5);//配置继电器管脚为输出
GPIO_DIS_OUTPUT(GPIO_ID_PIN(5));
GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 1);//输出高电平
GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 1);//输出高电平
增加初始化之后需要处理云端的开关指令,找到gizwits_product.c的gizwitsEventProcess函数,需要对valueswitch_led和valueswitch_relay进行修改:
首先修改valueswitch_led,找到gizwitsEventProcess函数里面的valueswitch_led的响应程序:if(0x01 == currentDataPoint.valueswitch_led)
{
//user handle
}
else
{
//user handle
}
修改其内容为:
if(0x01 ==currentDataPoint.valueswitch_led)
{
STA[0]=1;//打开大功率LED
}
else
{
STA[0]=0;//关闭大功率LED
}
同样也修改下面的valueswitch_relay,修改为
if(0x01 ==currentDataPoint.valueswitch_relay)
{
STA[1]=1;//打开继电器
}
else
{
STA[1]=0;//关闭继电器
}
修改完成之后我们找到定时上报函数:userHandle(void)函数
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),!STA[0]);//大功率LED开关,NPN型三极管,低电平有效,取反操作
GPIO_OUTPUT_SET(GPIO_ID_PIN(5),!STA[1]);//继电器开关,NPN型三极管,低电平有效,取反操作
if(time_updata==20)//定时50ms*20,修改定时器之后不改变上报频率
{
time_updata=0;
currentDataPoint.valueswitch_led= STA[0];//大功率LED开关状态上报
currentDataPoint.valueswitch_relay= STA[1];//继电器开关状态上报
}
else time_updata ;
在函数里面增加上面内容,userHandle(void)函数是定时上报的函数,定时时间我们修改一下,修改成50ms,默认1秒,因为我们需要把控制加在里面,50ms可以减小控制延迟,修改方法是打开user_main.c文件,找到gizwits_protocol.c文件里面的#defineUSER_TIME_MS 1000修改成#define USER_TIME_MS 50 然后需要定义一下time_updata,在gizwits_product.c开头定义就行了。到此为止,继电器和LED已经修改完成。
接下来我们增加DHT11温湿度的函数,使其实现温湿度的采集,将驱动文件hal_temp_hum.h和hal_temp_hum.c文件复制到项目的driver文件夹下面。如下图所示。
增加进去之后驱动库我到时候会在文件里面直接打包上传,或者直接跟我索要也行。需要注意的是这儿使用的是GPIO15,如果是其他GPIO,请修改管脚配置相关内容。
找到gizwits_product.c文件,在文件靠头增加#include"driver/hal_temp_hum.h"头文件,增加头文件之后我们需要对DHT11进行初始化,找到user_main.c文件,在最末尾的增加初始化dh11Init();//DHT11初始化。如图
初始化完成之后我们需要对采集的数据进行上报,上报在dh11SensorTest();函数里面的,所以我们在定时上报函数里面需要增加dh11SensorTest();//获取温度并上报 ,在增加后如图所示。
接下来我们修改开机数据点上报的默认值。找到gizwits_product.c文件最后的那个函数voidICACHE_FLASH_ATTR userInit(void);将其内容修改为:
voidICACHE_FLASH_ATTR userInit(void)
{
gizMemset((uint8_t *)¤tDataPoint,0, sizeof(dataPoint_t));
/**Warning !!! DataPoint Variables Init , Must Within The Data Range **/
currentDataPoint.valueswitch_led = 0;
currentDataPoint.valueswitch_relay = 0;
currentDataPoint.valuecolor_controls = 0;
currentDataPoint.valueLED_R = 0;
currentDataPoint.valueLED_G = 0;
currentDataPoint.valueLED_B = 0;
currentDataPoint.valuetemperature = 0;
currentDataPoint.valuehumidity = 0;
}
修改完初始化上报之后我们需要修改全彩灯控制程序,这里我们直接利用#include "pwm.h"库,这儿我把驱动写成了2个独立的库文件RGB_light.h和RGB_light.c,所以直接把我的库复制到驱动文件夹driver里面。然后再user_main.c和gizwits_product.c里面包含头文件。添加好之后在刚在初始化DHT11的位置在初始化一个RGB,添加下面代码
RGB_light_init();//初始化
RGB_light_set_period(500);//设置周期
RGB_light_set_color(0,0,0);//关闭 rgb
添加完之后在gizwits_product.c定义一个数组存放云端数据,用来缓存我们需要的数据。
uint32_tmode_Cloud_data[4]={0};//云端数据缓存 0模式 1R 2G 3B
然后找到gizwitsEventProcess函数,处理云端数据,把数据缓存到我们创建的数组里面。主要修改下面几个数据点的缓存,
currentDataPoint.valuecolor_controls)
currentDataPoint.valueLED_R
currentDataPoint.valueLED_G
currentDataPoint.valueLED_B
修改完成之后代码为:
case EVENT_color_controls:
currentDataPoint.valuecolor_controls =dataPointPtr->valuecolor_controls;
GIZWITS_LOG("Evt: EVENT_color_controls%d\n", currentDataPoint.valuecolor_controls);
switch(currentDataPoint.valuecolor_controls)
{
case color_controls_VALUE0:
mode_Cloud_data[0]=0;//关闭
break;
case color_controls_VALUE1:
mode_Cloud_data[0]=1;//自定义
break;
case color_controls_VALUE2:
mode_Cloud_data[0]=2;//设置红色
break;
case color_controls_VALUE3:
mode_Cloud_data[0]=3;//设置绿色
break;
case color_controls_VALUE4:
mode_Cloud_data[0]=4;//设置蓝色
break;
case color_controls_VALUE5:
mode_Cloud_data[0]=5;//设置黄色
break;
case color_controls_VALUE6:
mode_Cloud_data[0]=6;//设置紫色
break;
case color_controls_VALUE7:
mode_Cloud_data[0]=7;//设置粉色
break;
case color_controls_VALUE8:
mode_Cloud_data[0]=8;//设置白色
break;
default:
break;
}
break;
case EVENT_LED_R:
currentDataPoint.valueLED_R=dataPointPtr->valueLED_R;
GIZWITS_LOG("Evt:EVENT_LED_R%d\n",currentDataPoint.valueLED_R);
mode_Cloud_data[1]=currentDataPoint.valueLED_R;//红色值
if(mode_Cloud_data[1]!=1)
{
mode_Cloud_data[0]=1;//自定义
}
break;
case EVENT_LED_G:
currentDataPoint.valueLED_G=dataPointPtr->valueLED_G;
GIZWITS_LOG("Evt:EVENT_LED_G%d\n",currentDataPoint.valueLED_G);
mode_Cloud_data[2]=currentDataPoint.valueLED_G;//绿色值
if(mode_Cloud_data[2]!=1)
{
mode_Cloud_data[0]=1;//自定义
}
break;
case EVENT_LED_B:
currentDataPoint.valueLED_B=dataPointPtr->valueLED_B;
GIZWITS_LOG("Evt:EVENT_LED_B%d\n",currentDataPoint.valueLED_B);
mode_Cloud_data[3]=currentDataPoint.valueLED_B;//蓝色值
if(mode_Cloud_data[0]!=1)
{
mode_Cloud_data[0]=1;//自定义
}
break;
到这儿我们就成功缓存了所有的数据,接下来就到定时上报函数里面处理数据。在else语句的后面增加以下内容(所有代码会打包上传,不清楚哪儿加看代码)
switch(mode_Cloud_data[0])
{
case 0 :
RGB_light_set_color(0,0,0);//关闭灯
currentDataPoint.valuecolor_controls= 0;
currentDataPoint.valueLED_R= 0;
currentDataPoint.valueLED_G= 0;
currentDataPoint.valueLED_B= 0;
break;
case 1 :
RGB_light_set_color(mode_Cloud_data[1],mode_Cloud_data[2],mode_Cloud_data[3]);//自定义
currentDataPoint.valuecolor_controls= 1;
currentDataPoint.valueLED_R= mode_Cloud_data[1];
currentDataPoint.valueLED_G= mode_Cloud_data[2];
currentDataPoint.valueLED_B= mode_Cloud_data[3];
break;
case 2 :
RGB_light_set_color(255,0,0);//红色
currentDataPoint.valuecolor_controls= 2;
currentDataPoint.valueLED_R= 255;
currentDataPoint.valueLED_G= 0;
currentDataPoint.valueLED_B= 0;
break;
case 3 :
RGB_light_set_color(0,255,0);//绿色
currentDataPoint.valuecolor_controls= 3;
currentDataPoint.valueLED_R= 0;
currentDataPoint.valueLED_G= 255;
currentDataPoint.valueLED_B= 0;
break;
case 4 :
RGB_light_set_color(0,0,255);//蓝色
currentDataPoint.valuecolor_controls= 4;
currentDataPoint.valueLED_R= 0;
currentDataPoint.valueLED_G= 0;
currentDataPoint.valueLED_B= 255;
break;
case 5 :
RGB_light_set_color(255,255,0);//黄色
currentDataPoint.valuecolor_controls= 5;
currentDataPoint.valueLED_R= 255;
currentDataPoint.valueLED_G= 255;
currentDataPoint.valueLED_B= 0;
break;
case 6 :
RGB_light_set_color(255,0,255);//紫色
currentDataPoint.valuecolor_controls= 6;
currentDataPoint.valueLED_R= 255;
currentDataPoint.valueLED_G= 0;
currentDataPoint.valueLED_B= 255;
break;
case 7 :
RGB_light_set_color(255,52,179);//粉色(估计不是粉色)
currentDataPoint.valuecolor_controls= 7;
currentDataPoint.valueLED_R= 255;
currentDataPoint.valueLED_G= 52;
currentDataPoint.valueLED_B= 179;
break;
case 8 :
RGB_light_set_color(255,255,255);//白色
currentDataPoint.valuecolor_controls= 8;
currentDataPoint.valueLED_R= 255;
currentDataPoint.valueLED_G= 255;
currentDataPoint.valueLED_B= 255;
break;
default:
break;
}
修改完所有代码之后,编译代码。在项目地方右键,build项目,生成固件。
编译过后成功过后如下图所示,所有代码以项目文件为准。
打开ESP8266下载软件
选择固件,对应地址,和复选框,波特率串口之类的,然后点击start下载程序
下载中
下载完成
教程到此结束
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com