阿里云IOT套件-用一个控制器控制多个设备

2020-06-041.6万
AI 快速预览详细 收起
本教程详细介绍了如何使用阿里云IOT套件通过一个控制器控制多个设备,如多个继电器。首先,提供了所需的硬件清单和接线图。接着,详细说明了如何在阿里云平台上创建产品、配置功能定义、添加设备以及下载激活凭证。然后,通过Web应用界面配置数据源,确保设备状态同步。最后,提供了详细的代码修改步骤,包括增加继电器引脚定义、修改WIFI_SSID等参数、增加打开和关闭继电器的函数,以及解析云端下发的参数。通过这些步骤,您可以轻松实现一个控制器控制多个设备的功能。


阿里云IOT套件-用一个控制器控制多个设备


      阿里云IOT套件做物联网设计时,可以直接设计手机APP并下载,还可以设计web端的控制页面,在做一些设计时是十分简单便捷且高大上的。但是在阿里云IOT套件的官方教程中,只介绍了一个控制器控制一个设备的方法(控制一个继电器),没有介绍如何用一个控制器去控制多个设备(同时控制多个继电器)。并且,阿里云平台更新较快,教程中有一些地方并未更新,下面针对这些问题来做一个教程。
      补充:阿里云还有一个很坑的地方是,在代码中ClientId是可以随便写的,但是!当一个产品被控制过以后(就是ESP32烧过程序连接成功以后),这个产品的ClientId就会被锁定,如果这时写了另一个代码来控制这个产品,其中的ClientId改成了别的,那就会产生“上行错误”的错误。愿大家永不踩坑。

首先,要感谢szjuliet版主的帖子给到的启发,大家可以看一下:链接
其次,本教程是在官方教程“SmartLight”的基础上做修改,所以建议先做一下官方教程有一个简单的了解,链接

演示视频


元件清单

接线图


阿里云IOT套件-用一个控制器控制多个设备图1

创建阿里云产品


1.进入阿里云物联网平台
2.登录→新建项目
阿里云IOT套件-用一个控制器控制多个设备图2

3. 新建空白项目→填写项目名称→确认
阿里云IOT套件-用一个控制器控制多个设备图3
4.点击产品→新建产品→输入产品名称→自定义品类→其他设置默认→点击保存
阿里云IOT套件-用一个控制器控制多个设备图4
5.查看
阿里云IOT套件-用一个控制器控制多个设备图5
6.功能定义→自定义功能→添加自定义功能
阿里云IOT套件-用一个控制器控制多个设备图6
7.添加两个自定义功能。
                        阿里云IOT套件-用一个控制器控制多个设备图7            阿里云IOT套件-用一个控制器控制多个设备图8
8. 这里标识符如果设置的不是“light”和“relay”要对应更改程序
阿里云IOT套件-用一个控制器控制多个设备图9
9.点击设备→新增设备→产品选择之前创建的产品→提交→下载激活凭证
阿里云IOT套件-用一个控制器控制多个设备图10
10.查看
阿里云IOT套件-用一个控制器控制多个设备图11
11.记录下这三个参数,对应的替换掉程序中相应参数
阿里云IOT套件-用一个控制器控制多个设备图12
12.记录下post和set两个Topic列表,官方教程中用的不是这两个Topic列表因此会出现bug
阿里云IOT套件-用一个控制器控制多个设备图13
13.在线调试→调试虚拟设备→启动虚拟设备
阿里云IOT套件-用一个控制器控制多个设备图14
14. 推送后可以看到右边实时日志中收到了设备上报的数据信息和数据格式
阿里云IOT套件-用一个控制器控制多个设备图15
15.新建Web应用→输入名称后确认。由于移动端应用开发功能阿里云正在重新设计,因此关闭了新建功能,这里只能使用Web应用。
阿里云IOT套件-用一个控制器控制多个设备图16
16.在组件中找到指示灯和开关拖拽到编辑框中
阿里云IOT套件-用一个控制器控制多个设备图17
17.选中灯的开关框中的“开关组件”→配置数据源
阿里云IOT套件-用一个控制器控制多个设备图18
18.配置数据源(设备中选择指定设备),灯的开关框中“指示灯组件”采用相同的方式和参数配置,不要忘了最后验证数据格式。
阿里云IOT套件-用一个控制器控制多个设备图19
19. 在继电器的开关框中,使用相同的方法为“指示灯组件”和“开关组件”配置数据源,但是这里的属性要改为“继电器的开关”,记住不要忘记“验证数据格式”。
阿里云IOT套件-用一个控制器控制多个设备图20
20.点击页面右上角的纸飞机图标即可发布,点击链接即可打开网页。
阿里云IOT套件-用一个控制器控制多个设备图21
21.打开连接后可以进行第14步的虚拟设备调试,web页面会跟随虚拟设备调试的状态改变而改变。
阿里云IOT套件-用一个控制器控制多个设备图22

阿里云IOT套件-用一个控制器控制多个设备图23
22.我们还可以调试真实设备,当点击web端开关后,观察真实设备调试窗口的实时日志。我们继续上一个灯开继电器关的状态,这时将灯关闭。
阿里云IOT套件-用一个控制器控制多个设备图24
通过观察数据我们可以看到,云端下发的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

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(7)
蒋先生
蒋先生
楼主楼主 按继电器的开关 他闪一下就会自动关闭是怎么回事 求教求教
狮山闲人
狮山闲人
按步骤顺利完成,就是到创建web应用时,被卡住了。这个开关的属性格式不对。明明是bool型的,为啥不对哩

吊椅
吊椅回复狮山闲人
第13步再做一遍,然后刷新网页
狮山闲人
狮山闲人
clientID到底是干么的,有什么用,晕了
柳春晓
柳春晓
作者
回复狮山闲人
可以随便填,一个clientID绑定一个项目
大叔1
大叔1
已经解决了,谢谢LZ
阿离8
阿离8
占个楼,宣传下,专业提供云服务器,免备案,域名服务器,有需要可联系客服1839877443
大叔1
大叔1
有没有完整的源码?这里面缺失了好几个文件,无法编译啊
柳春晓
柳春晓
作者
回复大叔1
参数配置的有问题吧
大叔1
大叔1回复柳春晓
好的,现在就是上传了没法连接MQTT,不知道什么原因
共3条回复,已加载2条,点击查看更多共3条回复,已加载全部
东吴小将
东吴小将
ClientId没改……影响大吗
东吴小将
东吴小将回复柳春晓
好的 谢谢
柳春晓
柳春晓
作者
回复东吴小将
影响不大,就是在线调试的时候会一直说上行下行错误,但其实能正常使用,如果发现不能正常使用而且不知道ClientID就重新创一个项目吧
- 没有更多了 -