前言

最近公司老总买了NB-IOT的模块,老总考虑到STM32芯片的价格涨的很快,而我们的内容做的不是很复杂,再加上支持一下本地企业,QS-100模块到价格超级实惠,决定使用QS-100模块作为通信模块,主要是做上位机控制设备开关的功能吧

1.设计方案

为实现用户远程控制设备开关,采用onenet云平台作为中转平台,QS-100模块作为通信和MCU,微信小程序作为上位机,实现一个简单到NB-IOT物联网Demo。当用户在小程序上点击button时,设备执行开关操作。

2. 环境准备

  • VS code
  • cygwim
  • gcc
  • Logview程序下载工具
  • 串口调试助手,如sscom、MobaXter等

3.实现过程

3.1 QS-100接入OneNet平台

1.在onenet创建一个NB-IOT的设备,接入协议使用LWM2M协议接入,我也是第一次使用这个云平台,所以我选择使用旧版哈哈哈哈,方便在网上百度。
操作流程:进入NB-IOT物联网套件->添加产品->(自己写,网络运营可以选择移动,操作系统选择Linux)->添加设备,设备的IMEI、IMSI号码均可以通过AT指令获取。这里QS-100与OneNet云平台的连接就是通过这两个号码连接的,每个设备有自己的IMEI号码,建立连接就是依靠的这个吧(我理解的)。

//获取IMEI
AT+CGSN=1
//获取IMSI
AT+CIMI

2.准备2.0正常版本的SDK

卖家有提供,在USERAPP目录下,inc目录存放.h头文件,src 目录存放.c文件,examples目录存放厂商给的demo文件,这里连接onenet云平台,使用xy_cloud_demo/onenet/cis_opencu_demo.c文件,当然也可以提前使用simpe_demo.c文件先做一下测试。

使用SDK进行连接,打开这个工程后在src下新建一个onenet.c文件吧,并把cis_openmcu_demo.c文件的内容复制放到onenet.c并把宏定义打开,再模仿一下其他点.c文件把cis_task_init()函数放到命令行中,串口打印应该用zos_printf(),而不是xy_printf(),所以这里要在这改下。

烧录成功后,在串口调试助手中输入help查看所有命令,输入对应到命令即可。如果连接云平台成功,onenet的云端会显示在线。如果没成功到话就得思考一下了,如果模块内的imei号码丢失,肯定是连接不上的,使用AT+CGSN=1查询一下是否还存在。

onenet云平台只能接收300字节 onenet云平台搭建_onenet云平台只能接收300字节


点击详情,找到设备资源列表,看到属性值这里有数据了,没错,这就是设备传过来到数据,具体怎么传过来到可以看opencpu_send_data()函数,要想发送数据给设备(下行),点击写即可,这里要注意属性到类型,Colour的属性是String类型,所以在这最好啦。

onenet云平台只能接收300字节 onenet云平台搭建_onenet云平台只能接收300字节_02


观察onenet.c中到接收下行数据处理函数cis_demo_downstream_cb的参数可以知道,value就是从云端下发的消息的值。

onenet云平台只能接收300字节 onenet云平台搭建_NB-IOT_03


打印value、Valenlen等,因为这里的value是字符指针,也就是字符数组的首地址,所以就这样打印吧!

zos_printf("%s\r\n",value);
	zos_printf("云平台下发请求数据长度%d\r\n",valueLen);

出了使用onenet云端直接下发命令,也可以通过onenet提供的API接口下发命令,API接口文档如下:

OneNetAPI,可知,需要知道这这个ID号。

onenet云平台只能接收300字节 onenet云平台搭建_微信小程序_04


不知道ID号没有关系,可以在程序里面去看看,还是在那个函数里面,参数URI后面又赋值给了msg结构体,如下。所以这几个参数我们可以在这获取呀,直接zos_printf()打印就完事了。

onenet云平台只能接收300字节 onenet云平台搭建_NB-IOT_05

// zos_printf("msg->objId:%d\r\n",msg->objId);
	//zos_printf("msg->insId:%d\r\n",msg->insId);
	//zos_printf("msg->resId:%d\r\n",msg->resId);

打印之后可以知道,分别是3311、0、0。那好,可以做个判断,是这的时候再执行设备开关操作才好,当然这个GPIO的初始化我放到了main函数中,一定要进行初始化!否则这个灯点不亮的!zos_pin_mode(13,PIN_MODE_OUTPUT);

