NB-IoT与OneNET平台HTTP通信

1.硬件条件

  1. NB-IoT模块,这里选用BC35-G模块,移动物联网卡
  2. STM32开发板,能进行串口通信
  3. OneNET平台账号,需在平台预先创建相应的设备

2.NB-IoT相关知识

NB-IoT作为5G时代下,专为物联网而生的新兴通信技术,支持低功耗设备在广域网进行蜂窝数据连接。简单来说,就是一个无线通信模块,类似于GSM模块。NB-IoT支持UDP、TCP连接。本文的HTTP是建立在TCP连接上的,只要支持TCP连接的NB-IoT模块都可以进行HTTP通信。

2.1 NB-IoT模块初始化

本文针对BC35-G模块进行讲解。NB-IoT初始化流程大致如下,通过串口向NB模块发送AT指令,本次案例采用手动注册入网的方式。​​​

AT+NRB模块重启*
AT+CMEE=1打开错误信息提示
AT+CIMI查询物联网卡号
AT+QREGSWT=2不用注册华为平台
AT+BAND=8设置为B8频段[移动]
AT+CFUN=1全功能开启,不然没法联网
AT+CEREG=2使能网络注册,并且要求返回状态信息
AT+CGATT=1触发入网
AT+CEREG?入网状态查询,返回"CEREG:2,1"表示入网成功
AT+CSQ信号质量检查

2.2 NB-IoT连接服务器

接下来需要NB-IoT模块与OneNET平台建立TCP连接,主要是两条指令,其中需要获取模块返回的具体参数!


    TCP_SOCKET[] = "AT+NSOCR=STREAM,6,13703,1\r\n"

 注:STREAM 表示TCP;6表示TCP;137103表示监听端口【范围0-65535 除5683外】;1表示要求创建的socket编号.

    sprintf(ServerAdd,"AT+NSOCO=%c,183.230.40.33,80\r\n",SocketNum);

 注:SocketNum是上一条指令具体返回的参数,如下图所示,需要在程序里判断再写入命令中!

后面的两个信息是OneNET平台的服务器地址和HTTP协议的端口、
接下来就是向服务器发送具体是数据了!


 sprintf(NSOSD,"AT+NSOSD=%c,%d,%s\r\n",socketnum,len,HTTP_Buf_HEXStr);

注:socketnum跟前面的socket编号一致;len:要发送的数据长度;HTTP_Buf_HEXStr:由于NB-IoT网络中的数据都是HEX-String的格式,所以要发送的数据都要转成HEX-String格式!

3. HTTP报文格式

报文原文格式。其中设备编号和api-key要根据OneNET平台生成的来填写。报文具体数据部分为JSON格式

POST /devices/设备编号/datapoints HTTP/1.1
api-key: swiY0T8eLGx2xLu9T8tlDH3QisY=
Host:api.heclouds.com
Content-Length:66

{"datastreams":[{"id":"temperature","datapoints":[{"value":38}]}]}

HEXString格式的报文如下,不用具体看: 

504F5354202F646576696365732F3532323135313434322F64617461706F696E747320485454502F312E310A6170692D6B65793A2073776959305438654C474132784C75395438746C444833516973593D0A486F73743A6170692E6865636C6F7564732E636F6D0A436F6E74656E742D4C656E6774683A36360A0A7B226461746173747265616D73223A5B7B226964223A2274656D7065726174757265222C2264617461706F696E7473223A5B7B2276616C7565223A33387D5D7D5D7D,1,1

格式转码 hex_to_hexstring函数:

void hex_to_hexstring(char* src, char* dst, int len)
{
    int i = 0, j = 0;

    for(i = 0, j = 0; j < len * 2; i++, j++)
    {
        //if((src[i]<=9)&&(src[i]>=0))
        if(src[i] <= 9)
        {
            dst[j] =  '0';
            dst[++j] = src[i] + '0';
        }

        else  if(src[i] >= 0x0A && src[i] <= 0x0F)
        {
            dst[j] =  '0';
            dst[++j] = src[i] + 55;
        }

        else if(src[i] >= 0x0F)
        {
            dst[j] =  src[i] / 16 + '0';

            switch(dst[j])
            {
            case '0': dst[j] = '0'; break;

            case '1': dst[j] = '1'; break;

            case '2': dst[j] = '2'; break;

            case '3': dst[j] = '3'; break;

            case '4': dst[j] = '4'; break;

            case '5': dst[j] = '5'; break;

            case '6': dst[j] = '6'; break;

            case '7': dst[j] = '7'; break;

            case '8': dst[j] = '8'; break;

            case '9': dst[j] = '9'; break;

            case ':': dst[j] = 'A'; break;

            case ';': dst[j] = 'B'; break;

            case '<': dst[j] = 'C'; break;

            case '=': dst[j] = 'D'; break;

            case '>': dst[j] = 'E'; break;

            case '?': dst[j] = 'F'; break;

            default : break;
            }

            dst[++j] =  src[i] % 16 + '0';

            switch(dst[j])
            {
            case '0': dst[j] = '0'; break;

            case '1': dst[j] = '1'; break;

            case '2': dst[j] = '2'; break;

            case '3': dst[j] = '3'; break;

            case '4': dst[j] = '4'; break;

            case '5': dst[j] = '5'; break;

            case '6': dst[j] = '6'; break;

            case '7': dst[j] = '7'; break;

            case '8': dst[j] = '8'; break;

            case '9': dst[j] = '9'; break;

            case ':': dst[j] = 'A'; break;

            case ';': dst[j] = 'B'; break;

            case '<': dst[j] = 'C'; break;

            case '=': dst[j] = 'D'; break;

            case '>': dst[j] = 'E'; break;

            case '?': dst[j] = 'F'; break;

            default : break;
            }
        }
    }

    strcat(dst, ",1,1\r\n");

    return;
}

4. 具体使用案例

  1. 首先准备好需要发送的数据,温湿度等信息
  2. 组成HTTP报文
  3. 通过串口发送
  4. 最后回去服务器返回信息
    sprintf(IoL, "%.2f", BH1750_test());
    printf("\r\n光照强度=%s\n",IoL); 
	
    sprintf(temperature, "%.2f", DS18B20_Get_Temp()*1.0/10); 
    printf("室温=%s\n",temperature);
	 		
    sprintf(humidity, "%d", get_YL_value_percent());		
    printf("土壤湿度=%s\n",humidity);
	 	     
    len = HTTP_PostPkt(HTTP_Buf, API_KEY, DEV_ID, "Temperature",temperature,
                                                   "Light",IoL,
                                                   "Humidity",humidity);   //HTTP组包
    hex_to_hexstring(HTTP_Buf,HTTP_Buf_HEXStr,len);//转换为hexstring格式
	 
    printf("send HTTP msg:\r\n%s\r\n", HTTP_Buf);
    sprintf(NSOSD,"AT+NSOSD=%c,%d,%s\r\n",socketnum,len,HTTP_Buf_HEXStr);

    printf("%s",NSOSD);
	 
     USART2_Clear();//串口清空
    SendHTTPData(USART2, (unsigned char *)NSOSD, strlen((const char *)NSOSD));    //报文发送

    Delay_ms(3000);
    printf("rcv response:\r\n%s\r\n", usart2_rcv_buf);

相关资源下载地址:

https://download.csdn.net/download/sinat_37853238/11235159

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我楚狂声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值