NB-IOT模块与4G模块的区别是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NB-IOT模块与4G模块的区别是啥?相关的知识,希望对你有一定的参考价值。

我本人想要设计一个设备,需要上网、发短信和打电话功能。目前NB-IOT模块与4G模块除了网速区别,还有其他区别吗?NB-IOT模块可以打电话与发短信吗?NB-IOT是基于2G网、3G网还是4G网?
本人不是通信专业出身,因此不太懂这方面的知识,希望能用一些外行能听懂的话回答,谢谢

NB-IOT

NB-IOT使用的是DSSS调制,并非LTE无线电。由蜂窝网络构建而成的NB-IOT网络,带宽消耗大约只有180kHz,可直接部署于GSM网络、LTE网络等一系列网络,既降低了成本也方便了升级,License频段的使用支持带内、保护带以及独立载波等部署方式,与现有网络共存。

现在很多现场的基础设施都有将传感器数据做一个集合的网关,然后再通过网关与云端通信,将现场的数据远程传输给云端,对数据进行解析、存储和分析。


4G模组

基于4G通信技术的一个通信模组,具有高数据速率、宽带传输、无线即时通讯、兼容性高的特点,其核心变化是信息传输速率上面的变化。具备无线远程数传功能,且信息传输种类更加丰富,包括图片、音频、视频等,使得其在物联网应用市场被大家广泛应用。

参考技术A NB-IOT(简称NB)是基于LTE技术面向物联网市场的标准,虽然起源来自于4G,但它与4G在空口上是不同的,所以必须通过各自的网络来实现。
目前NB网络中是不支持语音业务的,可以短信,因为短信走信令,而且NB对于移动性支持不高,所以它主要适用于一些相对静止的物联网应用场景。追问

谢谢老哥的解答,另外我还想再问一下,eMTC和4G是一个网络吗?国内目前能用eMTC吗?

追答

是的,emtc是4G网络上通过终端实现的物联网技术

本回答被提问者和网友采纳

STM32F103学习笔记——NB-IoT模块BC26使用

一、简介

BC26 是一款高性能、低功耗、多频段 LTE Cat NB1/Cat NB2*无线通信模块。其尺寸仅为 17.7 mm × 15.8 mm × 2.0 mm,能最大限度地满足终端设备对小尺寸模块产品的需求,同时有效帮助客户减小产品尺寸并优化产品成本.BC26 在封装设计上兼容移远通信 GSM/GPRS 系列 M26 模块以及 NB-IoT 系列 BC28/BC25/BC260Y-CN 模块,方便客户快速、灵活的进行产品设计和升级。BC26 提供丰富的外部接口和协议栈,同时可支持中国移动 OneNET/Andlink、中国电信 IoT/ AEP以及阿里云IoT等物联网云平台,为客户的应用提供极大的便利。

BC26 采用更易于焊接的 LCC 封装,可通过标准 SMT 设备实现模块的快速生产,为客户提供可靠的连接方式,并满足复杂环境下的应用需求。

凭借紧凑的尺寸、超低功耗和超宽工作温度范围,BC26 成为 IoT 应用领域的理想选择,常被用于烟感、无线抄表、共享单车、智能停车、智慧城市、安防、资产追踪、智能家电、可穿戴设备、农业和环境监测以及其它诸多行业,以提供完善的短信和数据传输服务。

BC26资料:链接:https://pan.baidu.com/s/1n8rcRCna8wnMPFwikY3l0g?pwd=vgcm 提取码:vgcm

二、AT指令

发送数据时务必勾选:“加回车换行符”。否则模块不会响应。在本文中,仅显示响应,省略回车换行符。

2.1 AT

测试AT指令功能是否正常,等待模块返回 OK。

AT

OK

2.2 AT+CIMI

该命令用于查询(U)SIM 卡的国际移动用户识别码(IMSI,无双引号的字符串)。IMSI 允许 TE 识别连
接到 MT 的 USIM。

AT+CIMI

460001357924680

OK

