NB-IoT NBIOT(BC35、BC26、BC28)模塊 移遠BC35全網通接入OneNET平臺MQTT協議實現數據傳輸

網上很多NB-IOT模塊的資料都是使用LWM2M、COAP協議去連接onenet平臺
因爲現在很多的NB-IOT模塊都支持TCP協議,因此就想使用TCP協議然後轉MQTT協議連接onenet平臺,經過試驗證明是可以的。
首先我們先分析一下如何登陸接入Onenet平臺。
先從它數據格式開始分析。首先我們要從後臺取出三個信息,我們以這個爲例。
鑑權信息:test(具體的看你設置的)設備ID:123456789 產品ID:789123 (具體是什麼看你自己的設備)
MQTT接入都是發十六進制的數據。
那麼我們發送的時候就是這樣子的一串數據

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 
[ 0x10 ]   // MQTT類型=1  DupFlag=0 QosLevel=0 Retain=0 
[ 0x22 ]   // remainedLength=34  以下的數據長度  0x00 04......0x74 0x65 0x73 0x74這個之間的長度,您可以數一下看看

[ 0x00 0x04 ]   // protocolNameLength=4 這是發固定的MQTT這4個字母,長度爲4.但是需要兩個字節保存長度
[ 0x4D 0x51 0x54 0x54 ]   // protocolName=MQTT 
[ 0x04 ]   // protocolLevel=4  固定的一種類型
[ 0xC0 ]   // userFlag=1 passwordFlag=1 willFlag=0 willRetainFlag=0 willQosFlag=0 clenSessionFlag=0 clenSessionFlag=0  固定的一種類型
[ 0x00 0x78 ]   // keepAlive=120  這是保持連接的時間爲120S
[ 0x00 0x08]   // clientIdentifierLen=8 這是設備ID的長度 用兩個字節記錄
[ 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 ]   // clientIdentifier=12345678 設備ID
[ 0x00 0x06 ]   // userNameLen=6 這是產品ID的長度 用兩個字節記錄
[ 0x37 0x38 0x39 0x31 0x32 0x33]   // userName=789123
[ 0x00 0x04 ]   // userPasswordLen=4 這是鑑權信息的長度 用兩個字節記錄
[ 0x74 0x65 0x73 0x74 ]   // userPassword=test

這裏面有個坑,長度的十六進制是十進制轉換爲十六進制。而“MQTT” ,test(具體的看你設置的)設備ID:123456789 產品ID:789123 這些信息都是字符串轉十六進制
下面我們直接上指令

AT 
OK 
AT+NRB//重啓模塊的指令,在單片機裏面最好進行重啓一下 
AT+CMEE=1 
OK 
AT+CGSN=1 
+CGSN:867725030027605 
OK 
AT+NBAND? 
+NBAND:8 //移動的返回+NBAND:8,電信的返回+NBAND:5

OK 
AT+NBAND=8 //設置爲移動的,電信的指令爲AT+NBAND=5 
OK 
AT+CIMI //查詢卡號 
460042437100213 
OK 
AT+CSQ //查詢信號指令,如果返回+CSQ:99,99 說明還沒有信號 
+CSQ:29,99 
OK 
AT+NSOCR=STREAM,6,56000,1 //做TCP socket創建準備 
AT+NSOCO=1,183.230.40.39,6002//連接服務器。6002爲服務器端口號 
OK

注意:NB發送數據的時候數據內容需要轉換爲十六進制。大家可以使用在線轉換工具
發送數據的指令爲:AT+NSOSD=1,發送內容的長度,內容。//注意長度不可以多或者少

AT+NSOSD=1,36,102200044D51545404C00078000831323334353637380006373839313233000474657374
這個時候已經連接上服務器了,那麼現在就發送數據,原始數據如下
{"datastreams":[{"id":"temp","datapoints":[{"value":50}]}]}

但是需要增加一些數據頭之類的格式

這是轉換後的數據
下面我們開始發送數據到服務器

