中国移动物联网开放平台OneNET是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,快速完成产品开发部署,为智能硬件、智能家居产品提供完善的物联网解决方案。本人使用OneNET平台差不多已经有一年半,最初使用它的时候是有一个大学生创新项目,做的是老人健康监护手表,由于团队当初不会开发自己的服务器,因此借助了OneNET。想要使用OneNET需有一个OneNET账号,注册一个即可,注册流程很简单,这里不多介绍。
1、M5310模组采用华为海思Hi2110芯片。
2、M5310模组内置UDP控制命令、可以连接自己的服务器。
3、M5310模组内置LWM2M控制指令、可以直接连接ONENET。
由于内置了LWM2M协议,并且以AT指令的形式来连接OneNET,因此使用起来非常方便。
OneNET创建产品并添加设备操作很简单,只需在页面进行创建和添加即可:
1、点击右上角的“开发者中心”
接着点击创建产品
2、编辑产品信息
填写完信息后点击“确定”就完成产品的创建。
3、添加设备
点击平台的设备管理进行添加设备
设备类型:选择正式设备。
设备名称:随便命名。
IMEI:为NBIOT模组M5310的IMEI号。
Auth_Code:可不填写。
IMSI:为NBIOT物联SIM卡的IMSI号。
IMEI和IMSI和分别向模组发送AT+CGSN=1和AT+CIMI命令得到。
填写完毕后,选择“自动订阅”再点击“确定”就完成设备的添加。
1、配置串口调试助手,波特率为9600
2、上电初始化M5310
M5310
OK //开机启动信息
AT //开机之后循环发送 AT 直到返回 OK,证明模块初始化正常
OK
AT+COPS=1,2,"46000" //设置手动注册移动运营商 MNC
OK
AT+NEARFCN=0,3555 //锁定频点为 3555,锁频可以有效减小搜网时间,但是频点设置错误会导致搜网失败,建议通常情况下不要设置锁频
OK
AT+CSCON=1 //打开信号提示自动上报
OK
AT+CEREG=1 //打开注册信息自动上报
OK
3、生成模组侧设备注册码
模组侧设备创建使用 AT+MIPLCONF 指令,其使用格式为:
AT+MIPLCONF=
其中,
这里介绍两种生成注册码的方法:
(1)使用OneNET平台的专用配置工具OneNET_config_v1.2.exe进行注册码生成:
A.用DOS命令串口打开OneNET_config_v1.2.exe工具并按如下格式填写数据:
按回车键生成对应的数据:
其中,各参数具体含义如下:
0 关闭 debug 模式
1 仅打印接收/发送包数据长度
2 打印发送数据包长度和接收数据内容及数据长度
3 打印接收/发送数据内容及数据长度
ServerURI 远端服务器地址, 重庆平台使用 183.230.40.39
Port 远端服务器端口号, 重庆平台使用 5683
权参数 IMEI 和 和 IMSI;
会自动从 32768~65535 中选择一个可用的端口号;
这种方法适用于采用串口调试助手调试M5310模组。
(2)使用相关算法生成注册码:
#include "memory.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef enum
{
MIPL_DEBUG_LEVEL_NONE = 0,
MIPL_DEBUG_LEVEL_RXL,
MIPL_DEBUG_LEVEL_RXL_RXD,
MIPL_DEBUG_LEVEL_TXL_TXD,
} MIPL_DEBUG_LEVEL_E;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned uint32;
#define MIPL_BOOT 1
#define MIPL_ENCRYPT 0
#define MIPL_DEBUG MIPL_DEBUG_LEVEL_NONE
#define MIPL_PORT 0
#define MIPL_KEEP_ALIVE 3000
#define MIPL_BLOCK1 5
#define MIPL_BLOCK2 5
#define MIPL_BLOCK2TH 1
#define MIPL_URI "coap:\/\/183.230.40.39:5683"
#define MIPL_ENDPOINT "862018102915220;460040236709122"
typedef struct
{
uint8 boot;
uint8 encrypt;
MIPL_DEBUG_LEVEL_E debug;
uint16 port;
uint32 keep_alive;
size_t uri_len;
char* uri;
size_t ep_len;
char* ep;
uint8 block1; //COAP option BLOCK1(PUT or POST),0-6. 2^(4+n) bytes
uint8 block2; //COAP option BLOCK2(GET),0-6. 2^(4+n) bytes
uint8 block2th; //max size to trigger block-wise operation,0-2. 2^(8+n) bytes
} MIPL_T;
void mipl_generate(char *buf, size_t buflen, MIPL_T *mipl);
int main(void)
{
char config[1024];
MIPL_T m5310_mipl_t;
m5310_mipl_t.block1 = MIPL_BLOCK1;
m5310_mipl_t.block2 = MIPL_BLOCK2;
m5310_mipl_t.block2th = MIPL_BLOCK2TH;
m5310_mipl_t.boot = MIPL_BOOT;
m5310_mipl_t.debug = MIPL_DEBUG;
m5310_mipl_t.encrypt = MIPL_ENCRYPT;
m5310_mipl_t.ep_len = strlen((char*)MIPL_ENDPOINT);
m5310_mipl_t.ep = (char*)MIPL_ENDPOINT;
m5310_mipl_t.keep_alive = MIPL_KEEP_ALIVE;
m5310_mipl_t.port = MIPL_PORT;
m5310_mipl_t.uri = (char*)MIPL_URI;
m5310_mipl_t.uri_len = strlen((char*)MIPL_URI);
mipl_generate(config, sizeof(config), &m5310_mipl_t);
while(1);
return 0;
}
void output_buffer(unsigned char *buffer, int length,int index, int flag)
{
int i = 0;
while( i < length )
{
printf( "%02X", buffer[i++] );
}
printf(",%d,%d\r\n",index,flag);
}
void mipl_generate(char *buf, size_t buflen, MIPL_T *mipl)
{
uint32 offset = 0;
int mipl_num = 0;
char mode = 0;
memset(buf, 0, buflen);
mode = ((mipl->boot & 0x1) << 4) | (mipl->encrypt & 0x1);
memcpy(buf + offset, &mode, 1);
offset++;
memcpy(buf + offset, &mipl->debug, 1);
offset++;
memcpy(buf + offset, &mipl->port, 2);
offset += 2;
memcpy(buf+offset, &mipl->keep_alive, 4);
offset += 4;
memcpy(buf + offset, &mipl->uri_len, 2);
offset += 2;
memcpy(buf + offset, mipl->uri, mipl->uri_len);
offset += mipl->uri_len;
memcpy(buf + offset, &mipl->ep_len, 2);
offset += 2;
memcpy(buf + offset, mipl->ep, mipl->ep_len);
offset += mipl->ep_len;
*(buf + offset) = mipl->block1;
offset++;
*(buf + offset) = mipl->block2;
offset++;
*(buf + offset) = mipl->block2th;
offset++;
mipl_num = 0;
while(offset > 1024)//每条+MIPLCONF命令最多输入1024字节配置数据
{
printf("AT+MIPLCONF=%d,",1024);
output_buffer( (unsigned char *)(buf + (mipl_num >> 10)),1024,mipl_num + 1,0);//index从1起始
mipl_num++;
offset -= 1024;
}
printf("AT+MIPLCONF=%d,",offset);
output_buffer( (unsigned char *)(buf + (mipl_num >> 10)),offset,mipl_num + 1,1);//结束
}
这种方法适用于通过MCU控制M5310模组。
将生成的注册码发送到M5310:
AT+MIPLCONF=71,10000000B80B00001900636F61703A2F2F3138332E3233302E34302E33393A353638331F003836323031383130323931353232303B343630303430323336373039313232050501,1,1
0
OK
4、 订阅Object 组 配置
命令格式:AT+MIPLADDOBJ=,
objectid代表的类型可参考IPSO 资源模型,http://www.openmobilealliance.org/wp/OMNA/LwM2M/LwM2MRegistry.html。
如发送:AT+MIPLADDOBJ=0,3303,0
5、模组侧发起登录
AT+MIPLOPEN=0,15
上述指令中,30 代表登录超时时间;如果超过该时间,模组还未接收到平台的登录响应,模组则会上报登录失败的通知。
登录结果上报:
模组上报登录请求,服务器收到登录请求数据之后,会根据数据内容,返回本次登录结果;如果登录失败,或者登录超时,模组都会上报登录失败的响应。
登录成功上报打印如下:
+MIPLOPEN:0,1
登录失败上报打印如下:
+MIPLOPEN:0,0
需要注意的是, 如果在注册码中的 debug参数设置为非0,则在登录过程中,除了上报登录信息之外,还会应显示对应debug 等级的数据内容。
模组登录成功后,平台会下发Observer 消息和 Discover 消息;模组收到这两条消息之后,会自动处理,无需用户另行处理:
同时OneNET会显示设备在线:
6、向OneNET平台发送数据
命令格式:AT+MIPLNOTIFY=,
这里使用不带ackid方法上报:
AT+MIPLNOTIFY=0,3303,0,5700,4,"24.5"
OK
查看上报的数据:
参数说明:
1 | 2 | 3 | 4 | 5 | 6 |
string | opaque | integer | float | bool | hex_str |
1、上电检查流程
(1) AT //判断模组是否上电开机成功
(2) AT+CSQ //信号质量检查
(3) AT+CEREG? //判断 PS 域附着状态,标识位返回 1 或 5 表示附着正常
(4) AT+CGATT? //检查模组 PS 附着状态
2、模组侧设备创建及资源订阅,登录流程
(1) AT+MIPLCONF=72,1003000………. 3033393639050501,1,1//设置模组侧设备注册码
(2) AT+MIPLADDOBJ=0,3200,0 //订阅 Object 3200 资源设置
(3) AT+MIPLNOTIFY=0,3200,0,5505,6," E309C82FE6 ",1 //订阅 Resource 5500 资源设置
(4) AT+MIPLOPEN=0,30 //设备登录到 OneNET 平台
3、OneNET 数据收发流程
(1) AT+MIPLNOTIFY=0,3200,0,5505,6," E309C82FE6 ",1 //数据上传
(2) AT+MIPLREAD=0,60204,3200,0,5505," E309C82FE6 ",1 //Read 操作回复流程
(3) AT+MIPLWRITE=0,62069,1 //Write 操作回复流程
(4) AT+MIPLEXECUTE=0,46081,1 //Execute 操作回复流程
4、模组侧设备注销流程
(1) AT+MIPLCLOSE=0 //登录注销流程
(2) AT+MIPLDELOBJ=0,3200,0 //模组侧订阅资源列表释放
(3) AT+MIPLDEL=0 //模组侧通信实例删除
更多请参考:OMA LightweightM2M (LwM2M) Object and Resource Registry