开发准备
硬件:
- 一块 QuecPython_EC2X_EVB 开发板 (以该开发板为例,更多开发板介绍参见下文开发板列表)
- USB 数据线 (USB-A TO USB-C)
- PC (Windows10)
蜂窝模组开发板列表:
- EC2X_EVB
- EC600X_EVB
- EC800X_EVB
- EC600X/EC800X_CORE_EVB
- BG95_EVB
- EC200X_EVB
- EG91X_EVB
- EC600U_235_EVB
- BG95/EG915U/EG912U_CORE_EVB
- EC800G_HUA_EVB
- EC800X_DUINO_EVB
- EC800X_PICO_EVB
软件:
- 下载安装 USB驱动,用于开发调试QuecPython模组
- 下载调试工具 —— QPYcom - QuecPython全栈式开发调试工具
- 获取下载 QuecPython 固件和相关软件资源
- 安装Python语言的 文本编辑器,例如 VSCode
设备上手:
根据使用的设备参考上文的开发板列表完成设备的上电开机(包括天线安装、SIM卡安装、连接电源、开机等)
驱动准备
驱动下载
驱动程序(device driver)全称为“设备驱动程序”,是一种可以使计算机和设备通信的特殊程序,操作系统只能通过这个接口,才能控制硬件设备的工作。
- 打开QuecPython官网驱动下载链接
- 进入页面后先选择驱动栏,然后在驱动栏选择与自己模组型号和电脑系统匹配的驱动,不同平台的模组所需要的驱动程序不一致,需要根据模组型号去下载对应的驱动包
- 模组型号可以通过模组上的镭雕获取,也可以通过AT指令获取,镭雕如下图所示,镭雕上型号为EG912U
- 左侧筛选栏选择
EG912U,可以筛选出该型号的USB驱动QuecPython_USB Driver Win10_U_G)点击下载按钮下载驱动:
驱动安装
下载后解压驱动压缩包,找到"setup.exe" 或者是"setup.bat",双击运行即可,安装完之后打开设备管理器就可以看到设备管理器中端口的黄色感叹号消失了,说明安装成功,能够正常通信。
出现 Mobile ECM Network Adapter 或 CDC Ethernet Control Modle (ECM) 等设备未被识别属于正常现象,不影响固件烧录和后续开发,无需理会。
右键打开【我的电脑】——选择【管理】——选择【设备管理器】,然后在设备管理器中选择 【端口】
按照步骤打开页面后如图所示能刷新出Quectel USB 名称开头的串口则USB驱动安装成功
安装驱动后:
驱动安装常见问题参考: 开发环境与工具相关问题
获取工具
QPYcom获取
使用QuecPython进行开发需要用到专用的开发调试工具——QPYcom,包括但不限于调试代码、分析日志、文件传输、烧录固件、合并固件等。
QPYcom : 适用于QuecPython开发的一站式调试工具
注意:该工具无需安装,解压即用。
安装VSCode插件
编辑Python代码一般会用到专用于Python或者兼容多种语言的IDE,可以有效提升开发效率,这里推荐VSCode
针对VScode,QuecPython推出专用插件实现代码提示、代码补全和串口调试等功能,安装方法见下图
- 在VSCode中点击侧边栏插件市场,在插件市场中搜索 “QuecPython”,根据搜索结果下载该插件即可
- 在VSCode插件商店网站 搜索“QuecPython”,根据搜索结果下载该插件后会自动打开VSCode并安装
固件烧录
获取固件
模组在出厂时通常烧录有标准 AT 固件或 QuecOpen 固件,如需基于 QuecPython 对模块进行开发,需要手动为其重新烧录专门的 QuecPython 固件。
官网固件下载地址:资源下载 | QuecPython
面对官网种类众多的固件,如何选择合适的固件包,首先需要知道使用的模组的型号,模组型号可以通过模组的镭雕或者发送AT指令来获得。
在获取到模组型号之后根据模组的型号去官网下载该模组对应的固件即可。
固件的名称一般为QPY_OCPU_模组型号_FW,例如QPY_OCPU_EC800M_CNGC_FW,如果是EC800M_CNGC的模组就可以下载这个固件,并且可以在版本这一列选择想要下载的固件版本,固件的版本号格式统一为V+四位数版本号,例如V0001
点击下载列的下载按钮即可下载,下载成功后会得到一个固件名称命名的压缩包文件(zip包)
从官网下载的固件包为压缩包格式,固件压缩包下载到本地后,需进行解压。解压后可获得两个文件,其中 .bin 、.lod或 .pac 格式的是 QuecPython 固件本体,.md 格式的是更新日志。
固件解压后的本体文件有以下后缀区分(官网发布日期于2024.05.20之后的固件,所有模组型号固件已统一为.bin后缀)
| 固件下载文件名称后缀 | 固件文件对应模组型号 | 备注 |
|---|---|---|
| zip、bin | EC600M、EC600N、EG915N、EC200N、EG810M | 固件压缩包解压后可得 |
| pac | EC600U、EC200U、EG912U、EC800G、EC600G | 固件压缩包解压后可得 |
| lod | BC25 | 固件压缩包解压后可得 |
| binpkg | EC600E、EC800E | 解压后固件名称同名文件夹内 |
| hbinpkg | EC800Z | 解压后固件名称同名文件夹内 |
| blf | EC200A | 解压后固件名称同名文件夹内 |
| mbn | BG95 | 解压后固件名称同名文件夹内 |
请务必将压缩包内容解压至一个不包含中文、空格和其他特殊字符的路径下,否则下载工具可能无法正常识别到固件,同时下载工具路径也不可包含中文、空格和其他特殊字符。
烧录固件
- Step1:创建项目
首先确保模组连接正常并已开机,打开QPYcom工具进入下载页面,点击"创建"项目,新建要下载的固件项目,项目名称自定义,配置完成后持久化保存
- Step2:选择固件
选择要下载到模组的固件(根据要下载的模组型号选择对应的固件,若为新格式固件则所有模组型号都选择.bin文件即可)
其中BG95系列选择官网下载固件包解压后mbn结尾的文件,M/N系列选择官网下载固件包解压后的bin文件,U/G系列模组选择解压后的PAC文件,BC25选择lod文件,A系列选择blf文件,E系列选择binpkg文件
- Step3:设置下载模式
单击“Download script”右侧的下拉选择箭头,选择"Download FW"
- Step4:开始烧录固件
点击"Download FW"后,开始下载固件,下载过程会有进度条和进度百分比显示,等待下载完毕会有弹窗提示下载成功
| 模组型号 | 注意事项 |
|---|---|
| BC25 | 需要打开固件下载串口后再点击"Download FW",直接点击会提示打开串口 |
| BG95 | 需要打开DM串口后再点击"Download FW",直接点击会提示打开串口 |
| FCM360W | 需要打开串口后点击"Download FW"后等待进度条出现后再按下开发板“RESET”按钮开始下载固件 |
| EC600E | 需要短接开发板 BOOT 和 GND 并按下开发板“RESET”按钮出现下载口后,立即点击"Download FW"开始下载固件 |
| EC800E | 需要短接开发板 EXT 和 GND 并按下开发板“RESET”按钮出现下载口后,立即点击"Download FW"开始下载固件 |
| EC800Z | 需要短接开发板 BOOT 和 EXT 并按下开发板“RESET”按钮出现下载口后,立即点击"Download FW"开始下载固件 |
REPL调试
REPL全称为Read-Eval-Print-Loop (交互式解释器),可以在REPL中进行QuecPython程序的调试
运行 QPYcom 工具后,选择正确的串口(波特率无需指定)并打开,即可开始 Python 命令行交互。
- Step1:进入交互页面
进入交互页面首先需要打开USB交互口,注意不同平台交互口名称有差异
以EC600N/M系列模组举例,打开QPYcom工具,端口选择连接Quectel USB REPL Port,选择“交互”界面
| 模组 | 交互口名称 | 驱动名称 |
|---|---|---|
| EC600N/M EC200A | Quectel USB REPL Port | QuecPython_USB_Driver_Win10_ASR |
| EC200U EC600U/G EG800G EG912U EG915U | Quectel USB REPL Port | QuecPython_USB_Driver_Win10_U_G |
| BG95/BG600L | Quectel USB REPL Port | QuecPython_USB_Driver_Win10_BG |
| EC600E,EC800E | Quectel USB 串行设备 | QuecPython_USB_Driver_Win10_E |
注意只有使用最新版本的固件和新版本的驱动才会显示 Quectel USB REPL Port
在老版本的固件和驱动上串口的显示名称会根据平台的不同有所区别
其中U、G系列模组交互口名称为Quectel USB Serial-1 Port
N/M、A系列模组交互口名称为Quectel USB MI05 COM Port
BG95、BG600L系列模组交互口名称为Quectel USB NEMA Port
- Step2:打开串口
点击“打开串口”按钮,在交互界面输入print(‘hello world’),按回车后可以看到执行的结果信息
<span style="color:#262626"><span style="background-color:#ffffff"><span style="background-color:#2d2d2d"><span style="color:#cccccc"><code class="language-python"><span style="color:#67cdcc">>></span><span style="color:#67cdcc">></span> <span style="color:#cc99cd">print</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'hello world'</span><span style="color:#cccccc">)</span>
hello world
</code></span></span></span></span>
注意:工具交互页面输入时需要输入英文字符,中文字符将会被屏蔽
开发第一个脚本
编写第一个脚本文件
创建helloworld.py文件输出“hello world”,打印“hello world”,编写脚本如下所示:
<span style="color:#262626"><span style="background-color:#ffffff"><span style="background-color:#2d2d2d"><span style="color:#cccccc"><code class="language-python"><span style="color:#cc99cd">print</span><span style="color:#cccccc">(</span><span style="color:#7ec699">"hello world"</span><span style="color:#cccccc">)</span>
</code></span></span></span></span>
通过QPYcom将上面编辑好的文件下载到模组中去并运行
PC与模组间的文件传输
下载方法一:
- Step1:打开串口
首先选择模组的交互口,点击"打开串口"按钮
- Step2:通过工具按钮下载
可以通过文件页面右侧上面的 "+","-" 按钮来上传和删除文件
- Step3:通过拖拽形式下载
也可以通过拖拽的方式将文件页面左侧显示的本地文件直接拖拽到右侧模组中去(也可以拖拽文件夹)
- Step4:下载进度和结果
下载过程中会在状态栏显示下载文件名和下载进度
下载方法二:
- Step1:创建项目
根据需求,创建用户项目(点击"创建"按钮),步骤同上文烧录固件
- Step2:配置要下载的文件
选择需要下载到模块的用户脚本(在"用户脚本"区域通过右键菜单添加)
- Step3:设置下载模式
左击下拉选择箭头,选择"下载脚本",即"Download Script"
- Step4:开始下载脚本
点击"下载脚本"开始下载脚本,下载过程中有进度条提示
执行脚本文件
- Step1:下载脚本
将要执行的脚本文件下载到模组中去,具体步骤参考上文
- Step2:通过repl执行脚本
打开串口之后,在QPYcom交互页面输入以下代码执行脚本文件
<span style="color:#262626"><span style="background-color:#ffffff"><span style="background-color:#2d2d2d"><span style="color:#cccccc"><code class="language-python"><span style="color:#cc99cd">import</span> example
example<span style="color:#cccccc">.</span><span style="color:#cc99cd">exec</span><span style="color:#cccccc">(</span><span style="color:#7ec699">"/usr/helloworld.py"</span><span style="color:#cccccc">)</span> <span style="color:#999999"># filePath为要执行的脚本文件路径</span>
</code></span></span></span></span>
- Step3:通过GUI工具执行脚本
或者通过QPYcom文件页面 执行 按钮执行脚本文件,在工具的文件页面选择要执行的脚本文件然后点击 "▷"按钮
执行结果如图
停止程序运行
如何停止正在运行的程序,根据运行的脚本文件类型有以下方法:
| 程序名是否 为main.py | 程序中是否 包含了死循环 | 程序中是否 使用了多线程 | 停止步骤 |
|---|---|---|---|
| ✓ | ✓ | ✓ | (1)按 Ctrl + A 键进入 RAW 模式 (2)按 Ctrl + D 键重启 QuecPython 虚拟机 (3)按 Ctrl + B 键回到普通交互模式 (4)若以上方法无效,请重新烧录固件 |
| ✗ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件 | ||
| ✗ | ✓ | (1)按 Ctrl + A 键进入 RAW 模式 (2)按 Ctrl + D 键重启 QuecPython 虚拟机 (3)按 Ctrl + B 键回到普通交互模式 (4)若以上方法无效,请耐心等待程序运行结束 | |
| ✗ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件 | ||
| ✗ | ✓ | ✓ | (1)按 Ctrl + D 键重启 QuecPython 虚拟机 (2)若以上方法无效,请直接重启模块 |
| ✗ | (1)按 Ctrl + D 键重启 QuecPython 虚拟机 (2)若以上方法无效,请直接重启模块 | ||
| ✗ | ✓ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件或直接重启模块 | |
| ✗ | (1)按 Ctrl + C 键打断程序运行 (2)若以上方法无效,请重新烧录固件或直接重启模块 |
蜂窝基础开发
本章节主要介绍 QuecPython 模组的拨号上网流程,拿到模组后如何注网拨号以及网络异常的处理等
QuecPython 拨号上网流程
设备硬件连接
首先按照上文的硬件准备步骤安装开发板配套的天线(部分开发板型号有板载天线的不需要安装),并将SIM卡插入开发板上的SIM卡座,然后将模组连接电源并开机,开机后模组会自动进行网卡激活。
获取拨号信息
QuecPython的模组默认开机都会自动激活第一路蜂窝无线网卡,只有蜂窝无线网卡激活成功,才能进行socket、http、mqtt等网络业务。
所以在业务动作之前需要先获取拨号信息,包括拨号状态、IP地址、DNS服务器地址等,以此来判断网卡是否激活成功
import dataCall
dataCall.getInfo(profileID, ipType)
# profileID - PDP上下文ID,整型值,范围1~3。
# ipType - IP协议类型,整型值,0:IPV4 1:IPV6 2:IPV4&IPV6
返回值格式为
(profileID, ipType, [state, reconnect, addr, priDNS, secDNS])
查询网卡状态信息这一操作,是用户必须进行的。不管是什么应用场景,只要用户需要进行网络业务操作,就必须先查询网卡激活状态,确认蜂窝无线网卡已经激活成功。具体而言,只要用户有如下需求,都需要使用dataCall.getInfo来查询:
- 确认蜂窝无线网卡激活是否成功,通过
dataCall.getInfo方法返回值的state来确定,为1表示激活成功。 - 用户使用QuecPython的socket功能时,需要知道模组当前的IP地址。
- 激活多路蜂窝无线网卡后,需要建立多路socket,不同的socket使用不同的网卡,此时需要获取每一路网卡的IP地址信息,然后与对应的socket进行绑定。
- 获取蜂窝无线网卡当前使用DNS地址。
如果获取拨号信息发现网卡激活失败则需要手动激活网卡
手动激活网卡
经过上述的查询处理后如果网卡激活失败则需要手动激活网卡,使用如下的API来手动激活网卡
dataCall.activate(profileID)
# profileID - PDP上下文ID,整型值,范围1~3。
QuecPython的模组默认开机都会自动激活蜂窝无线网卡,正常情况无需手动设置激活或者去激活操作,但是一些特殊场景或者用户的特殊需求,需要使用上述方法来手动激活或者去激活蜂窝无线网卡,比如:
用户关闭了开机自动激活蜂窝无线网卡功能,由用户应用程序根据需要在某个时间进行网卡的激活和去激活操作。这种情况下,就需要用户在其应用程序中,根据需要来调用dataCall.activate和dataCall.deactivate方法。
获取SIM卡状态
如果模组蜂窝无线网卡手动激活失败,需要依次排查SIM卡和注网状态,查询SIM状态需要使用以下API来获取
import sim
sim.getStatus()
如果sim.getStatus()的返回值为0,说明设备没有检测到SIM卡,此时需要确定是否插入了SIM卡。如果用户已经插入SIM卡并且重启设备后,查询状态值还是0,那可能的原因如下:
- SIM卡没有插好,比如插反了、没有插紧。可以重新插入SIM卡并重启设备,开机后再次查询SIM卡状态是否为1。
- SIM卡本身有损坏。可以换一张可以正常使用的SIM卡插入后,重启设备,然后再次查询SIM卡状态是否为1。
- SIM卡卡槽有损坏。如果确认是这个问题,则需要更换新的卡槽。
- SIM卡的硬件电路存在问题,比如接触不良,导致设备无法正常识别SIM卡。需要硬件工程师检查电路确认问题。
用户可以依次排查上面几种情况来确认问题。
如果返回值为1,说明已经检测到SIM卡,则需要检测注网状态
其他状态的SIM卡异常参考SIM卡异常处理
获取设备网络注册状态
设备的蜂窝无线网络注册状态是非常重要的参数。成功激活蜂窝无线网卡的前提,就是设备必须先注网成功。QuecPython提供了相关API用来查询设备的注网状态。通过该API可以查询当前设备的网络状态
import net
net.getState()
API返回值为
([voice_state, voice_lac, voice_cid, voice_rat, voice_reject_cause, voice_psc], [data_state, data_lac, data_cid, data_rat, data_reject_cause, data_psc])
其中data_state为网络注册状态,网络注册状态有多种情况,当返回值为1或者5时可视为网络注册成功,具体返回值参考获取网络注册信息,当网络注册状态不为1或5的情况,可视为网络异常,导致网络异常的原因可能有多种,比方说SIM卡欠费、SIM卡只支持特定网络制式或者特定频段等、射频性能不好、没有配置APN等,以上异常的情况的详细处理步骤参考模块网络注册失败
正常情况下,只要模组网卡能激活成功,用户是不需要查询注网状态的。需要查询设备注网状态的场景主要如下:
- 模组蜂窝无线网卡激活失败,需要依次排查SIM卡和注网状态。此时可以使用
net.getState来查询注网状态,确认设备注网有没有成功,如果注册网络状态异常则需要按照上述步骤继续检查。
网络状态检测
QuecPython提供了检测网络状态的API接口,可以用于检测网络状态是否已经就绪。
checkNet.waitNetworkReady(timeout)
等待模组网络就绪。该方法会依次检测SIM卡状态、模组网络注册状态和PDP Context激活状态;在设定的超时时间之内,如果检测到PDP Context激活成功,会立即返回,否则直到超时才会退出。可以直接使用该API接口来检测网络代替上文的检测SIM卡状态、模组网络注册状态和PDP Context激活状态三个步骤,如果检测出对应步骤有异常再去对异常的部分进行检测处理
参数描述:
timeout- 超时时间,整型值,范围1~3600秒,默认60秒。
返回值描述:
返回一个元组,格式为:(stage, state)
| 参数 | 类型 | 含义 |
|---|---|---|
| stage | 整型 | 表示当前正在检测什么状态: 1 - 正在检测SIM卡状态; 2 - 正在检测网络注册状态; 3 - 正在检测PDP Context激活状态。 |
| state | 整型 | 根据stage值,来表示不同的状态,具体如下: stage = 1时,state表示 SIM卡的状态,范围0-21,每个状态值的详细说明,请参考sim.getStatus()方法的返回值说明; stage = 2时,state表示网络注册状态,范围0-11,每个状态值的详细说明,请参考net.getState()方法的返回值说明; stage = 3时,state表示PDP Context激活状态,0表示没有激活成功,1表示激活成功。 |
异常处理
网络异常分为两种。一种是在开机时发生网络异常,一种是开机已经注网成功,然后在后续的业务处理过程中网络异常
设备开机时的网络异常处理
模组开机时的网络异常,主要包括3种情况,分别是:
- SIM卡异常
- 模组网络注册失败
- 蜂窝无线网卡自动激活失败
这3种情况导致的直接结果,就是模组无法连接到网络。因此我们将这些情况都称之为“网络异常”,以上三种异常情况的检查和处理流程参见上文。
设备运行过程中网络异常处理
蜂窝无线网卡激活成功后,用户的应用程序还需要关注一件事——设备与网络的连接状态。这是因为在设备运行过程中,可能会因为一些异常原因(如网络异常、环境干扰、信号差等)导致模组与网络的连接断开。如果用户应用程序没有关注这种网络事件,很可能导致用户应用程序中和网络相关的业务执行异常,导致出现无法预料的问题。
QuecPython提供了网络事件监听功能,用户应用程序可以通过注册回调函数的方式来监听网络状态变化事件。当设备与无线网络的连接状态发生变化时,系统就会自动将对应的事件通过用户注册的回调函数,推送给用户的应用程序。
注册网络监听回调函数的方法如下:
dataCall.setCallback(fun)
回调函数的示例如下:
def netCallback(args):
profileID = args[0]
netState = args[1]
if netState == 0:
print('### network {} disconnected.'.format(profileID))
elif netState == 1:
print('### network {} connected.'.format(profileID))
该回调函数的参数是一个元组,包含3个元素,目前用户只需要关注前两个元素即可。前两个参数说明如下:
| 参数 | 类型 | 说明 |
|---|---|---|
| args[0] | 整型 | 蜂窝无线网卡编号,表示当前是哪一路无线网卡的网络连接状态发生了变化。 |
| args[1] | 整型 | 网络状态,0表示网络连接断开,1表示网络连接成功。 |
建议用户注册该回调函数,用于监听网络连接状态,确保当网络连接状态发生变化时,用户应用程序可以根据网络状态变化进行及时的处理。通常,我们可以参考下面的方式来处理:
- 回调函数中收到网络连接状态发生变化的事件后,通过消息队列功能将网络事件发送给其他线程去处理。当然,用户也可以使用QuecPython的
sys_bus功能来代替消息队列。 - 其他线程在收到网络事件时,判断如果是网络连接断开事件,则停止socket、mqtt等这类和网络相关的业务。同时,该线程也可以选择启动一个定时器,比如先将定时器时间设定为60s。如果60s后,网络还没有恢复,则执行CFUN0/1切换,然后看网络是否可以恢复。
什么是CFUN0/1切换?
通过《蜂窝网络基础概念》章节中关于CFUN的说明,可以知道,CFUN指的是移动终端的功能模式。CFUN0/1切换是指通过
net.setModemFun(0)方法先将设备切换到模式0(最小功能模式),然后再通过net.setModemFun(1)方法将设备切换到模式1(全功能模式)。当切换到模式0,设备的整个射频网络协议栈全部关闭,SIM卡模块停止供电;再次切换到模式1时,会重新恢复对SIM卡的供电并重新进行初始化,同时与射频相关的软硬件功能都会重新开启,此时设备会重新发起网络注册流程。为什么要进行CFUN0/1切换?
QuecPython具有自动重连功能,如果发生网络异常导致设备与网络的连接断开,异常消失后,不是应该自动恢复吗?为什么上面提到的处理方式中,还要进行CFUN0/1的切换?
我们需要搞清楚,QuecPython的自动重连功能指的是在网络异常恢复后,模组自动重新激活无线网卡,而不是重新注册到网络。设备的网络注册行为是由系统的射频网络协议栈自动控制的,理论上在网络异常因素消失后,射频网络协议栈会自动重新发起网络注册。但是不排除因为一些原因,导致设备没有及时重新进行网络注册的情况。这时因为设备网络注册尚未成功,无线网卡也无法重新激活。因此,我们主动进行了CFUN0/1的切换操作。其实就像是我们平时使用手机时,有时候遇到网络差或者没信号的时候,我们会选择先关闭手机的移动网络,然后再重新打开是一样的道理。当然,用户也可以选择进行重启。
192

被折叠的 条评论
为什么被折叠?



