以前做过的一个演示项目,一款判断人体进出的语言播报方案,通过LwM2M 协议连接 OneNET :
硬件平台:M5311 + STM32F103
云平台:中国移动 OneNET
语音芯片:WT(唯创知音) WT588D
传感器探头: SHARP(夏普) GP2Y0A21YK0F
文章意在于对本次项目做个笔记,方便以后再次用到。
前言
本文是个人笔记,文章只讲基本流程,不讲细节,因为时间太久了,也不太记得了= =!只是个人笔记……
最后所有的资料原理图和程序都会上传至资源。
一、硬件部分
整个项目硬件本相对来说是最简单的,硬件设计可以参考《M5311硬件设计手册》,下面上一下各部分原理图,因为本文主要记录的是 M5311 的使用,STM32我就当大家都很熟悉了,上个最小系统,然后语音模块WT588D 芯片:
1.1 M5311芯片部分
1.2 SIM 卡部分
1.3 控制与指示部分
1.4 STM32部分
1.5 WT588D部分
1.6 功放部分
1.7 电源部分
其他的细节图这里就不上了,只要把主要的这几个地方设计好,其他的地方是很简单的。
二、对接流程
一般来说,对于开发者,这种对接流程是整个工程中相对比较复杂的。
但是中移动官方已经给我们提供了详细的说明文档:《M531X_OneNET参考手册》,因为模块是中移动的,云平台也是中移动的,所以对接资料还是很到位的,这里我只做个简单总结:
2.1 整理流程图
2.2 注册码
一般来说都是对接重庆的平台,M5311直接使用这个码就可以:
char* Onenet_key = "AT+MIPLCREATE=56,130038F10003F2002A04001100000000000010196E\
62696F7462742E6865636C6F7564732E636F6D3A35363833000131F300080000000000,0,56,0\r\n";
2.3 OneNeT 指令集接入汇总
说明部分截取文档中的说明:
2.3.1 资源说明
对于上面的 Object 3200 资源对应关系,有一个表格(下面只列出了部分),在上传资源《资源表》文档有完整的说明:
如果设备超过了保活时间就会离线,此时无法发送消息,需要重新上线,但是不需要再进行注册码登记了,直接发送资源配置与登录即可,保活时间单位为s
三、软件部分
本项目的重点就在于 M5311 的驱动部分,解决了 M5311 的驱动,其他基本没有问题。
3.1 基本定义
M5311 的驱动需要根据文档的说明来,首先我们得根据自己的需求做一个初始的定义:
3.2 AT命令发送函数
其次实现 AT 指令发送的函数:
3.3 M5311初始化函数
初始化函数中除了对模块的复位操作,还有重要的地方就是获取 SIM 卡的 IMEI 和 IMSI,这个在后面平台添加设备的时候需要填写 SIM 卡的这两个参数。
初始化函数如下图:
其他的地方直接看下面源代码把。
虽然所有资料我会上传至资料,但是还要积分下载,这里我把本项目核心的 M5311 驱动部分代码直接贴上,需要的小伙伴直接看这个就行了
#include"common.h"
char* AT = "AT";
char* AT_RST = "AT+CMRB";
char* IMEI = "AT+GSN";
char* IMSI = "AT+CIMI";
char* Open_led = "AT+CMSYSCTRL=0,2";
char* Close_sleep = "AT+SM=LOCK_FOREVER";
char RSSI[] = "AT+CSQ";
char CEREG[] = "AT+CEREG?";
char* Onenet_key = "AT+MIPLCREATE=56,130038F10003F2002A04001100000000000010196E\
62696F7462742E6865636C6F7564732E636F6D3A35363833000131F300080000000000,0,56,0\r\n";
char* LWM_object_T = "AT+MIPLADDOBJ=0,3303,1,\"1\",0,1";
char* LWM_Resource_T = "AT+MIPLDISCOVERRSP=0,3303,1,4,\"5700\"";
char* LWM_object_H = "AT+MIPLADDOBJ=0,3304,1,\"1\",0,1";
char* LWM_Resource_H = "AT+MIPLDISCOVERRSP=0,3304,1,4,\"5700\"";
char* Onenet_connect = "AT+MIPLOPEN=0,65000,30";
char LWM_object_Pir[] = "AT+MIPLADDOBJ=0,3300,1,\"1\",0,0";
char LWM_Resource_Pir[] = "AT+MIPLDISCOVERRSP=0,3303,1,4,\"5502\"";
char* Time_refresh = "AT+MIPLUPDATE=0,65000,0";
char* T_begin= "AT+MIPLNOTIFY=0,0,3303,0,5700,4,4,\"";
char* T_end = "\",0,0";
void T_Send_Test(u8 t_data){
char Send_onenet_T[50] = "";
sprintf(Send_onenet_T,"AT+MIPLNOTIFY=0,0,3303,0,5700,4,4,\"%d\",0,0",t_data);
Iot_SendCmd(Send_onenet_T,"OK",1000);
}
int Iot_SendCmd(char* cmd, char* reply, int wait)
{
u8 i;
memset(&struct_usart3.USART_BUFF, 0, sizeof(struct_usart3.USART_BUFF));
struct_usart3.USART_Length = 0;
printf("[NBiot_SendCmd] %s\r\n 等待时间 %d ms\r\n", cmd,wait);
delay_ms(100);
uart3_send_buff((u8*)cmd,strlen(cmd));
if (wait >= 1000){
for (i = 0; i < (wait / 1000); i++){
delay_ms(1000);
}
}
else delay_ms(wait);
if(strcmp(reply , "") == 0) return 0 ;
if (struct_usart3.USART_Length != 0){
if (strstr((char*)struct_usart3.USART_BUFF, reply)){
printf("\r\n%s\r\n", struct_usart3.USART_BUFF);
return 1;
}
else if (strstr((char*)struct_usart3.USART_BUFF, "ERROR")){
printf("ERROR...\r\n");
return 0;
}
else{
printf("\r\n%s\r\n", struct_usart3.USART_BUFF);
return 0;
}
}
return 0 ;
}
void Iot_SendNOCheck(char* cmd)
{
uart3_send_buff((u8*)cmd,strlen(cmd));
}
void m5311_on(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_7);
delay_ms(1200);
GPIO_ResetBits(GPIOB,GPIO_Pin_7);
delay_ms(200);
}
int Rst_mode()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(AT_RST,"READY",3000);
if(res == 1) return res;
}
return res ;
}
int AT_OK()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(AT,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Closesleep_mode()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(Close_sleep,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Check_CEREG()
{
int res = 0 ;
int i = 0;
for(i=0;i<6;i++){
res = Iot_SendCmd(CEREG,"1",1500);
if(res == 1) return res;
}
return res ;
}
int Onenet_create()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(Onenet_key,"+MIP",1500);
if(res == 1) return res;
}
return res ;
}
int Lwm2m_object_Pir()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(LWM_object_Pir,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Lwm2m_object_T()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(LWM_object_T,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Lwm2m_object_H()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(LWM_object_H,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Lwm2m_resource_Pir()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(LWM_Resource_Pir,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Lwm2m_resource_T()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(LWM_Resource_T,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Lwm2m_resource_H()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(LWM_Resource_H,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Onenet_sign_in()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(Onenet_connect,"OK",1000);
if(res == 1) return res;
}
return res ;
}
int Onenet_time_refresh()
{
int res = 0 ;
int i = 0;
for(i=0;i<4;i++){
res = Iot_SendCmd(Time_refresh,"OK",1000);
if(res == 1) return res;
}
return res ;
}
#ifdef TTEST
void m5311_init(void)
{
m5311_on();
}
#else
void m5311_init(void)
{
m5311_on();
printf("等待软复位……\r\n");
if(Rst_mode()){
if(AT_OK()){
printf("复位成功……,AT指令测试成功,打开LED指示灯\r\n");
Iot_SendCmd(Open_led, "OK", 1000);
if(Closesleep_mode()){
printf("关闭睡眠模式,查询NB卡的IMEI和IMSI\r\n");
Iot_SendCmd(IMEI,"OK", 1000);
Iot_SendCmd(IMSI,"OK", 1000);
printf("查看信号质量\r\n");
if(Check_CEREG()){
printf("信号正常,一切准备就绪\r\n");
}
}
}
}
}
#endif
#ifdef TTEST
void onenet_init(void)
{
printf("开始测试……,请手动输入指令\r\n");
}
#else
void onenet_init()
{
printf("开始创建设备,如果创建过,返回错误也没关系,直接跳过这一步\r\n");
Onenet_create();
Lwm2m_object_Pir();
Lwm2m_resource_Pir();
if(Onenet_sign_in()){
printf("ONENET 登录成功!\r\n");
}
else;
Onenet_ON = TRUE;
}
#endif
void EXECUTER_back(char *cmd)
{
char Send_EXECUTER_back[50] = "";
sprintf(Send_EXECUTER_back,"AT+MIPLEXECUTERSP=0,%s,2",cmd);
Iot_SendNOCheck(Send_EXECUTER_back);
printf("%s\r\n",Send_EXECUTER_back);
}
void call_back()
{
u8 i = 0;
u8 j = 0;
u8 u8Count =0;
char msg[10] = {0};
if(struct_usart3.flag == 1){
printf("收到服务器数据:%s \r\n",struct_usart3.USART_BUFF);
if (strstr((char*)struct_usart3.USART_BUFF, "+MIPLEXECUTE")){
printf("指令数据……\r\n");
if(strstr((char*)struct_usart3.USART_BUFF, "chone")){command_on = TRUE;command = 1;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chtwo")){command_on = TRUE;command = 2;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chthree")){command_on = TRUE;command = 3;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chfour")){command_on = TRUE;command = 4;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chfive")){command_on = TRUE;command = 5;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chsix")){command_on = TRUE;command = 6;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chseven")){command_on = TRUE;command = 7;}
else if(strstr((char*)struct_usart3.USART_BUFF, "cheight")){command_on = TRUE;command = 8;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chnine")){command_on = TRUE;command = 9;}
else if(strstr((char*)struct_usart3.USART_BUFF, "chten")){command_on = TRUE;command = 10;}
else;
for(i=0;i<strlen(struct_usart3.USART_BUFF);i++){
if((char)struct_usart3.USART_BUFF[i] == ':') break;
}
i++;
i++;
i++;
u8Count =i;
for(;i<(strlen(struct_usart3.USART_BUFF)-u8Count);i++){
if((char)struct_usart3.USART_BUFF[i] != ','){
msg[j++] = struct_usart3.USART_BUFF[i];
}
else break;
}
printf("指令回复……\r\n");
EXECUTER_back(msg);
printf("指令回复完毕……\r\n");
}
else if(strstr((char*)struct_usart3.USART_BUFF, "+MIPLWRITE")){
printf("写数据……\r\n");
}
else if(strstr((char*)struct_usart3.USART_BUFF, "+MIPLREAD")){
printf("读数据……\r\n");
}
else printf("不需要的数据\r\n");
printf("清楚缓存……\r\n");
struct_usart3.flag = 0;
struct_usart3.USART_Length = 0;
memset(&struct_usart3.USART_BUFF, 0, sizeof(struct_usart3.USART_BUFF));
}
}
四、云平台部分
云平台设置部分,使用截图演示一遍。
4.1 创建添加产品
在 OneNET 主界面右上角 进入控制台 界面,选择NB-IoT物联网套件,如图:
进入NB-IoT物联网套件页面以后,如果以前有产品会有产品列表: 这里我们点击添加产品:
4.2 添加设备
点击需要添加设备的产品进行添加设备,按如下操作:
这里填写的 IMEI 和 IMSI 是根据上文 3.3 M5311初始化函数获取到的,新的 SIM卡添加设备需要在 第一次上电的时候查看一下这两个参数:
这里我就不添加了,直接用以前的设备做个展示:
添加好了设备以后模块通过我们的正常流程就能与 OneNET 交互信息了,里面的一些详情和资源可以自己研究查看一下,比如资源属性:
这个5502是和 2.3.1 资源说明 一样的,属性意义在《资源表》文档中有说明:
本片记录就到这里,需要全部资源的小伙伴可以去下载,或者直接找我要也可以!
资源链接:STM32+ M5311连接OneNET方案原理图,源码,参考资料
|