湖畔开源电子论坛

 找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
热搜: 4G NB ZigBee WiFi
查看: 4230|回复: 0

NB-IoT (BC35、BC26、BC28)模块移远BC35全网通接入OneNET平...

[复制链接]

88

主题

89

帖子

816

积分

超级版主

Rank: 8Rank: 8

积分
816
发表于 2019-10-14 19:47:34 | 显示全部楼层 |阅读模式
本帖最后由 湖畔科技 于 2019-10-14 19:56 编辑

  1. 网上很多NB-IOT模块的资料都是使用LWM2M、COAP协议去连接onenet平台
  2. 因为现在很多的NB-IOT模块都支持TCP协议,因此就想使用TCP协议然后转MQTT协议连接onenet平台,经过试验证明是可以的。
  3. 首先我们先分析一下如何登陆接入Onenet平台。
  4. 先从它数据格式开始分析。首先我们要从后台取出三个信息,我们以这个为例。
  5. 鉴权信息:test(具体的看你设置的)设备ID:123456789 产品ID:789123 (具体是什么看你自己的设备)
  6. MQTT接入都是发十六进制的数据。
  7. 那么我们发送的时候就是这样子的一串数据
复制代码
  1. <p>0x10 0x24 0x00 0x04 0x4D 0x51 0x54 0x54 0x04 0xC0 0x00 0x78 0x00 0x09 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x00 0x07 0x37 0x38 0x39 0x31 0x32 0x33 0x20 0x00 0x04 0x74 0x65 0x73 0x74
  2. [ 0x10 ]   // MQTT类型=1  DupFlag=0 QosLevel=0 Retain=0
  3. [ 0x22 ]   // remainedLength=34  以下的数据长度  0x00 04......0x74 0x65 0x73 0x74这个之间的长度,您可以数一下看看</p><p>[ 0x00 0x04 ]   // protocolNameLength=4 这是发固定的MQTT这4个字母,长度为4.但是需要两个字节保存长度
  4. [ 0x4D 0x51 0x54 0x54 ]   // protocolName=MQTT
  5. [ 0x04 ]   // protocolLevel=4  固定的一种类型
  6. [ 0xC0 ]   // userFlag=1 passwordFlag=1 willFlag=0 willRetainFlag=0 willQosFlag=0 clenSessionFlag=0 clenSessionFlag=0  固定的一种类型
  7. [ 0x00 0x78 ]   // keepAlive=120  这是保持连接的时间为120S
  8. [ 0x00 0x08]   // clientIdentifierLen=8 这是设备ID的长度 用两个字节记录
  9. [ 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 ]   // clientIdentifier=12345678 设备ID
  10. [ 0x00 0x06 ]   // userNameLen=6 这是产品ID的长度 用两个字节记录
  11. [ 0x37 0x38 0x39 0x31 0x32 0x33]   // userName=789123
  12. [ 0x00 0x04 ]   // userPasswordLen=4 这是鉴权信息的长度 用两个字节记录
  13. [ 0x74 0x65 0x73 0x74 ]   // userPassword=test</p>
复制代码

这里面有个坑,长度的十六进制是十进制转换为十六进制。而“MQTT” ,test(具体的看你设置的)设备ID:123456789 产品ID:789123 这些信息都是字符串转十六进制
下面我们直接上指令
  1. <p>AT
  2. OK
  3. AT+NRB//重启模块的指令,在单片机里面最好进行重启一下
  4. AT+CMEE=1
  5. OK
  6. AT+CGSN=1
  7. +CGSN:867725030027605
  8. OK
  9. AT+NBAND?
  10. +NBAND:8 //移动的返回+NBAND:8,电信的返回+NBAND:5</p><p>OK
  11. AT+NBAND=8 //设置为移动的,电信的指令为AT+NBAND=5
  12. OK
  13. AT+CIMI //查询卡号
  14. 460042437100213
  15. OK
  16. AT+CSQ //查询信号指令,如果返回+CSQ:99,99 说明还没有信号
  17. +CSQ:29,99
  18. OK
  19. AT+NSOCR=STREAM,6,56000,1 //做TCP socket创建准备
  20. AT+NSOCO=1,183.230.40.39,6002//连接服务器。6002为服务器端口号
  21. OK</p>
复制代码


注意:NB发送数据的时候数据内容需要转换为十六进制。大家可以使用在线转换工具
发送数据的指令为:AT+NSOSD=1,发送内容的长度,内容。//注意长度不可以多或者少

  1. <p>AT+NSOSD=1,36,102200044D51545404C00078000831323334353637380006373839313233000474657374
  2. 这个时候已经连接上服务器了,那么现在就发送数据,原始数据如下
  3. {"datastreams":[{"id":"temp","datapoints":[{"value":50}]}]}</p>
复制代码


但是需要增加一些数据头之类的格式