AT+NSOSD=1,69,3043000324647001003B7B226461746173747265616D73223A5B7B226964223A2274656D70222C2264617461706F696E7473223A5B7B2276616C7565223A35307D5D7D5D7D

數據頭的內容:

3043000324647001003B

數據頭的含義

30 // MQTT類型=3  DupFlag=0 QosLevel=0 Retain=0 
43 //remainedLength=67 即是本位以下的內容數據長度,是十進制的長度裝16進制
0003// TopicNameLen=3 
246470//TopicName=$dp 
01//數據類型:數據類型1:Json數據1;一共有七種	
003B//兩位數據包長度,即發送內容的長度

完整的步驟

AT 
OK 
AT+NRB//重啓模塊的指令,在單片機裏面最好進行重啓一下 
AT+CMEE=1 
OK 
AT+CGSN=1 
+CGSN:867725030027605 
OK 
AT+NBAND? 
+NBAND:8 //移動的返回+NBAND:8,電信的返回+NBAND:5

OK 
AT+NBAND=8 //設置爲移動的,電信的指令爲AT+NBAND=5 
OK 
AT+CIMI //查詢卡號 
460042437100213 
OK 
AT+CSQ //查詢信號指令,如果返回+CSQ:99,99 說明還沒有信號 
+CSQ:29,99 
OK 
AT+NSOCR=STREAM,6,56000,1 //做TCP socket創建準備 
AT+NSOCO=1,183.230.40.33,6002//連接服務器。6002爲服務器端口號 
OK
AT+NSOSD=1,36,102200044D51545404C00078000831323334353637380006373839313233000474657374

OK 
+NSONMI:1,4//這是服務器返回來的數據。 
AT+NSORF=1,4//查詢接收內容的指令203是需要查詢的長度。可以多, 
1,183.230.40.33,80,203,20200000,0

OK 
AT+NSOSD=1,69,3043000324647001003B7B226461746173747265616D73223A5B7B226964223A2274656D70222C2264617461706F696E7473223A5B7B2276616C7565223A35307D5D7D5D7D

附上C語言轉十六進制函數

int Str2Hex(char *str,char *hex)
{
        int high = 0;
        int low = 0;
        int temp = 0;

        if (NULL==str || NULL==hex){
                //printf("the str or hex is wrong\n");
                return -1;
        }

        if (0==strlen(str)){
                //printf("the input str is wrong\n");
                return -2;
        }

        while(*str)
        {
                temp = (int)(*str);
                high = temp>>4;
                low = temp & 15;
                *hex = Value2Hex(high);
                hex++;
                *hex = Value2Hex(low);
                hex++;
                str++;
        }
        *hex = '\0';
        return 0;
}

附上發送MQTT連接服務器的數據及發送數據的格式化函數

