NB-IoT作为5G时代下,专为物联网而生的新兴通信技术,支持低功耗设备在广域网进行蜂窝数据连接。简单来说,就是一个无线通信模块,类似于GSM模块。NB-IoT支持UDP、TCP连接。本文的HTTP是建立在TCP连接上的,只要支持TCP连接的NB-IoT模块都可以进行HTTP通信。
本文针对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 | 信号质量检查 |
接下来需要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格式!
报文原文格式。其中设备编号和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;
}
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