这是转换后的数据
下面我们开始发送数据到服务器

  1. AT+NSOSD=1,69,3043000324647001003B7B226461746173747265616D73223A5B7B226964223A2274656D70222C2264617461706F696E7473223A5B7B2276616C7565223A35307D5D7D5D7D
复制代码

数据头的内容:



  1. 3043000324647001003B
复制代码

数据头的含义
  1. <p>30 // MQTT类型=3  DupFlag=0 QosLevel=0 Retain=0
  2. 43 //remainedLength=67 即是本位以下的内容数据长度,是十进制的长度装16进制
  3. 0003// TopicNameLen=3
  4. 246470//TopicName=$dp
  5. 01//数据类型:数据类型1:Json数据1;一共有七种
  6. 003B//两位数据包长度,即发送内容的长度</p>
复制代码


完整的步骤
  1. <p>AT
  2. OK
  3. AT+NRB//重启模块的指令,在单片机里面最好进行重启一下
  4. AT+CMEE=1
  5. OK
  6. AT+CGSN=1
  7. +CGSN:867725030027605
  8. OK
  9. AT+NBAND?
  10. +NBAND:8 //移动的返回+NBAND:8,电信的返回+NBAND:5</p><p>OK
  11. AT+NBAND=8 //设置为移动的,电信的指令为AT+NBAND=5
  12. OK
  13. AT+CIMI //查询卡号
  14. 460042437100213
  15. OK
  16. AT+CSQ //查询信号指令,如果返回+CSQ:99,99 说明还没有信号
  17. +CSQ:29,99
  18. OK
  19. AT+NSOCR=STREAM,6,56000,1 //做TCP socket创建准备
  20. AT+NSOCO=1,183.230.40.33,6002//连接服务器。6002为服务器端口号
  21. OK
  22. AT+NSOSD=1,36,102200044D51545404C00078000831323334353637380006373839313233000474657374</p><p>OK
  23. +NSONMI:1,4//这是服务器返回来的数据。
  24. AT+NSORF=1,4//查询接收内容的指令203是需要查询的长度。可以多,
  25. 1,183.230.40.33,80,203,20200000,0</p><p>OK
  26. AT+NSOSD=1,69,3043000324647001003B7B226461746173747265616D73223A5B7B226964223A2274656D70222C2264617461706F696E7473223A5B7B2276616C7565223A35307D5D7D5D7D</p>
复制代码



附上C语言转十六进制函数
  1. <p>int Str2Hex(char *str,char *hex)
  2. {
  3.         int high = 0;
  4.         int low = 0;
  5.         int temp = 0;</p><p>        if (NULL==str || NULL==hex){
  6.                 //printf("the str or hex is wrong\n");
  7.                 return -1;
  8.         }</p><p>        if (0==strlen(str)){
  9.                 //printf("the input str is wrong\n");
  10.                 return -2;
  11.         }</p><p>        while(*str)
  12.         {
  13.                 temp = (int)(*str);
  14.                 high = temp>>4;
  15.                 low = temp & 15;
  16.                 *hex = Value2Hex(high);
  17.                 hex++;
  18.                 *hex = Value2Hex(low);
  19.                 hex++;
  20.                 str++;
  21.         }
  22.         *hex = '\0';
  23.         return 0;
  24. }</p>
复制代码



