3. 网络注册状态查询

网络注册状态查询 学习卡片

任务说明

本案例目标为:通过AT指令AT+CREG?查询模块当前网络注册状态,根据返回值判断模块是否成功附着到LTE网络,并针对不同注册状态给出处理建议。实现方式为串口发送指令并解析响应,适用于LTE Cat1/Cat4模块(如EC200U、Air724UG、ML302等)的AT指令开发场景。

AT+CREG指令说明

AT+CREG?用于查询网络注册状态,返回格式为:

+CREG: <n>,<stat>

其中<n>为查询模式(通常为0或1),<stat>为注册状态码,含义如下:

stat值含义是否附着成功
0未注册,正在搜索网络否
1已注册,归属地网络是
2未注册,正在搜索但超时否
3注册被拒绝否
4未知状态否
5已注册,漫游状态是

代码实现

以下代码通过串口发送AT+CREG?并解析响应,输出注册状态及对应处理建议。代码使用Python的pyserial库,适用于PC通过USB转串口与模块通信的场景。

import serial
import time
import re

def query_creg(port: str, baudrate: int = 115200, timeout: float = 2.0) -> dict:
    """
    发送AT+CREG?并解析注册状态
    
    参数:
        port: 串口号,如 'COM3' 或 '/dev/ttyUSB0'
        baudrate: 波特率,默认115200
        timeout: 串口超时时间(秒)
    
    返回:
        dict: 包含 'raw_response' 原始响应和 'stat' 注册状态码
    """
    try:
        ser = serial.Serial(port, baudrate, timeout=timeout)
    except serial.SerialException as e:
        return {'error': f'串口打开失败: {e}'}
    
    # 清空缓冲区
    ser.reset_input_buffer()
    
    # 发送查询指令
    cmd = 'AT+CREG?\r\n'
    ser.write(cmd.encode('ascii'))
    
    # 读取响应(最多等待1秒)
    time.sleep(0.5)
    response = ser.read(ser.in_waiting).decode('ascii', errors='ignore')
    ser.close()
    
    # 解析响应
    match = re.search(r'\+CREG:\s*(\d+),(\d+)', response)
    if match:
        n = int(match.group(1))
        stat = int(match.group(2))
        return {
            'raw_response': response.strip(),
            'n': n,
            'stat': stat
        }
    else:
        return {
            'raw_response': response.strip(),
            'error': '未找到+CREG响应,请检查模块是否支持该指令或串口连接'
        }

def interpret_stat(stat: int) -> str:
    """根据注册状态码返回处理建议"""
    if stat == 0:
        return '未注册,正在搜索网络。请等待5-10秒后重试查询。'
    elif stat == 1:
        return '已注册到归属地LTE网络,附着成功。'
    elif stat == 2:
        return '未注册,搜索超时。请检查天线连接、SIM卡是否欠费或所在区域信号覆盖。'
    elif stat == 3:
        return '注册被拒绝。请检查SIM卡是否有效、是否被运营商限制,或APN配置是否正确。'
    elif stat == 4:
        return '未知状态。建议重新上电或执行AT+CFUN=1重新初始化射频。'
    elif stat == 5:
        return '已注册到漫游LTE网络,附着成功(漫游状态)。'
    else:
        return f'未定义状态码: {stat}'

if __name__ == '__main__':
    # 示例:查询串口 /dev/ttyUSB0 的注册状态
    result = query_creg('/dev/ttyUSB0')
    
    if 'error' in result:
        print(f'查询失败: {result["error"]}')
    else:
        print(f'原始响应: {result["raw_response"]}')
        print(f'注册状态码: {result["stat"]}')
        print(f'判定结果: {interpret_stat(result["stat"])}')

代码说明

代码核心逻辑分为三部分:

  1. 串口通信:使用pyserial打开指定串口,发送AT+CREG?\r\n,等待500ms后读取全部响应数据。
  2. 响应解析:通过正则表达式\+CREG:\s*(\d+),(\d+)提取n和stat值。若响应中无匹配内容,则返回错误信息。
  3. 状态判定:interpret_stat()函数根据stat值返回对应处理建议。其中stat=1和stat=5表示附着成功,其余状态均需排查问题。

运行与验证

依赖安装:

pip install pyserial

运行方法:

  1. 将LTE模块通过USB转串口连接到电脑,确认设备管理器中的串口号(Windows)或ls /dev/ttyUSB*(Linux)。
  2. 修改代码末尾的串口号为实际值,例如'COM5'或'/dev/ttyUSB0'。
  3. 执行脚本:python creg_query.py

验证判定标准:

  • 若模块已插入有效SIM卡且处于LTE信号覆盖区域,预期输出中注册状态码为1或5,并显示“附着成功”。
  • 若未插SIM卡或信号差,状态码可能为0或2,输出对应排查建议。
  • 若串口打开失败,输出包含“串口打开失败”的错误信息。

注意:实际状态码取决于模块当前所处环境,上述预期仅针对正常附着场景。若需确认模块是否已启用RF功能,可先发送AT+CFUN=1再执行本查询。

状态处理流程

AT+CREG? 注册状态处理流程 发送 AT+CREG? 解析 +CREG: <n>,<stat> stat=1 或 5? 是 附着成功 可进行数据业务 否 未附着成功 按状态码排查 不同状态码处理建议 stat=0 搜索中 等待重试 stat=2 搜索超时 查天线/SIM stat=3 注册拒绝 查SIM/APN stat=4 未知状态 重启模块 stat=5 漫游注册 附着成功 其他 未定义 查手册

常见问题排查

  • 返回ERROR:模块可能不支持AT+CREG?,或当前处于飞行模式。先发送AT+CFUN=1开启射频,再重试。
  • 长时间无响应:检查串口波特率是否匹配(模块默认通常为115200或9600),以及模块是否已上电并完成开机注册流程(约需5-15秒)。
  • 状态码在0和2之间切换:说明信号不稳定或SIM卡未正确识别,可检查天线连接和SIM卡触点。