2.3 AT+CGATT=1

设置命令用于将 MT 附着于 PS 域。命令完成后,MT 保持在 V.250 命令状态。如果 MT 已经处于请求状态,则忽略该命令,并且仍将响应 OK。如果 MT 无法实现请求状态,将响应 ERROR 或+CME ERROR。

AT+CGATT=1

OK

2.4 AT+CGATT?

查询命令返回当前 PS 域服务状态。

AT+CGATT=?

+CGATT: <state>
如:+CGATT: 1

OK

整型。PDP 上下文激活状态。

  • 0 去附着
  • 1 附着

2.5 AT+CEREG?

AT+CEREG?

+CEREG: <n>,<stat>
如:+CEREG: 0,1
如:+CEREG: 1,1

OK

整型。禁止或允许上报网络注册状态等信息。

  • 0 禁止上报网络注册状态 URC
  • 1 允许上报网络注册状态 URC +CEREG:
  • 2 允许上报网络注册状态和位置信息 URC +CEREG: [,[],[],[]]
  • 3 允许上报网络注册状态、位置信息和 EMM 原因值 URC +CEREG: [,[],[],[][,<cause_type>,<reject_cause>]]
  • 4 对于请求 PSM 的 UE,允许上报网络注册状态和位置信息 URC +CEREG: [,[],[],[][,[,[],[]]]]
  • 5 对于请求 PSM 的 UE,允许上报网络注册状态、位置信息和 EMM 原因值 URC +CEREG: [,[],[],[][,[<cause_type>],[<reject_cause>][,[, []]]]

整型。EPS 注册状态。

  • 0 未注册,MT 当前未搜索网络
  • 1 已注册,归属网络
  • 2 未注册,但 MT 当前正在尝试附着或搜索网络以进行注册
  • 3 注册被拒绝
  • 4 未知(例如:超出 E-UTRAN 覆盖范围)
  • 5 已注册,漫游状态

2.6 AT+QIPADDR

查询 UE 的 IP 地址

AT+QIPADDR

+QIPADDR: fe80:0:0:0:3c:ffb8:f4c9:1207

+QIPADDR: 2001:14bb:170:4c91:3c: ffh8:f4c9:1207

+QIPADDR: 178.55.211.180

+QIPADDR: 127.0.0.1

OK

2.7 AT+QIOPEN

该命令用于打开套接字服务。

  • AT+QIOPEN=?:查询命令参数。
  • AT+QIOPEN=,,<service_type>,<IP_address>/<domain_name>,<remote_port>[,<local_po CONNECTrt>[,<access_mode>]] :打开 Socket 服务。
    • :整数类型。上下文ID。范围是1-16。
    • :整数类型。套接字服务索引。范围是0-11。
    • <SERVICE_TYPE>:字符串类型。套接字服务类型。
      • “ TCP ” :作为客户端启动TCP连接
      • “ UDP ”:作为客户端启动UDP连接
      • “TCP LISTENER” :启动TCP服务器以侦听TCP连接
      • “UDP SERVICE” :启动UDP服务
    • <IP_address>:字符串类型。
      • 如果<service_type>是TCP或UDP ,则表示远程服务器的IP地址,例如 “220.180.239.212”。
      • 如果<service_type>是TCP LISTENER或UDP SERVICE 地址,请输入“127.0.0.1”。
    • <domain_name>:字符串类型。远程服务器的域名地址。
    • <remote_port> :远程服务器的端口,仅在<service_type>为“TCP”或“UDP”时有效。范围是0-65535。
    • <LOCAL_PORT> :本地端口。范围是0-65535。
      • 如果<service_type>是“TCP LISTENER”或“UDP SERVICE”,则此参数必须指定。
      • 如果<service_type>是“TCP”或“UDP”。如果<local_port>为0,那么本地端口将是自动分配。否则,将按指定分配本地端口。
    • <access_mode> :整数类型。套接字服务的数据访问模式。
      • 0: 缓冲区访问模式
      • 1:直推模式
      • 2:透明访问模式
    • :整数类型。操作的错误代码。请参阅第4章。
AT+QIOPEN=1,0,\\"TCP\\",\\"180.97.81.180\\",53540,0,1

OK

+QIOPEN: 0,0

Buffer模式,Push模式,透传模式。通过参数<access_mode>进行配置。





2.8 AT + QISEND

如果指定套接字服务的<access_mode>是缓冲区访问模式或直接推送模式,则数据可以是通过AT + QISEND发送。如果数据成功发送到模块,将返回“ SEND OK ” 。否则它将返回“ SEND FAIL ” 或“ ERROR ” 。“ SEND FAIL ” 表示发送缓冲区已满客户可以尝试重新发送数据。“ERROR”表示在发送过程中遇到错误 数据。客户应该延迟一段时间来发送数据。最大数据长度为1460字。“SEND OK”并不意味着数据已成功发送到服务器。客户可以查询数据是否通过AT + QISEND = ,0命令到达服务器。透传模式下不需要AT指令发送数据

三、TCP应用时序图

四、复位模块

通过拉低 RESET 引脚至少 50ms 可以使模块复位。

五、移植文件

5.1 board_bc26.c

/*********************************************************************
 * INCLUDES
 */
#include "stdlib.h"
#include "string.h"
#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h" 

#include "board_bc26.h" 

static uint8_t sendCmd(char *pCmd, char *pRes, char *pRes2, uint32_t timeOut, uint8_t sendNum);
static void clearBuffer(void);
static void reset(void);

/*********************************************************************
 * GLOBAL VARIABLES
 */  
uint8_t g_usart2RecvFinish = 0;                                                 // 串口2接收标志串口接收完成标志
char g_bc26Buf[1024] = 0;                                                     // 接收缓存
volatile uint32_t g_bc26Cnt;                                                    // 接收计数                                 

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/**
 @brief 初始化
 @param 无
 @return 1 - 成功;0 - 失败
*/
uint8_t BC26_Init(void)
		
    printf("BC26_Init\\r\\n");
    uint8_t result = 0;
    uint8_t step = 0;
    switch(step)
    
        case 0:
            if(sendCmd("AT\\r\\n", "OK", NULL, 10, 6))                            // 测试AT指令功能是否正常
            
                step++;
            
            else
            
                printf("Err:AT\\r\\n");
                reset();
                break;
             
        case 1:
            if(sendCmd("AT+CIMI\\r\\n", "OK", NULL, 20, 1))                       // 查询SIM卡是否正常,返回OK则表示SIM卡正常
            
                step++;
            
            else
            
                printf("Err:AT+CIMI\\r\\n");                                      // 20秒内,无法识别SIM状态,重启模块
                reset();
                break;
            
        case 2:
            if(sendCmd("AT+CGATT=1\\r\\n", "OK", "+IP:", 60, 1))                  // 激活PDP场景
            
                step++;                                                 
            
            else
            
                printf("Err:AT+CGATT=1\\r\\n");        
                step++;                                                         
            
        case 3:
            if(sendCmd("AT+CEREG?\\r\\n", "+CEREG: 0,1", "+CEREG: 1,1", 60, 3))   // 查询模组是否注册上EPS网络
            
                step++;                                                 
            
            else
            
                printf("Err:AT+CEREG?\\r\\n");      
                step++;                                                         
            
        case 4:
            if(sendCmd("AT+CGATT?\\r\\n", "+CGATT: 1", NULL, 85, 3))              // 查询当前PS域服务状态
            
                step++;
            
            else
            
                printf("Err:AT+CGATT?\\r\\n");                                    // 如果3次都没停止成功或超过85秒没有回应,则重启模块
                reset();
                break;
            
        case 5:
            if(sendCmd("AT+QIPADDR\\r\\n", "+QIPADDR:", NULL, 60, 3))             // 查询本机IP地址
            
                BC26_Connect();
                result = 1;
            
            else
            
                printf("Err:AT+QIPADDR\\r\\n");                                   // 如果3次都没停止成功或超过60秒没有回应,则重启模块
                reset();
                break;
            
    
    return result;


/**
 @brief 复位引脚配置
 @param 无
 @return 无
*/
void BC26_GpioConfig(void)

    GPIO_InitTypeDef gpioInitStructure;		
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                       // 使能GPIO
    gpioInitStructure.GPIO_Pin = GPIO_Pin_8;                                    // 选择要初始化的GPIOB引脚PB8
    gpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                             // 设置引脚工作模式为通用推挽输出 		
    gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;                            // 设置引脚输出最大速率为50MHz
    GPIO_Init(GPIOB, &gpioInitStructure);	    

    GPIO_SetBits(GPIOB, GPIO_Pin_8);


/**
 @brief 连接TCP服务器
 @param 无
 @return 无
*/
void BC26_Connect(void)

    if(sendCmd("AT+QICLOSE=0\\r\\n", "OK", NULL, 20, 1))                          // 关闭TCP连接
    
        if(sendCmd("AT+QIOPEN=1,0,\\"TCP\\",\\"180.97.81.180\\",53540,0,1\\r\\n", "+QIOPEN:", 150, 5))    
        
            printf("Connect Success\\r\\n");
              
        else
        
            printf("Err:AT+QIOPEN=1,0\\r\\n");
            reset();                                                            // 没有响应重启模块
               
    


/**
 @brief 发送数据到TCP服务器
 @param pString -[in] 发送数据
 @return 无
*/
void BC26_Send(char *pString)

    if(sendCmd("AT+QISEND=0\\r\\n", ">", NULL, 30, 2))                            // 等待60秒,没有响应重启模块                            
    
        vTaskDelay(500);                                                        // 等待500ms
        char sendBuf[1024] = 0;
        sprintf(sendBuf, "%s\\r\\n\\x1A", pString);
        if(sendCmd(sendBuf, "SEND OK", "OK", 30, 2))
        
            if(sendCmd("AT+QISEND=0,0\\r\\n", "+QISEND:", NULL, 5, 24))           // 2分钟后(每5秒查询一次,共24次)
                
                /* 发送数据成功,对方收到数据 */
            
            else
            
                printf("Err:AT+QISEND=0\\r\\n");                                      
                if(sendCmd("AT+QICLOSE=0\\r\\n", "OK", NULL, 20, 1))              // TCP连接出现异常,关闭TCP连接
                
                    printf("AT+QICLOSE\\r\\n");
                    BC26_Connect();
                
            
        
        else
        
            BC26_Reset();                                                       // 等待60秒,没有响应重启模块
         
    
    else
    
        BC26_Reset();                                                           // 等待60秒,没有响应重启模块    
    


/**
 @brief 从TCP服务器接收数据
 @param pRecvDataBuf -[out] 接收数据
 @return 接收数据长度
*/
uint32_t EC200S_Receive(char *pRecvDataBuf)

    uint32_t recvDataLen = 0;
    if(g_isUsart2RecvFinish)                                                    // 如果串口接收完成
    
        if(strstr((const char *)g_bc26Buf, "+QIURC: \\"recv\\",0,") != NULL)      // 如果检索到关键词
        
            memcpy(pRecvDataBuf, g_bc26Buf, g_bc26Cnt);
            recvDataLen = g_bc26Cnt;
        
        else if(strstr((const char *)g_bc26Buf, "+QIURC: \\"closed\\",0,") != NULL)
        
            BC26_Reset();
        
        clearBuffer();
    	
    return recvDataLen;


/**
 @brief 重启模块
 @param 无
 @return 无
*/
void BC26_Reset(void)

    reset();


/*********************************************************************
 * LOCAL FUNCTIONS
 */
/**
 @brief 发送AT命令
 @param pCmd -[in] 命令字符串
 @param pRes -[in] 需要检测的返回命令字符串
 @param pRes2 -[in] 需要检测的返回命令字符串
 @param timeOut -[in] 等待时间
 @param sendNum -[in] 命令发送次数
 @return 1 - 成功;0 - 失败
*/
static uint8_t sendCmd(char *pCmd, char *pRes, char *pRes2, uint32_t timeOut, uint8_t sendNum)

    uint8_t i = 0;
    uint32_t time;
    clearBuffer();                                                              // 清空缓存	
    for(i = 0; i < sendNum; i++)
	
        time = timeOut * 10;
        USART_SendString(USART2, pCmd);
        while(time--)
        
            if(g_usart2RecvFinish)                                              // 如果串口接收完成
            
                if(strstr((const char *)g_bc26Buf, pRes) != NULL)               // 如果检索到关键词
                
                    printf("%s", g_bc26Buf);
                    return 1;
                
                else if(strstr((const char *)g_bc26Buf, pRes2) != NULL))       // 如果检索到关键词2
                
                    printf("%s", g_bc26Buf);
                    return 1;
                
            	
			vTaskDelay(100);                                                   // 等待100毫秒
        
        clearBuffer();
    
    return 0;