附上发送MQTT连接服务器的数据及发送数据的格式化函数
  1. <p>void ClearRAM(u8* ram,u32 n)
  2. {
  3.   u32 i;
  4.   for (i = 0;i < n;i++)
  5.   {
  6.     ram[i] = 0x00;
  7.   }
  8. }
  9. //构建MQTT连接包
  10. u16 mqtt_connect_message(char *mqtt_message,char *PROID,char *AUTH_INFO,char *DEVID)
  11. {
  12. //        char HTTP_Buf[400];     //HTTP报文缓存区
  13.         char str[500];
  14.         char strHEX[500];
  15.         u16 PROID_length = strlen(PROID);
  16.         u16 DEVID_length = strlen(DEVID);
  17.         u16 AUTH_INFO_length = strlen(AUTH_INFO);
  18.         u16 MQTT_length = strlen("MQTT");
  19.         u16 packetLen;
  20.         u16 i,baseIndex;
  21.         ClearRAM((u8*)str,200);   //清空commandAT数据包缓存,发送命令包含ip端口和长度
  22.         ClearRAM((u8*)strHEX,200); //清空locationHex数据包缓存,转换为hex 需要发送的真实数据
  23.         packetLen = 12;//固定的数据头长度
  24.         if(PROID_length > 0)
  25.                 packetLen = packetLen + 2 + PROID_length;
  26.         if(DEVID_length > 0)
  27.                 packetLen = packetLen+ 2 + DEVID_length;
  28.                 if(AUTH_INFO_length > 0)
  29.                 packetLen = packetLen+ 2 + AUTH_INFO_length;
  30.                
  31.                 strncpy((char*)(mqtt_message+strlen((char*)mqtt_message)),"10",2);
  32.                 sprintf(strHEX,"%02x",(packetLen-2));</p><p>                strcat(mqtt_message,strHEX);
  33.                 ClearRAM((u8*)str,200);   //清空commandAT数据包缓存,发送命令包含ip端口和长度
  34.                 ClearRAM((u8*)strHEX,200); //清空locationHex数据包缓存,转换为hex 需要发送的真实数据
  35.                 strcat(mqtt_message,"00044D51545404C00100");               
  36.     //装载设备ID到数据包               
  37.                 sprintf(str, "%02x%02x",((0xff00&(DEVID_length))>>8),(0xff&DEVID_length));
  38.                 strcat(mqtt_message,str);
  39.                 ClearRAM((u8*)str,200);  
  40.                 sprintf(str, "%s",DEVID);
  41.                 Str2Hex((char*)str,(char*)strHEX);
  42.                 strcat(mqtt_message,strHEX);        
  43.                 ClearRAM((u8*)str,200);
  44.                 ClearRAM((u8*)strHEX,200);
  45.                  //装载产品ID到数据包               
  46.                 sprintf(str, "%02x%02x",((0xff00&(PROID_length))>>8),(0xff&PROID_length));
  47.                 strcat(mqtt_message,str);
  48.                 ClearRAM((u8*)str,200);  
  49.                 sprintf(str, "%s",PROID);
  50.                 Str2Hex((char*)str,(char*)strHEX);
  51.                 strcat(mqtt_message,strHEX);        
  52.                 ClearRAM((u8*)str,200);
  53.                 ClearRAM((u8*)strHEX,200);
  54.           //装载产品ID到数据包               
  55.                 sprintf(str, "%02x%02x",((0xff00&(AUTH_INFO_length))>>8),(0xff&AUTH_INFO_length));
  56.                 strcat(mqtt_message,str);
  57.                 ClearRAM((u8*)str,200);  
  58.                 sprintf(str, "%s",AUTH_INFO);
  59.                 Str2Hex((char*)str,(char*)strHEX);
  60.                 strcat(mqtt_message,strHEX);        
  61.                 ClearRAM((u8*)str,200);
  62.                 ClearRAM((u8*)strHEX,200);
  63.                 Str2Hex((char*)str,(char*)strHEX);
  64.                 strcat(mqtt_message,strHEX);
  65.                 strcat(mqtt_message,"\r\n");        
  66.                 return packetLen;   
  67. }
  68. //构建MQTT数据包
  69. u16 mqtt_SendData_message(char *mqtt_messageHEX,char *SendData,short length)
  70. {
  71.                 char str[200];
  72.                 char strHEX[200];
  73.                 u16 packetLen=length+8;
  74.           u16 SendData_length = strlen(SendData);
  75.           strncpy((char*)(mqtt_messageHEX+strlen((char*)mqtt_messageHEX)),"30",2);
  76.                 sprintf(strHEX,"%02x",(packetLen));
  77.                 strcat(mqtt_messageHEX,strHEX);
  78.                 ClearRAM((u8*)str,200);   //清空commandAT数据包缓存,发送命令包含ip端口和长度
  79.                 ClearRAM((u8*)strHEX,200); //清空locationHex数据包缓存,转换为hex 需要发送的真实数据
  80.                 strcat(mqtt_messageHEX,"01000324647001");        
  81.               //装载json数据到数据包               
  82.                 sprintf(str, "%02x%02x",((0xff00&(SendData_length))>>8),(0xff&SendData_length));
  83.                 strcat(mqtt_messageHEX,str);
  84.                 ClearRAM((u8*)str,200);  
  85.                 sprintf(str, "%s",SendData);
  86.                 Str2Hex((char*)str,(char*)strHEX);
  87.                 strcat(mqtt_messageHEX,strHEX);        
  88.                 ClearRAM((u8*)str,200);
  89.                 ClearRAM((u8*)strHEX,200);        
  90.           return packetLen;   
  91. }        </p>
复制代码


MQTT ONEnet测试调试工具:https://www.amobbs.com/thread-5698272-1-1.html
Onenet平台MQTT协议数据包生成器:关注微信公众号“NNHPTCH”,南宁湖畔科技,回复“Onenet平台MQTT协议数据包生成器”


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|官方淘宝店|手机版|湖畔科技官网|加入QQ群|湖畔开源电子论坛 ( 公安备案:45010702001370(交互式论坛) 工信部备案:桂ICP备17008293号 )

GMT+8, 2024-4-26 23:22 , Processed in 0.044489 second(s), 21 queries .

Powered by 湖畔科技

Copyright © 2001-2021

快速回复 返回顶部 返回列表