if(msg->objId==3311&&msg->insId==0&&msg->resId==0)
	 {
		 zos_printf("control\r\n");
        char onStr[] = "0";
		char offStr[] = "1";
         if(strcmp(value,onStr)==0){
			zos_printf("on\r\n");
		    zos_pin_write(13, PIN_LOW);//开
		 }else if(strcmp(value,offStr)==0){
		    zos_printf("off\r\n");
			zos_pin_write(13, PIN_HIGH);//关
		 }else{
			 zos_printf("print error!\r\n");
		 }
	 }

3.2 接口测试

可以使用Postman接口测试工具进行测试,下行命令发起POST请求测试结果如下。

onenet云平台只能接收300字节 onenet云平台搭建_NB-IOT_06


串口接收到数据;

onenet云平台只能接收300字节 onenet云平台搭建_微信小程序_07


请求参数和请求头贴上去!

onenet云平台只能接收300字节 onenet云平台搭建_NB-IOT_08


onenet云平台只能接收300字节 onenet云平台搭建_微信小程序_09


好啦,这就OK啦,当然也可以查看设备的信息一类的信息,在API文档里面仔细阅读即可。,发起GET请求查看设备示例如下:

onenet云平台只能接收300字节 onenet云平台搭建_onenet云平台只能接收300字节_10

3.3 微信小程序开发demo

使用微信小程序作为上位机也是比较不错滴!只要会WEB开发就比较好上手,毕竟基于Vue.js的嘛。好,简单到demo设计如下,先搭建出来一个框框!其实也就是对oneNet的api的运用罢了!这一点不得不说比阿里云IOT要方便不少,我还不知道阿里云IOT有没有API这个功能接口哈!不喜勿喷。

关于小程序的账号注册、新建工程、界面就不再多说!

1.设置合法域名。

微信小程序的开发并不是所有的API接口都能用的,必须是https的域名才可以使用哈!

在微信小程序的后台,开发->开发管理->开发设置中添加合法域名

onenet云平台只能接收300字节 onenet云平台搭建_onenet_11


如果你不想添加合法域名,只是为了测试,也可以在调试的时候选择不校验合法域名,当然这样你发布的时候域名请求不到而已!

onenet云平台只能接收300字节 onenet云平台搭建_物联网_12


2.界面书写

当然这只是一个demo,样子写到比较简单,只有几个button。

<button class="weui-btn" type="primary" bindtap="openFunction">开</button>
<button class="weui-btn" type="primary" bindtap="closeFunction">关</button>
<button class="weui-btn" type="primary" bindtap="Looksingle">查看单个设备</button>

onenet云平台只能接收300字节 onenet云平台搭建_微信小程序_13

我这里有用到了weui开发组件,如果你的界面和我的界面不一样没关系,请不要沮丧,在app.json中添加字段即可,和windows并列。

"useExtendedLib": {
    "weui": true
  },

3.请求接口的JS写法
代码如下,其实就是对API接口的运用罢了,小程序的生命周期以及数据绑定等等的,根据业务需求自己了解哈。

Page({

  data: {

  },

  //打开函数
  openFunction(){
    console.log("开");
    //全部参数
    this.sendMessage("0");
  },
  //关闭函数
  closeFunction(){
    console.log("关");
    this.sendMessage("1");
  },
  //查看单个设备处理函数
  Looksingle(){
    //参数
     let deviceId = "754221911"
     let apiKey= "xxxxxxx=";// 写你到apiKey
     let headers = {
       "api-key":apiKey,
       "Host":"api.heclouds.com"
     }
      //拼接URL地址
      let GetUrl = "https://api.heclouds.com/devices/"+deviceId;
     wx.request({
       url: GetUrl,
       method:"GET",
       header:headers,
       success(res){
        console.log(res)
         console.log("查看单个设备",res.data)
       },fail(ret){
         console.log(ret)
       }
     })
  },
  //发送函数
 sendMessage(message){
   let apiKey= "xxxxxxx=";// 写你到apiKey
  let imei = xxxxx;//写你的imei
  let obj_id =3311;
  let obj_inst_id = 0;
  let res_id = 0;
  //发起Post请求
  let header={
    "api-key":apiKey,
    "Host":"api.heclouds.com",
    "Content-Type":"application/json",
  }
  //拼接URL请求地址
  let postUrl = url + "?imei="+imei+"&obj_id="+obj_id+"&obj_inst_id="+obj_inst_id+"&res_id="+res_id;
  wx.request({
    url: postUrl,
    method:"POST",
    data:{
      "args": message
    },
    header:header,
    success(res){
       console.log(res.data)
    },fail(ret){
      console.log(ret)
    }
  })
 }
})

4 感悟与总结

onenet的API接口有点好用,只需要一些参数发起API请求即可。