/**
 @brief 清空缓存
 @param 无
 @return 无
*/
void clearBuffer(void)

    memset(g_bc26Buf, 0, sizeof(g_bc26Buf));
    g_bc26Cnt = 0;
	g_usart2RecvFinish = 0;


/**
 @brief 重启模块
 @param 无
 @return 无
*/
void reset(void)

	printf("reset\\n");
    
    GPIO_ResetBits(GPIOB, GPIO_Pin_8);
    vTaskDelay(60);
    GPIO_SetBits(GPIOB, GPIO_Pin_8);


/****************************************************END OF FILE****************************************************/

5.2 board_bc26.h

#ifndef _BOARD_BC26_H_
#define _BOARD_BC26_H_

/*********************************************************************
 * INCLUDES
 */
#include "stm32f10x.h"

/*********************************************************************
 * GLOBAL VARIABLES
 */  
extern uint8_t g_usart2RecvFinish;      // 串口2接收标志串口接收完成标志
extern char g_bc26Buf[1024];            // 接收缓存
extern uint32_t g_bc26Cnt;              // 接收计数

/*********************************************************************
 * API FUNCTIONS
 */
uint8_t BC26_Init(void);
void BC26_GpioConfig(void);
void BC26_Connect(void);
void BC26_Send(char *pString);
uint32_t BC26_Receive(char *pRecvDataBuf);
void BC26_Reset(void);

#endif /* _BOARD_BC26_H_ */

六、使用方法

BC26_GpioConfig();
BC26_Init();
while(1)                                                            // 任务都是一个无限循环,不能返回

    BC26_Send("TEST");
    vTaskDelay(10000);  
    char recvDataBuf[256] = 0;
    int recvDataLen = BC26_Receive(recvDataBuf);           

/**
 @brief 串口2收发中断
 @param 无
 @return 无
*/
void USART2_IRQHandler(void)

    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)                           // 接收中断
    
        g_usart2RecvFinish = 1;                                                   // 串口2接收标志

        if(g_bc26Cnt >= sizeof(g_bc26Buf))
        
            g_bc26Cnt = 0;                                                        // 防止串口被刷爆
        

        g_bc26sBuf[g_bc26Cnt++] = USART2->DR;
		
        USART_ClearFlag(USART2, USART_FLAG_RXNE);
     				 											 


• 由 Leung 写于 2022 年 8 月 26 日

• 参考:移远BC35-G模组(NB-IoT 通信模组)AT指令测试 UDP 通信过程
    NB-IOT(BC26)相关AT指令——UDP/TCP传输
    NB260软件设计手册

以上是关于NB-IOT模块与4G模块的区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章

wifi模块和4g模块有啥区别?

4g模块从stm32得到数据发送到电脑是啥意思

怎么用stm32这样的单片机控制4G模块

什么是4G模块,4G模块是什么

4G模块是什么 4G模块的工作原理

4G DTU工作原理是啥