void ClearRAM(u8* ram,u32 n)
{
  u32 i;
  for (i = 0;i < n;i++)
  {
    ram[i] = 0x00;
  }
}
//構建MQTT連接包 
u16 mqtt_connect_message(char *mqtt_message,char *PROID,char *AUTH_INFO,char *DEVID)
{
//        char HTTP_Buf[400];     //HTTP報文緩存區
        char str[500];
        char strHEX[500];
        u16 PROID_length = strlen(PROID);
        u16 DEVID_length = strlen(DEVID);
        u16 AUTH_INFO_length = strlen(AUTH_INFO);
        u16 MQTT_length = strlen("MQTT");
        u16 packetLen;
        u16 i,baseIndex;
        ClearRAM((u8*)str,200);   //清空commandAT數據包緩存,發送命令包含ip端口和長度
        ClearRAM((u8*)strHEX,200); //清空locationHex數據包緩存,轉換爲hex 需要發送的真實數據
        packetLen = 12;//固定的數據頭長度
        if(PROID_length > 0)
                packetLen = packetLen + 2 + PROID_length;
        if(DEVID_length > 0)
                packetLen = packetLen+ 2 + DEVID_length;
                if(AUTH_INFO_length > 0)
                packetLen = packetLen+ 2 + AUTH_INFO_length;
                
                strncpy((char*)(mqtt_message+strlen((char*)mqtt_message)),"10",2);
                sprintf(strHEX,"%02x",(packetLen-2));

                strcat(mqtt_message,strHEX);
                ClearRAM((u8*)str,200);   //清空commandAT數據包緩存,發送命令包含ip端口和長度
                ClearRAM((u8*)strHEX,200); //清空locationHex數據包緩存,轉換爲hex 需要發送的真實數據
                strcat(mqtt_message,"00044D51545404C00100");                
    //裝載設備ID到數據包                
                sprintf(str, "%02x%02x",((0xff00&(DEVID_length))>>8),(0xff&DEVID_length));
                strcat(mqtt_message,str);
                ClearRAM((u8*)str,200);  
                sprintf(str, "%s",DEVID);
                Str2Hex((char*)str,(char*)strHEX);
                strcat(mqtt_message,strHEX);        
                ClearRAM((u8*)str,200); 
                ClearRAM((u8*)strHEX,200);
                 //裝載產品ID到數據包                
                sprintf(str, "%02x%02x",((0xff00&(PROID_length))>>8),(0xff&PROID_length));
                strcat(mqtt_message,str);
                ClearRAM((u8*)str,200);  
                sprintf(str, "%s",PROID);
                Str2Hex((char*)str,(char*)strHEX);
                strcat(mqtt_message,strHEX);        
                ClearRAM((u8*)str,200); 
                ClearRAM((u8*)strHEX,200);
          //裝載產品ID到數據包                
                sprintf(str, "%02x%02x",((0xff00&(AUTH_INFO_length))>>8),(0xff&AUTH_INFO_length));
                strcat(mqtt_message,str);
                ClearRAM((u8*)str,200);  
                sprintf(str, "%s",AUTH_INFO);
                Str2Hex((char*)str,(char*)strHEX);
                strcat(mqtt_message,strHEX);        
                ClearRAM((u8*)str,200); 
                ClearRAM((u8*)strHEX,200);
                Str2Hex((char*)str,(char*)strHEX);
                strcat(mqtt_message,strHEX);
                strcat(mqtt_message,"\r\n");        
                return packetLen;    
}
//構建MQTT數據包 
u16 mqtt_SendData_message(char *mqtt_messageHEX,char *SendData,short length)
{
                char str[200];
                char strHEX[200];
                u16 packetLen=length+8;
          u16 SendData_length = strlen(SendData);
          strncpy((char*)(mqtt_messageHEX+strlen((char*)mqtt_messageHEX)),"30",2);
                sprintf(strHEX,"%02x",(packetLen));
                strcat(mqtt_messageHEX,strHEX);
                ClearRAM((u8*)str,200);   //清空commandAT數據包緩存,發送命令包含ip端口和長度
                ClearRAM((u8*)strHEX,200); //清空locationHex數據包緩存,轉換爲hex 需要發送的真實數據
                strcat(mqtt_messageHEX,"01000324647001");        
              //裝載json數據到數據包                
                sprintf(str, "%02x%02x",((0xff00&(SendData_length))>>8),(0xff&SendData_length));
                strcat(mqtt_messageHEX,str);
                ClearRAM((u8*)str,200);  
                sprintf(str, "%s",SendData);
                Str2Hex((char*)str,(char*)strHEX);
                strcat(mqtt_messageHEX,strHEX);        
                ClearRAM((u8*)str,200); 
                ClearRAM((u8*)strHEX,200);        
          return packetLen;    
}        

到此結束。有什麼不對的地方還望指正
MQTT ONEnet測試調試工具:https://www.amobbs.com/thread-5698272-1-1.html
Onenet平臺MQTT協議數據包生成器:關注微信公衆號“NNHPTCH”,南寧湖畔科技,回覆“Onenet平臺MQTT協議數據包生成器”

QQ羣:

796415884

歡迎大家進羣交流!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章