12018| 14
|
[官方案例教程] 阿里云IOT套件-用一个控制器控制多个设备 |
本帖最后由 柳春晓 于 2020-6-12 11:59 编辑 阿里云IOT套件-用一个控制器控制多个设备 阿里云IOT套件做物联网设计时,可以直接设计手机APP并下载,还可以设计web端的控制页面,在做一些设计时是十分简单便捷且高大上的。但是在阿里云IOT套件的官方教程中,只介绍了一个控制器控制一个设备的方法(控制一个继电器),没有介绍如何用一个控制器去控制多个设备(同时控制多个继电器)。并且,阿里云平台更新较快,教程中有一些地方并未更新,下面针对这些问题来做一个教程。 补充:阿里云还有一个很坑的地方是,在代码中ClientId是可以随便写的,但是!当一个产品被控制过以后(就是ESP32烧过程序连接成功以后),这个产品的ClientId就会被锁定,如果这时写了另一个代码来控制这个产品,其中的ClientId改成了别的,那就会产生“上行错误”的错误。愿大家永不踩坑。
演示视频元件清单接线图创建阿里云产品1.进入阿里云物联网平台
2.登录→新建项目3. 新建空白项目→填写项目名称→确认 4.点击产品→新建产品→输入产品名称→自定义品类→其他设置默认→点击保存 5.查看 6.功能定义→自定义功能→添加自定义功能 7.添加两个自定义功能。 8. 这里标识符如果设置的不是“light”和“relay”要对应更改程序 9.点击设备→新增设备→产品选择之前创建的产品→提交→下载激活凭证 10.查看 11.记录下这三个参数,对应的替换掉程序中相应参数 12.记录下post和set两个Topic列表,官方教程中用的不是这两个Topic列表因此会出现bug 13.在线调试→调试虚拟设备→启动虚拟设备 14. 推送后可以看到右边实时日志中收到了设备上报的数据信息和数据格式 15.新建Web应用→输入名称后确认。由于移动端应用开发功能阿里云正在重新设计,因此关闭了新建功能,这里只能使用Web应用。 16.在组件中找到指示灯和开关拖拽到编辑框中 17.选中灯的开关框中的“开关组件”→配置数据源 18.配置数据源(设备中选择指定设备),灯的开关框中“指示灯组件”采用相同的方式和参数配置,不要忘了最后验证数据格式。 19. 在继电器的开关框中,使用相同的方法为“指示灯组件”和“开关组件”配置数据源,但是这里的属性要改为“继电器的开关”,记住不要忘记“验证数据格式”。 20.点击页面右上角的纸飞机图标即可发布,点击链接即可打开网页。 21.打开连接后可以进行第14步的虚拟设备调试,web页面会跟随虚拟设备调试的状态改变而改变。 22.我们还可以调试真实设备,当点击web端开关后,观察真实设备调试窗口的实时日志。我们继续上一个灯开继电器关的状态,这时将灯关闭。 通过观察数据我们可以看到,云端下发的params中只有light=0一个参数并没有relay的参数!这里就很神奇,照正常的逻辑来说云端应该将灯和继电器的属性一起下发,然而现在云端却只下发了灯的属性(因为灯的状态被改变)忽略了继电器的属性,这里就是本次设计的关键所在,在下面的程序设计中会讲如何解决这个问题。 程序设计1.打开官方的“SmartLight”例程,基于这个例程修改代码。首先在开始的地方定义一个继电器引脚D3。 [mw_shl_code=c,false]#define Smart_LIGHT D2//******************************************** #define Smart_RELAY D3//********************************************[/mw_shl_code] 2.修改WIFI_SSID、WIFI_PASSWORD、ProductKey、ClientId、DeviceName、DeviceSecret、subTopic、pubTopic,注意最后两个上报和订阅参数为上面第12步截图中的参数,其中subTopic对应/*****/ set,pubTopic对应/*****/ post。 3.修改并增加一个产品标识符。 [mw_shl_code=c,false]/*需要操作的产品标识符*/ String Identifier_light = "light";//******************************************** String Identifier_relay = "relay";//********************************************[/mw_shl_code] 4.增加打开和关闭继电器的函数,这里要注意增加了一个引脚的控制要在setup函数中设置pinMode [mw_shl_code=c,false]//******************************************** static void openRelay(){ digitalWrite(Smart_RELAY, HIGH); } //******************************************** static void closeRelay(){ digitalWrite(Smart_RELAY, LOW); }[/mw_shl_code] 5.在callback函数中,要解析灯的状态和继电器的状态两个参数。 [mw_shl_code=c,false]const char* LightStatus = root["params"][Identifier_light]; //************************** const char* RelayStatus = root["params"][Identifier_relay]; //*************************[/mw_shl_code] 我们已经知道,云端下发的params中只有一个参数(状态被改变的参数),所以另一个参数解析出来一定是空的,如果直接判断这个参数是0还是1,那空参数NULL会被判断为0,这样就会出现当灯的状态被改变后继电器就一定会被关闭的现象。因此这里我们必须要加一个数据是否为空的条件判断,这里就是功能实现的关键。 [mw_shl_code=c,false]//******************************************** if(LightStatus !=NULL) { const uint16_t LightStatus = root["params"][Identifier_light]; if(LightStatus == 1){ openLight(); }else{ closeLight(); } String tempMseg = "{\"id\":"+ClientId+",\"params\":{\""+Identifier_light+"\":"+(String)LightStatus+"},\"method\":\"thing.event.property.post\"}"; char sendMseg[tempMseg.length()]; strcpy(sendMseg,tempMseg.c_str()); client.publish(pubTopic,sendMseg); } if(RelayStatus!=NULL) { const uint16_t relayStatus = root["params"][Identifier_relay]; if(relayStatus == 1){ openRelay(); }else{ closeRelay(); } String tempMseg = "{\"id\":"+ClientId+",\"params\":{\""+Identifier_relay+"\":"+(String)relayStatus+"},\"method\":\"thing.event.property.post\"}"; char sendMseg[tempMseg.length()]; strcpy(sendMseg,tempMseg.c_str()); client.publish(pubTopic,sendMseg); }[/mw_shl_code] 6.最后在setup函数中设置一下开机初始状态:灯和继电器都关闭,以及继电器引脚D3的模式。 [mw_shl_code=c,false] pinMode(Smart_LIGHT,OUTPUT);//******************************************** pinMode(Smart_RELAY,OUTPUT);//******************************************** /*开机先关灯和关继电器*/ closeLight(); closeRelay(); /*上报关灯和关继电器信息*/ client.publish(pubTopic,("{\"id\":"+ClientId+",\"params\":{\""+Identifier_light+"\":0,\""+Identifier_relay+"\":0},\"method\":\"thing.event.property.post\"}").c_str());[/mw_shl_code] 最后将附件中的文件解压到桌面运行就可以了。SmartLight_Relay.zip |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed