diff --git "a/docs/Application_guide/zh/media/network-comm/sim/\351\207\215\345\220\257\345\220\216SIM\345\215\241\347\212\266\346\200\201\346\201\242\345\244\215\346\255\243\345\270\270.png" "b/docs/Application_guide/zh/media/network-comm/sim/\351\207\215\345\220\257\345\220\216SIM\345\215\241\347\212\266\346\200\201\346\201\242\345\244\215\346\255\243\345\270\270.png" new file mode 100644 index 0000000000000000000000000000000000000000..ad96db1ca00e7c8e572042f4fb6d9f37db869f9b Binary files /dev/null and "b/docs/Application_guide/zh/media/network-comm/sim/\351\207\215\345\220\257\345\220\216SIM\345\215\241\347\212\266\346\200\201\346\201\242\345\244\215\346\255\243\345\270\270.png" differ diff --git a/docs/Application_guide/zh/network-comm/esim/README.md b/docs/Application_guide/zh/network-comm/esim/README.md index 710d75dbd053b9bc06531123d3f2df54ab17d7a8..1f8a08c66ee2f9e9d598cbbfd7cac2862f18b9fd 100644 --- a/docs/Application_guide/zh/network-comm/esim/README.md +++ b/docs/Application_guide/zh/network-comm/esim/README.md @@ -116,7 +116,7 @@ M2M的远程SIM配置使用服务器驱动(推送模式)来配置和远程 * 跨境设备 -设备移动跨境场景需要进行运营商网络切换普通 SIM 卡无法满足,全球漫游卡资费又比较昂贵,通过eSIM 可以自由切换到当地运营商,而无需改动硬件。 +设备移动跨境场景需要进行运营商网络切换,普通 SIM 卡无法满足,全球漫游卡资费又比较昂贵,通过eSIM 可以自由切换到当地运营商,而无需改动硬件。 @@ -141,17 +141,17 @@ Quecpython现支持eSIM功能具体型号如下表: ### 工具介绍 -esimtools软件主要用于处理eSIM空卡情况,esimtools软件需要从运营商服务器下载数据,需要个人电脑可以正常访问因特网。 +QEsimTool软件主要用于处理eSIM空卡情况,QEsimTool软件需要从运营商服务器下载数据,需要个人电脑可以正常访问因特网。 -esimtools软件的运行机制:用户从运营商获取AccCode,将AccCode作为参数传给esimtools,esimtools通过AccCode解析出运营商服务器地址,并向运营商服务器发送下载profile数据请求。当esimtools下载profile数据完成后,将通过AT指令将数据发送到设备中,进而将profile写入eSIM卡中。 +QEsimTool软件的运行机制:用户从运营商获取AccCode,将AccCode作为参数传给QEsimTool,QEsimTool通过AccCode解析出运营商服务器地址,并向运营商服务器发送下载profile数据请求。当QEsimTool下载profile数据完成后,将通过AT指令将数据发送到设备中,进而将profile写入eSIM卡中。 -esimtools软件获取方式:请到[quectel](https://www.quectel.com/)官网,联系客服进行领取。 +QEsimTool软件获取方式:请到[quectel](https://www.quectel.com/)官网,联系客服进行领取。 ### 界面介绍 -esimtools软件附有应用指导文档,以下仅做简单介绍。 +QEsimTool软件附有应用指导文档,以下仅做简单介绍。 -esimtools软件启动界面如下: +QEsimTool软件启动界面如下: ![](../../media/network-comm/esim/1-1.png) @@ -163,7 +163,7 @@ Baud rate :串口波特率。 OPEN :以指定的波特率打开Port。 -AccCode :AccCode需要运营商提供,填入esimtools中,作为参数。 +AccCode :AccCode需要运营商提供,填入QEsimTool中,作为参数。 DownloadProfile :点击此按钮将解析AccCode,通过网络下载profile。 @@ -183,7 +183,7 @@ DeleteProfile :删除和ICCID对应的profile。 用户可以按照如下步骤进行操作: -* 正常启动模组设备后,在个人电脑中打开esimtools软件。 +* 正常启动模组设备后,在个人电脑中打开QEsimTool软件。 * 检查个人电脑是否可以正常访问因特网。 @@ -248,7 +248,7 @@ from sim import esim def usrFun(result): ''' :param result :OTA下载profile结果。 - :type result :整形,0:成功 1:失败 + :type result :整型,0:成功 1:失败 ''' print("OTA result:{}".format(result)) @@ -287,7 +287,7 @@ print("Get all profile :{}".format(profile_list)) ### 下载安装运营商profile -用户可通过如下接口下载安装运营商的profile。如eSIM为空卡,请使用esimtools工具进行安装首个profile。为确保此接口可以正常下载profile信息,需eSIM卡当前启用的profile能够正常注网,并且可以正常和AccCode中的运营商服务器地址进行网络数据交互。在此接口调用后,必须等下载结果通知到达后才能调用eSIM接口进行别的操作,否则将影响下载安装结果。 +用户可通过如下接口下载安装运营商的profile。如eSIM为空卡,请使用QEsimTool工具进行安装首个profile。为确保此接口可以正常下载profile信息,需eSIM卡当前启用的profile能够正常注网,并且可以正常和AccCode中的运营商服务器地址进行网络数据交互。在此接口调用后,必须等下载结果通知到达后才能调用eSIM接口进行别的操作,否则将影响下载安装结果。 接口如下: @@ -304,7 +304,7 @@ from sim import esim def usrFun(result): ''' :param result :OTA下载profile结果。 - :type result :整形,0:成功 1:失败 + :type result :整型,0:成功 1:失败 ''' print("OTA result:{}".format(result)) @@ -438,9 +438,9 @@ class pyesim(): self.stage, self.state = checkNet.waitNetworkReady(60) if self.stage == 3 and self.state == 1: print("network is success!") - self.debug_enbale = True - self.ota_result = False - pass + self.debug_enbale = True + self.ota_result = False + pass def esim_log(self,args): if self.debug_enbale == True: print("esim {}".format(args)) @@ -530,14 +530,14 @@ if __name__ == '__main__': ### 无法下载安装profile * AccCode是否错误,可向运营商进行确认。 -* 当前的设备或PC机是否可以正常访问从AccCode中解析除的url地址。 +* 当前的设备或PC机是否可以正常访问从AccCode中解析出的url地址。 * 是否重复下载安装profile。 * 是否运营商进行限制,同一个AccCode只能使用一次,需和运营商进行确定。 * 网络信号是否太弱,网络不稳定。 ### 下载安装profile后无法上网 -如遇到下载安装profile成功后无法上网,请做一次CFUN=0,1的切换操作。如依然无法上网,请按如下方面进行检查。 +如遇到下载安装profile成功后无法上网,请做一次CFUN=0/1的切换操作。如依然无法上网,请按如下方面进行检查。 * SIM卡状态是否异常 * 下载安装的profile是否已正常激活。 @@ -546,4 +546,5 @@ if __name__ == '__main__': ### 提示eSIM卡未插卡 -请参考Quecptyhon官网wik蜂窝无线网卡[网络异常处理]()。 +请参考QuecPtyhon官网wik蜂窝无线网卡[网络异常处理](https://python.quectel.com/doc/Application_guide/zh/network-comm/nic/cellular/exception-handling.html#开机时网络异常处理)。 + diff --git a/docs/Application_guide/zh/network-comm/sim/Common-exception-handling.md b/docs/Application_guide/zh/network-comm/sim/Common-exception-handling.md index 866fd518ffd668977c0b0804499b0a0fc63bccea..e5f4a867e58638c8a8060fae12939dfa3a5692bd 100644 --- a/docs/Application_guide/zh/network-comm/sim/Common-exception-handling.md +++ b/docs/Application_guide/zh/network-comm/sim/Common-exception-handling.md @@ -1,5 +1,5 @@ # 常见异常处理 -SIM卡状态异常以及注网、拨号异常,请参考Quecpython官网wiki蜂窝无线网卡[网络异常处理]()部分 +SIM卡状态异常以及注网、拨号异常,请参考QuecPython官网wiki蜂窝无线网卡[网络异常处理](https://python.quectel.com/doc/Application_guide/zh/network-comm/nic/cellular/exception-handling.html)部分 ## 无法发短信 * 检查SIM卡状态是否异常。 @@ -19,8 +19,9 @@ SIM卡状态异常以及注网、拨号异常,请参考Quecpython官网wiki蜂 ## 注网拨号成功URL无法访问 * SIM卡是否欠费,运营商不转发对端回复数据或不转发请求报文到对端。如欠费请充费。 -* 其他异常情况参考Quecpython官网wiki蜂窝无线网卡[网络异常处理]()部分。 +* 其他异常情况参考QuecPython官网wiki蜂窝无线网卡[网络异常处理](https://python.quectel.com/doc/Application_guide/zh/network-comm/nic/cellular/exception-handling.html)部分。 ## 某些协议数据不能正常交互 * 对于此类SIM卡运营商是否对指定的某些协议做了限制,例如NTP协议,某些运营商对NTP协议限制只能发送到指定的NTP服务地址,否则无法交互。和运营商核实,开通此类业务。 -* 其他异常情况参考Quecpython官网wiki蜂窝无线网卡[网络异常处理]()部分。 +* 其他异常情况参考QuecPython官网wiki蜂窝无线网卡[网络异常处理](https://python.quectel.com/doc/Application_guide/zh/network-comm/nic/cellular/exception-handling.html)部分。 + diff --git a/docs/Application_guide/zh/network-comm/sim/Frequently-Asked-Questions.md b/docs/Application_guide/zh/network-comm/sim/Frequently-Asked-Questions.md index 64773bfd7bc037f124c7dc322aae32b001c54bfd..cecf445cb5b2b6a7bb7e3925cba8587ec82a2f63 100644 --- a/docs/Application_guide/zh/network-comm/sim/Frequently-Asked-Questions.md +++ b/docs/Application_guide/zh/network-comm/sim/Frequently-Asked-Questions.md @@ -2,13 +2,13 @@ ## 新办理SIM卡首次使用需要做什么 新办理SIM卡一般需要激活SIM卡,可以通过电话或者运营商提供的url地址进行操作。 ## SIM卡为什么无法发送短信 -* 未能正常设置短信验证码 +* 未能正常设置短信中心号码 * 未开通短信业务 * 运营商不支持 * 未正常联网 ## 为什么不能拨打电话 -* SIM卡是未流量卡不支持打电话 +* SIM卡是流量卡不支持打电话 * 设备不在服务区 * 信号太弱 * 设备未能正常注网 diff --git a/docs/Application_guide/zh/network-comm/sim/Quecpython-SIM-function-application-example.md b/docs/Application_guide/zh/network-comm/sim/Quecpython-SIM-function-application-example.md index 1ecb0fa228af2ad0d9982aba22f8b34370fa9c06..0b2872e0ff0cf5e90330fdfddfd861ac8c8a2419 100644 --- a/docs/Application_guide/zh/network-comm/sim/Quecpython-SIM-function-application-example.md +++ b/docs/Application_guide/zh/network-comm/sim/Quecpython-SIM-function-application-example.md @@ -1,770 +1,828 @@ -# Quecpython SIM卡API说明 - -## 查询SIM卡信息 - -### 查询IMSI - -用户可通过如下接口获取SIM卡的IMSI号码,以方便用户对IMSI的应用。 - -接口如下: - -```python -sim.getImsi() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -imsi = sim.getImsi() -print("Get IMSI : {}".format(imsi)) - -``` - -### 查询ICCID - -用户可通过如下接口查询SIM卡的ICCID,以方便用户对SIM卡的ICCID的应用。 - -接口如下: - -```python -sim.getIccid() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -iccid = sim.getIccid() -print("Get IMSI : {}".format(iccid)) - -``` - - - -### 查询电话号码 - -用户可通过如下接口查询SIM卡电话号码,SIM电话号码需要先设置后查询。 - -接口如下: - -```python -sim.getPhoneNumber() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -phone_num = sim.getPhoneNumber() -print("Get Phone Number is : {}".format(phone_num)) - -``` - -### 应用场景 - -应用程序启动后,等待注网成功,然后查询SIM卡信息,为后续处理业务做准备。 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim -import checkNet - -sim_status_dict={ - 0:"SIM卡不存在/被移除", - 1:"SIM已经准备好", - 2:"SIM卡已锁定,等待CHV1密码", - 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", - 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", - 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", - 6:"需要隐藏电话簿条目的密钥", - 7:"需要解锁隐藏密钥的编码", - 8:"SIM卡已锁定,等待CHV2密码", - 9:"SIM卡被阻拦,需要CHV2解锁密码", - 10:"由于网络个性化检查失败,SIM卡被锁定", - 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", - 12:"由于子网络锁个性化检查失败,SIM卡被锁定", - 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", - 14:"由于服务提供商个性化检查失败,SIM卡被锁定", - 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", - 16:"由于企业个性化检查失败,SIM卡被锁定", - 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", - 18:"SIM正在初始化,等待完成", - 19:"CHV1/CHV2/PIN错误", - 20:"SIM卡无效", - 21:"未知状态" -} - -if __name__ == '__main__': - - # 1、查询SIM卡状态 - sim_status = sim.getStatus() - if sim_status not in sim_status_dict: - print("接口返回失败") - exit() - if sim_status != 1: - print("Get SIM status : {}".format(sim_status_dict[sim_status])) - exit() - - # 2、等待注网成功 - stage, state = checkNet.waitNetworkReady(30) - if stage == 3 and state == 1: - print('Network connection successful.') - else: - print('Network connection failed, stage={}, state={}'.format(stage, state)) - exit() - - # 3、查询开机注网后的SIM卡信息 - - imsi = sim.getImsi() - if type(imsi).__name__ == 'int': - print("Get IMSI failed !") - exit() - print("Get IMSI is : {}".format(imsi)) - - iccid = sim.getIccid() - if type(iccid).__name__ == 'int': - print("Get ICCID failed !") - exit() - print("Get ICCID is : {}".format(iccid)) - - phone_number= sim.getPhoneNumber() - if type(phone_number).__name__ == 'int': - print("Get phone_number failed !") - exit() - print("Get phone number is : {}".format(phone_number)) - -``` - - - -## 查询SIM卡状态 - -用户可通过如下接口获取当前SIM卡的状态,通过SIM卡状态判断SIM卡是否可以正常使用。 - -接口如下: - -``` -sim.getStatus() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim -sim_status_dict={ - 0:"SIM卡不存在/被移除", - 1:"SIM已经准备好", - 2:"SIM卡已锁定,等待CHV1密码", - 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", - 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", - 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", - 6:"需要隐藏电话簿条目的密钥", - 7:"需要解锁隐藏密钥的编码", - 8:"SIM卡已锁定,等待CHV2密码", - 9:"SIM卡被阻拦,需要CHV2解锁密码", - 10:"由于网络个性化检查失败,SIM卡被锁定", - 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", - 12:"由于子网络锁个性化检查失败,SIM卡被锁定", - 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", - 14:"由于服务提供商个性化检查失败,SIM卡被锁定", - 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", - 16:"由于企业个性化检查失败,SIM卡被锁定", - 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", - 18:"SIM正在初始化,等待完成", - 19:"CHV1/CHV2/PIN错误", - 20:"SIM卡无效", - 21:"未知状态" -} - -sim_status = sim.getStatus() -if sim_status not in sim_status_dict: - print("接口返回失败") - exit() - if sim_status != 1: - print("Get SIM status status : {}".format(sim_status_dict[sim_status])) - exit() -print("Get sim_status is : {}".format(sim_status_dict[sim_status])) - -``` - - - -## PIN码验证功能 - -用户可通过开启PIN码验证功能来保证SIM卡的使用安全。PIN码是SIM卡的安全识别码,用于验证用户的身份和保护个人信息安全。开启PIN码验后,每次重启设备后(或CFUN0/1切换后)均需进行PIN码验证,在验证通过后SIM卡才能正常使用。PIN码验证连续3次输入错误后SIM卡将被锁定,需要用PUK码进行解码。 - -### 开启PIN验证 - -用户可通过如下接口开启SIM卡PIN码验证功能,用以保证SIM卡的使用安全。 - -接口如下: - -```python -sim.enablePin(pin) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -result = sim.enablePin("1234") -print("Enable PIN : {}".format(result)) - -``` - - - -### 关闭PIN验证 - -用户可通过如下接口关闭PIN码验证功能,在保证SIM卡是在安全的环境下使用时,可以关闭PIN码验证功能来简化应用程序。 - -接口如下: - -```python -sim.disablePin(pin) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -#根据实际PIN码输入,此处"1234"为示例PIN码 -result = sim.disablePin("1234") -print("Disable PIN : {}".format(result)) - -``` - - - -### PIN验证 - -用户可通过如下接口来完成SIM卡的PIN码验证,开启PIN码验证后,SIM卡需完成PIN码验证后才能将状态将切换到正常状态,之后应用程序才能进行业务处理。 - -接口如下: - -```python -sim.verifyPin(pin) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -#根据实际PIN码输入 -result = sim.verifyPin("1234") -print("Verify PIN result is : {}".format(result)) -``` - - - -### 修改PIN - -用户可定期通过如下接口修改SIM卡的PIN码,提高SIM卡使用的安全性。 - -接口如下: - -```python -sim.changePin(oldPin, newPin) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -sim.changePin("1234", "4321") -``` - -### 应用场景 - -用户为了安全应用SIM卡,需要在开启PIN码验证功能的情况下进行业务处理。 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim -import checkNet - -sim_status_dict={ - 0:"SIM卡不存在/被移除", - 1:"SIM已经准备好", - 2:"SIM卡已锁定,等待CHV1密码", - 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", - 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", - 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", - 6:"需要隐藏电话簿条目的密钥", - 7:"需要解锁隐藏密钥的编码", - 8:"SIM卡已锁定,等待CHV2密码", - 9:"SIM卡被阻拦,需要CHV2解锁密码", - 10:"由于网络个性化检查失败,SIM卡被锁定", - 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", - 12:"由于子网络锁个性化检查失败,SIM卡被锁定", - 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", - 14:"由于服务提供商个性化检查失败,SIM卡被锁定", - 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", - 16:"由于企业个性化检查失败,SIM卡被锁定", - 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", - 18:"SIM正在初始化,等待完成", - 19:"CHV1/CHV2/PIN错误", - 20:"SIM卡无效", - 21:"未知状态" -} - -if __name__ == '__main__': - - sim_status = sim.getStatus() - if sim_status not in sim_status_dict: - print("接口返回失败") - exit() - - if sim_status == 2: - # 开启了PIN码验证,需要验证PIN码 - PIN="1234" #PIN码-请根据SIM卡真实的PIN码填写 - pin_result = sim.verifyPin(PIN) - if pin_result != 0: - print("Error PIN ! Please input right PIN!") - exit() - - # 验证成功后关闭PIN码验证,下次不再需要进行PIN码验证 - # result = sim.disablePin(PIN) - #if result != 0: - # print("Error PIN ! Please input right PIN!") - # exit() - - # 查询SIM状态 - sim_status = sim.getStatus() - if sim_status not in sim_status_dict: - print("接口返回失败") - exit() - if sim_status != 1: - print("Get SIM status : {}".format(sim_status_dict[sim_status])) - exit() - - print("Get sim_status is : {}".format(sim_status_dict[sim_status])) - - #等待注网成功,进行业务处理 - stage,state = checkNet.waitNetworkReady(30) - if stage == 3 and state == 1: - print('Network connection successful.') - else: - print('Network connection failed, stage={}, state={}'.format(stage, state)) - -``` - - - -## SIM卡解锁 - -用户可通过如下接口处理连续3次输入PIN码错误导致锁PIN的情况。这个接口在用PUK码解锁的同时重新设置了PIN码。需要注意PUK码错误10次后SIM卡将被永久锁定,自动报废。 - -接口如下: - -``` -sim.unblockPin(puk, newPin) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -sim.unblockPin("12345678", "0000") - -``` - -## 电话薄功能 - -用户在实际项目应用过程中,如需保存对端电话号码,需要用到电话薄功能。此接口可以提供保存电话号码信息的功能。此功能接口支持情况请参考Quecpython官网wiki[电话薄功能](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#%E7%94%B5%E8%AF%9D%E7%B0%BF%E5%8A%9F%E8%83%BD) - -### 读取电话薄 - -用户可通过如下接口读取电话薄。其中电话号码存储位置参考Quecpython官网wiki中`sim.readPhonebook()`[接口参数描述](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#%3Ccode%3Esim.readPhonebook%3C/code%3E)。需注意start-end差值需要小于等于20。 - -接口如下: - -```python -sim.readPhonebook(storage, start, end, username) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -# 读取本SIM卡电话薄中索引值1到4的电话信息 -sim_phone_boo = sim.readPhonebook(9, 1, 4, "") -print("SIM卡中电话薄 : {}".format(miss_call)) - -# 读取未接来电中索引值1到4的电话信息 -miss_call = sim.readPhonebook(4, 1, 4, "") -print("未接来电 : {}".format(miss_call)) - -``` - - - -### 设置电话薄 - -用户可通过如下接口来保存电话号码信息到电话簿中: - -``` -sim.writePhonebook(storage, index, username, number) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -# 保存Tom电话号码保存到SIM卡电话薄索引位置1的位置上 -sim.writePhonebook(9, 1, 'Tom', '18144786859') - -``` - -### 应用场景 - -在项目运行中,获取到电话号码,并保存电话号码到SIM卡电话薄中。 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -def save_phone_number_to_simbook(index,name,phonenumber,type = 0 ): - # type = 0,如果设置保存电话号码位置已经存在电话号码,直接返回,不覆盖保存 - if type == 0: - # 查询当前位置是否已有电话号码信息 - phone_info = sim.readPhonebook(9, index, index, "") - if type(phone_info).__name__ == 'int': - print("不存在") - elif phone_info[1][0][1] == name and phone_info[1][0][2] == phonenumber: - # 电话号码已存在 - print("已存在") - return - else: - print("不存在") - else: - pass - # 保存姓名,电话号码到SIM卡电话薄中index地址处 - result = sim.writePhonebook(9, index, name, phonenumber) - -def get_name_phone(): - return 'Tom','18144786858' - -if __name__ == '__main__': - name,phonenumber = get_name_phone() - - # 姓名电话号码已存在则不保存 - save_phone_number_to_simbook(1,name,phonenumber,0) - - #姓名电话号码已存在覆盖保存 - save_phone_number_to_simbook(1,name,phonenumber,1) -``` - - - -## SIM卡热插拔 - -在项目中,用户如需监测SIM卡插拔情况,可以用如下接口注册回调函数。当SIM卡插入或者拔出时,系统将会调用如下接口注册的回调函数,回调函数会上送SIM卡插入或者拔出的事件给应用层。用户可以根据通知事件来判断SIM卡是插入还是拔出。Quecpython模组对此接口支持情况请参考Quecpython官网wiki[热插拔功能](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#%E7%83%AD%E6%8F%92%E6%8B%94%E5%8A%9F%E8%83%BD) - -### 注册热插拔回调 - -用户可通过如下接口注册SIM卡热插拔回调函数。 - -接口如下: - -```python -sim.setCallback(usrFun) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -def sim_hot_call(event): - if event == 1: - # SIM 卡插入 - print("Get SIM Inster event : {}".format(event)) - elif event == 2: - # SIM 卡拔出 - print("Get SIM Unplug event : {}".format(event)) - else: - # 未知事件 - print("Get SIM Unkown event : {}".format(event)) - -sim.setCallback(sim_hot_call) - -``` - - - -### 获取SIM卡热插拔配置 - -用户可通过如下接口查询SIM卡热插拔功能的当前配置信息,根据配置信息可以判断当前是否开启了热插拔功能。 - -接口如下: - -```python -sim.getSimDet() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -sim_hot_conf = sim.getSimDet() -print("Get Current SIM config info : {}".format(sim_hot_conf)) -if sim_hot_conf[0] == 1: - # SIM卡热插拔功能启用 - print("Current SIM Hotplug is enable") -``` - - - -### 配置SIM卡热插拔 - -用户可通过如下接口启用或者关闭SIM卡热插拔功能。 - -接口如下: - -```python -sim.setSimDet(switch, triggerLevel) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -# 先判断SIM卡插入时,电平是高电平还是低电平,在此以SIM插入时为高电平为例 - -# 1、注册热插拔回调函数 -def sim_hot_call(event): - print("Get SIM event : {}".format(event)) - -sim.setCallback(sim_hot_call) - -sim_hot_conf = sim.getSimDet() -# 2、开启SIM卡热插拔功能并标记模组SIM卡插入时,电平为高电平 -if sim_hot_conf[0] == 0: - print("SIM hot-swapping is not currently enabled") - print("Will enable this function") - sim.setSimDet(1, 1) -else: - print("Already enbale this function") - -``` - -### 应用场景 - -用户在项目中,检测SIM卡插拔事件,并设置标识,标记发生了SIM卡插入或者拔出事件。(用户可以根据需要决定是否通知应用程序中其他模块发生了SIM卡插拔事件)。 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim -import net -insert_flag = False -def sim_hot_call(event): - global insert_flag - print("Get SIM event : {}".format(event)) - if event == 1: - #检测到SIM卡插入,设置标记SIM卡被插入 - insert_flag = True - else: - insert_flag = False - -if __name__ == '__main__': - sim_hot_conf = sim.getSimDet() - if sim_hot_conf[0] == 0: - - #为开启SIM卡热插拔功能,在位电平标记请根据实际SIM卡在位电平设置 - #此处以SIM卡在为电平为1为例 - print("enable this function") - sim.setSimDet(1, 1) - - else: - print("Already enbale this function") - - #设置回调函数检测SIM卡的插拔动作 - sim.setCallback(sim_hot_call) - -``` - - - -## 双卡切换 - -用户在项目应用过程中,为了网络稳定,满足多种网络场景,需要两张不同SIM卡可以随时切换的功能,以应对各种网络异常情况。Quecpython模组对于此功能支持情况请参考Quecpython官网wiki中[SIM卡切卡功能](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#SIM%E5%8D%A1%E5%88%87%E5%8D%A1%E5%8A%9F%E8%83%BD)。 - -### 注册切卡回调函数 - -用户可通过如下接口注册回调函数监测切卡事件。当发生了切卡事件,系统将通过注册的回调函数发出切卡事件通知应用层,应用层收到切卡事件通知后,将进行切卡导致的网络异常情况的处理。 - -接口如下: - -```python -sim.setSwitchcardCallback(usrFun) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim -import net - -def switch_sim_call(result): - print("Get switch SIM card event : {}".format(reslut)) - if result == 7: - # SIM卡切卡成功,通知应用层,SIM卡切卡成功 - print("SIM switch success!") - elif result == 9: - print("SIM switch failed!") - -if __name__ == '__main__': - - sim.setSwitchcardCallback(switch_sim_call) - -``` - - - -### 查询当前 SIM卡ID - -用户可通过如下接口查询当前启用的SIM卡ID。 - -接口如下 : - -```python -sim.getCurSimid() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -simid = sim.getCurSimid() -print("Current SIM is : {}".format(simid)) -``` - - - -### 切换SIM卡 - -用户可通过如下接口切换到指定SIM卡。如当前SIM卡出现不可恢复的异常网络情况,可用此接口将正在使用的SIM卡切换到另一张SIM卡,使应用程序可以继续处理业务。 - -接口如下: - -```python -sim.switchCard(simId) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim - -simid = sim.getCurSimid() -print("Current SIM is : {}".format(simid)) - -if simid == 0: - # 启用SIM2 - print("Current is SIM 1 and Will switch to SIM2") - sim.switchCard(1) - -``` - -### 应用场景 - -以下场景根据客户需求和业务流程,可能需要切卡操作。 - -* 检测到当前卡信号弱满足不了业务需求就尝试切到另一张卡, 比如单车,对讲机。 -* 一张卡接入公网,一张卡接入专网,公网卡主要做数据业务, 专网卡处理一些特殊任务, 比如电网客户。 - -* 用户应用程序在启动时检测到当前SIM卡状态无效,无法进行网络交互,切换到另一张SIM卡。 - -```python -# -*- coding: UTF-8 -*- -#示例 -import sim -import net - -def switch_sim_call(result): - print("Get switch SIM card event : {}".format(reslut)) - if result == 7: - print("SIM switch success!") - net.setModemFun(0) - net.setModemFun(1) - elif result == 9: - print("SIM switch failed!") - - -if __name__ == '__main__': - - sim.setSwitchcardCallback(switch_sim_call) - - sim_status = sim.getStatus() - if sim_status not in sim_status_dict: - print("接口返回失败") - exit() - if sim_status != 20: - # sim卡状态无效 - print("Get SIM status status : {}".format(sim_status_dict[sim_status])) - - #查询当前使用SIM卡 - sim_id = sim.getCurSimid() - - #切换到另一张卡上运行 - if sim_id == 0: - sim.switchCard(1) - else: - sim.switchCard(0) - -``` - - +# QuecPython SIM卡API说明 + +## 查询SIM卡信息 + +### 查询IMSI + +用户可通过如下接口获取SIM卡的IMSI号码,以方便用户对IMSI的应用。 + +接口如下: + +```python +sim.getImsi() +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +imsi = sim.getImsi() +print("Get IMSI : {}".format(imsi)) + +``` + +### 查询ICCID + +用户可通过如下接口查询SIM卡的ICCID,以方便用户对SIM卡的ICCID的应用。 + +接口如下: + +```python +sim.getIccid() +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +iccid = sim.getIccid() +print("Get IMSI : {}".format(iccid)) + +``` + + + +### 查询电话号码 + +用户可通过如下接口查询SIM卡电话号码,SIM电话号码需要先设置后查询。 + +接口如下: + +```python +sim.getPhoneNumber() +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +phone_num = sim.getPhoneNumber() +print("Get Phone Number is : {}".format(phone_num)) + +``` + +### 查询信息应用场景 + +应用程序启动后,等待注网成功,然后查询SIM卡信息,为后续处理业务做准备。 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim +import checkNet +import sys + +sim_status_dict={ + 0:"SIM卡不存在/被移除", + 1:"SIM已经准备好", + 2:"SIM卡已锁定,等待CHV1密码", + 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", + 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", + 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", + 6:"需要隐藏电话簿条目的密钥", + 7:"需要解锁隐藏密钥的编码", + 8:"SIM卡已锁定,等待CHV2密码", + 9:"SIM卡被阻拦,需要CHV2解锁密码", + 10:"由于网络个性化检查失败,SIM卡被锁定", + 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", + 12:"由于子网络锁个性化检查失败,SIM卡被锁定", + 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", + 14:"由于服务提供商个性化检查失败,SIM卡被锁定", + 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", + 16:"由于企业个性化检查失败,SIM卡被锁定", + 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", + 18:"SIM正在初始化,等待完成", + 19:"CHV1/CHV2/PIN错误", + 20:"SIM卡无效", + 21:"未知状态" +} + +if __name__ == '__main__': + + # 1、查询SIM卡状态 + sim_status = sim.getStatus() + if sim_status not in sim_status_dict: + print("接口返回失败") + sys.exit() + print("Get SIM status : {}".format(sim_status_dict[sim_status])) + if sim_status != 1: + sys.exit() + + # 2、等待注网成功 + stage, state = checkNet.waitNetworkReady(30) + if stage == 3 and state == 1: + print('Network connection successful.') + else: + print('Network connection failed, stage={}, state={}'.format(stage, state)) + sys.exit() + + # 3、查询开机注网后的SIM卡信息 + + imsi = sim.getImsi() + if type(imsi).__name__ == 'int': + print("Get IMSI failed !") + sys.exit() + print("Get IMSI is : {}".format(imsi)) + + iccid = sim.getIccid() + if type(iccid).__name__ == 'int': + print("Get ICCID failed !") + sys.exit() + print("Get ICCID is : {}".format(iccid)) + + phone_number= sim.getPhoneNumber() + if type(phone_number).__name__ == 'int': + print("Get phone_number failed !") + sys.exit() + print("Get phone number is : {}".format(phone_number)) + +``` + + + +## 查询SIM卡状态 + +用户可通过如下接口获取当前SIM卡的状态,通过SIM卡状态判断SIM卡是否可以正常使用。 + +接口如下: + +``` +sim.getStatus() +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim +import sys + +sim_status_dict={ + 0:"SIM卡不存在/被移除", + 1:"SIM已经准备好", + 2:"SIM卡已锁定,等待CHV1密码", + 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", + 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", + 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", + 6:"需要隐藏电话簿条目的密钥", + 7:"需要解锁隐藏密钥的编码", + 8:"SIM卡已锁定,等待CHV2密码", + 9:"SIM卡被阻拦,需要CHV2解锁密码", + 10:"由于网络个性化检查失败,SIM卡被锁定", + 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", + 12:"由于子网络锁个性化检查失败,SIM卡被锁定", + 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", + 14:"由于服务提供商个性化检查失败,SIM卡被锁定", + 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", + 16:"由于企业个性化检查失败,SIM卡被锁定", + 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", + 18:"SIM正在初始化,等待完成", + 19:"CHV1/CHV2/PIN错误", + 20:"SIM卡无效", + 21:"未知状态" +} + +if __name__ == '__main__': + sim_status = sim.getStatus() + if sim_status not in sim_status_dict: + print("接口返回失败") + sys.exit() + if sim_status != 1: + print("Get SIM status status : {}".format(sim_status_dict[sim_status])) + sys.exit() + print("Get sim_status is : {}".format(sim_status_dict[sim_status])) + +``` + + + +## PIN码验证功能 + +用户可通过开启PIN码验证功能来保证SIM卡的使用安全。PIN码是SIM卡的安全识别码,用于验证用户的身份和保护个人信息安全。开启PIN码验后,每次重启设备后(或CFUN0/1切换后)均需进行PIN码验证,在验证通过后SIM卡才能正常使用。PIN码验证连续3次输入错误后SIM卡将被锁定,需要用PUK码进行解码。 + +### 开启PIN验证 + +用户可通过如下接口开启SIM卡PIN码验证功能,用以保证SIM卡的使用安全。 + +接口如下: + +```python +sim.enablePin(pin) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +result = sim.enablePin("1234") +print("Enable PIN : {}".format(result)) + +``` + + + +### 关闭PIN验证 + +用户可通过如下接口关闭PIN码验证功能,在保证SIM卡是在安全的环境下使用时,可以关闭PIN码验证功能来简化应用程序。 + +接口如下: + +```python +sim.disablePin(pin) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +#根据实际PIN码输入,此处"1234"为示例PIN码 +result = sim.disablePin("1234") +print("Disable PIN : {}".format(result)) + +``` + + + +### PIN验证 + +用户可通过如下接口来完成SIM卡的PIN码验证,开启PIN码验证后,SIM卡需完成PIN码验证后才能将状态将切换到正常状态,之后应用程序才能进行业务处理。 + +接口如下: + +```python +sim.verifyPin(pin) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +#根据实际PIN码输入 +result = sim.verifyPin("1234") +print("Verify PIN result is : {}".format(result)) +``` + + + +### 修改PIN + +用户可定期通过如下接口修改SIM卡的PIN码,提高SIM卡使用的安全性。 + +接口如下: + +```python +sim.changePin(oldPin, newPin) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +sim.changePin("1234", "4321") +``` + +### PIN码应用场景 + +用户为了安全应用SIM卡,需要在开启PIN码验证功能的情况下进行业务处理。 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim +import checkNet +import sys + +sim_status_dict={ + 0:"SIM卡不存在/被移除", + 1:"SIM已经准备好", + 2:"SIM卡已锁定,等待CHV1密码", + 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", + 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", + 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", + 6:"需要隐藏电话簿条目的密钥", + 7:"需要解锁隐藏密钥的编码", + 8:"SIM卡已锁定,等待CHV2密码", + 9:"SIM卡被阻拦,需要CHV2解锁密码", + 10:"由于网络个性化检查失败,SIM卡被锁定", + 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", + 12:"由于子网络锁个性化检查失败,SIM卡被锁定", + 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", + 14:"由于服务提供商个性化检查失败,SIM卡被锁定", + 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", + 16:"由于企业个性化检查失败,SIM卡被锁定", + 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", + 18:"SIM正在初始化,等待完成", + 19:"CHV1/CHV2/PIN错误", + 20:"SIM卡无效", + 21:"未知状态" +} + +if __name__ == '__main__': + + sim_status = sim.getStatus() + if sim_status not in sim_status_dict: + print("接口返回失败") + sys.exit() + + if sim_status == 2: + # 开启了PIN码验证,需要验证PIN码 + PIN="1234" #PIN码-请根据SIM卡真实的PIN码填写 + pin_result = sim.verifyPin(PIN) + if pin_result != 0: + print("Error PIN ! Please input right PIN!") + sys.exit() + + # 验证成功后关闭PIN码验证,下次不再需要进行PIN码验证 + # result = sim.disablePin(PIN) + #if result != 0: + # print("Error PIN ! Please input right PIN!") + # sys.exit() + + # 查询SIM状态 + sim_status = sim.getStatus() + if sim_status not in sim_status_dict: + print("接口返回失败") + sys.exit() + if sim_status != 1: + print("Get SIM status : {}".format(sim_status_dict[sim_status])) + sys.exit() + + print("Get sim_status is : {}".format(sim_status_dict[sim_status])) + + #等待注网成功,进行业务处理 + stage,state = checkNet.waitNetworkReady(30) + if stage == 3 and state == 1: + print('Network connection successful.') + else: + print('Network connection failed, stage={}, state={}'.format(stage, state)) + + +``` + + + +## SIM卡解锁 + +用户可通过如下接口处理连续3次输入PIN码错误导致锁PIN的情况。这个接口在用PUK码解锁的同时重新设置了PIN码。需要注意PUK码错误10次后SIM卡将被永久锁定,自动报废。 + +接口如下: + +``` +sim.unblockPin(puk, newPin) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +sim.unblockPin("12345678", "0000") + +``` + +## 电话薄功能 + +用户在实际项目应用过程中,如需保存对端电话号码,需要用到电话薄功能。此接口可以提供保存电话号码信息的功能。此功能接口支持情况请参考QuecPython官网wiki[电话薄功能](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#%E7%94%B5%E8%AF%9D%E7%B0%BF%E5%8A%9F%E8%83%BD) + +### 读取电话薄 + +用户可通过如下接口读取电话薄。其中电话号码存储位置参考QuecPython官网wiki中`sim.readPhonebook()`[接口参数描述](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#%3Ccode%3Esim.readPhonebook%3C/code%3E)。需注意start-end差值需要小于等于20。 + +接口如下: + +```python +sim.readPhonebook(storage, start, end, username) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +# 读取本SIM卡电话薄中索引值1到4的电话信息 +sim_phone_boo = sim.readPhonebook(9, 1, 4, "") +print("SIM卡中电话薄 : {}".format(miss_call)) + +# 读取未接来电中索引值1到4的电话信息 +miss_call = sim.readPhonebook(4, 1, 4, "") +print("未接来电 : {}".format(miss_call)) + +``` + + + +### 设置电话薄 + +用户可通过如下接口来保存电话号码信息到电话簿中: + +``` +sim.writePhonebook(storage, index, username, number) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +# 保存Tom电话号码保存到SIM卡电话薄索引位置1的位置上 +sim.writePhonebook(9, 1, 'Tom', '18144786859') + +``` + +### 电话薄应用场景 + +在项目运行中,获取到电话号码,并保存电话号码到SIM卡电话薄中。 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +def save_phone_number_to_simbook(index,name,phonenumber,input_type = 0 ): + # type = 0,如果设置保存电话号码位置已经存在电话号码,直接返回,不覆盖保存 + if input_type == 0: + # 查询当前位置是否已有电话号码信息 + phone_info = sim.readPhonebook(9, index, index, name) + if type(phone_info).__name__ == 'int': + print("不存在") + elif phone_info[1][0][1] == name and phone_info[1][0][2] == phonenumber: + # 电话号码已存在 + print("已存在") + return + else: + print("不存在") + else: + pass + # 保存姓名,电话号码到SIM卡电话薄中index地址处 + result = sim.writePhonebook(9, index, name, phonenumber) + +def get_name_phone(): + return 'Tom','18144786858' + +if __name__ == '__main__': + name,phonenumber = get_name_phone() + + # 姓名电话号码已存在则不保存 + save_phone_number_to_simbook(1,name,phonenumber,0) + + #姓名电话号码已存在覆盖保存 + save_phone_number_to_simbook(1,name,phonenumber,1) + +``` + + + +## SIM卡热插拔 + +在项目中,用户如需监测SIM卡插拔情况,可以用如下接口注册回调函数。当SIM卡插入或者拔出时,系统将会调用如下接口注册的回调函数,回调函数会上送SIM卡插入或者拔出的事件给应用层。用户可以根据通知事件来判断SIM卡是插入还是拔出。QuecPython模组对此接口支持情况请参考QuecPython官网wiki[热插拔功能](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#%E7%83%AD%E6%8F%92%E6%8B%94%E5%8A%9F%E8%83%BD) + +### 注册热插拔回调 + +用户可通过如下接口注册SIM卡热插拔回调函数。 + +接口如下: + +```python +sim.setCallback(usrFun) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +def sim_hot_call(event): + if event == 1: + # SIM 卡插入 + print("Get SIM Inster event : {}".format(event)) + elif event == 2: + # SIM 卡拔出 + print("Get SIM Unplug event : {}".format(event)) + else: + # 未知事件 + print("Get SIM Unkown event : {}".format(event)) + +sim.setCallback(sim_hot_call) + +``` + + + +### 获取SIM卡热插拔配置 + +用户可通过如下接口查询SIM卡热插拔功能的当前配置信息,根据配置信息可以判断当前是否开启了热插拔功能。 + +接口如下: + +```python +sim.getSimDet() +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +sim_hot_conf = sim.getSimDet() +print("Get Current SIM config info : {}".format(sim_hot_conf)) +if sim_hot_conf[0] == 1: + # SIM卡热插拔功能启用 + print("Current SIM Hotplug is enable") +``` + + + +### 配置SIM卡热插拔 + +用户可通过如下接口启用或者关闭SIM卡热插拔功能。 + +接口如下: + +```python +sim.setSimDet(switch, triggerLevel) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +# 先判断SIM卡插入时,电平是高电平还是低电平,在此以SIM插入时为高电平为例 + +# 1、注册热插拔回调函数 +def sim_hot_call(event): + print("Get SIM event : {}".format(event)) + +sim.setCallback(sim_hot_call) + +sim_hot_conf = sim.getSimDet() +# 2、开启SIM卡热插拔功能并标记模组SIM卡插入时,电平为高电平 +if sim_hot_conf[0] == 0: + print("SIM hot-swapping is not currently enabled") + print("Will enable this function") + sim.setSimDet(1, 1) +else: + print("Already enbale this function") + +``` + +### SIM卡热插拔应用场景 + +用户在项目中,检测SIM卡插拔事件,并设置标识,标记发生了SIM卡插入或者拔出事件。(用户可以根据需要决定是否通知应用程序中其他模块发生了SIM卡插拔事件)。 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim +import net +insert_flag = False +def sim_hot_call(event): + global insert_flag + print("Get SIM event : {}".format(event)) + if event == 1: + #检测到SIM卡插入,设置标记SIM卡被插入 + insert_flag = True + else: + insert_flag = False + +if __name__ == '__main__': + sim_hot_conf = sim.getSimDet() + if sim_hot_conf[0] == 0: + + #为开启SIM卡热插拔功能,在位电平标记请根据实际SIM卡在位电平设置 + #此处以SIM卡在为电平为1为例 + print("enable this function") + sim.setSimDet(1, 1) + + else: + print("Already enbale this function") + + #设置回调函数检测SIM卡的插拔动作 + sim.setCallback(sim_hot_call) + +``` + + + +## 双卡切换 + +用户在项目应用过程中,为了网络稳定,满足多种网络场景,需要两张不同SIM卡可以随时切换的功能,以应对各种网络异常情况。QuecPython模组对于此功能支持情况请参考QuecPython官网wiki中[SIM卡切卡功能](https://python.quectel.com/doc/API_reference/zh/iotlib/sim.html#SIM%E5%8D%A1%E5%88%87%E5%8D%A1%E5%8A%9F%E8%83%BD)。 + +### 注册切卡回调函数 + +用户可通过如下接口注册回调函数监测切卡事件。当发生了切卡事件,系统将通过注册的回调函数发出切卡事件通知应用层,应用层收到切卡事件通知后,将进行切卡导致的网络异常情况的处理。 + +接口如下: + +```python +sim.setSwitchcardCallback(usrFun) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim +import net + +sim_status_dict={ + 0:"SIM卡不存在/被移除", + 1:"SIM已经准备好", + 2:"SIM卡已锁定,等待CHV1密码", + 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", + 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", + 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", + 6:"需要隐藏电话簿条目的密钥", + 7:"需要解锁隐藏密钥的编码", + 8:"SIM卡已锁定,等待CHV2密码", + 9:"SIM卡被阻拦,需要CHV2解锁密码", + 10:"由于网络个性化检查失败,SIM卡被锁定", + 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", + 12:"由于子网络锁个性化检查失败,SIM卡被锁定", + 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", + 14:"由于服务提供商个性化检查失败,SIM卡被锁定", + 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", + 16:"由于企业个性化检查失败,SIM卡被锁定", + 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", + 18:"SIM正在初始化,等待完成", + 19:"CHV1/CHV2/PIN错误", + 20:"SIM卡无效", + 21:"未知状态" +} + +def switch_sim_call(result): + print("Get switch SIM card event : {}".format(reslut)) + if result == 7: + # SIM卡切卡成功,通知应用层,SIM卡切卡成功 + print("SIM switch success!") + elif result == 9: + print("SIM switch failed!") + +if __name__ == '__main__': + + sim.setSwitchcardCallback(switch_sim_call) + +``` + + + +### 查询当前 SIM卡ID + +用户可通过如下接口查询当前启用的SIM卡ID。 + +接口如下 : + +```python +sim.getCurSimid() +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +simid = sim.getCurSimid() +print("Current SIM is : {}".format(simid)) +``` + + + +### 切换SIM卡 + +用户可通过如下接口切换到指定SIM卡。如当前SIM卡出现不可恢复的异常网络情况,可用此接口将正在使用的SIM卡切换到另一张SIM卡,使应用程序可以继续处理业务。 + +接口如下: + +```python +sim.switchCard(simId) +``` + +示例 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim + +simid = sim.getCurSimid() +print("Current SIM is : {}".format(simid)) + +if simid == 0: + # 启用SIM2 + print("Current is SIM 1 and Will switch to SIM2") + sim.switchCard(1) + +``` + +### 双卡切换应用场景 + +以下场景根据客户需求和业务流程,可能需要切卡操作。 + +* 检测到当前卡信号弱满足不了业务需求就尝试切到另一张卡, 比如单车,对讲机。 +* 一张卡接入公网,一张卡接入专网,公网卡主要做数据业务, 专网卡处理一些特殊任务, 比如电网客户。 + +* 用户应用程序在启动时检测到当前SIM卡状态无效,无法进行网络交互,切换到另一张SIM卡。 + +```python +# -*- coding: UTF-8 -*- +#示例 +import sim +import net +import sys + +sim_status_dict={ + 0:"SIM卡不存在/被移除", + 1:"SIM已经准备好", + 2:"SIM卡已锁定,等待CHV1密码", + 3:"SIM卡已被阻拦,需要CHV1密码解锁密码", + 4:"由于SIM/USIM个性化检查失败,SIM卡被锁定", + 5:"由于PCK错误导致SIM卡被阻拦,需要MEP密码解除阻拦", + 6:"需要隐藏电话簿条目的密钥", + 7:"需要解锁隐藏密钥的编码", + 8:"SIM卡已锁定,等待CHV2密码", + 9:"SIM卡被阻拦,需要CHV2解锁密码", + 10:"由于网络个性化检查失败,SIM卡被锁定", + 11:"由于NCK不正确,SIM卡被阻拦,需要MEP解锁密码", + 12:"由于子网络锁个性化检查失败,SIM卡被锁定", + 13:"由于错误的NSCK,SIM卡被阻拦,需要MEP解锁密码", + 14:"由于服务提供商个性化检查失败,SIM卡被锁定", + 15:"由于SPCK错误,SIM卡被阻拦,需要MEP解锁密码", + 16:"由于企业个性化检查失败,SIM卡被锁定", + 17:"由于CCK不正确,SIM卡被阻止,需要MEP解锁密码", + 18:"SIM正在初始化,等待完成", + 19:"CHV1/CHV2/PIN错误", + 20:"SIM卡无效", + 21:"未知状态" +} + +def switch_sim_call(result): + print("Get switch SIM card event : {}".format(reslut)) + if result == 7: + print("SIM switch success!") + net.setModemFun(0) + net.setModemFun(1) + elif result == 9: + print("SIM switch failed!") + + +if __name__ == '__main__': + + sim.setSwitchcardCallback(switch_sim_call) + + sim_status = sim.getStatus() + if sim_status not in sim_status_dict: + print("接口返回失败") + sys.exit() + if sim_status != 20: + # sim卡状态无效 + print("Get SIM status status : {}".format(sim_status_dict[sim_status])) + + #查询当前使用SIM卡 + sim_id = sim.getCurSimid() + + #切换到另一张卡上运行 + if sim_id == 0: + sim.switchCard(1) + else: + sim.switchCard(0) + +``` + + diff --git a/docs/Application_guide/zh/network-comm/sim/Troubleshoot-SIM-card-abnormalities.md b/docs/Application_guide/zh/network-comm/sim/Troubleshoot-SIM-card-abnormalities.md index b143d1d305436400848adcb5c6fcdbda9f416d10..c5281fe722ee46f886174dbe756f2cc10983d235 100644 --- a/docs/Application_guide/zh/network-comm/sim/Troubleshoot-SIM-card-abnormalities.md +++ b/docs/Application_guide/zh/network-comm/sim/Troubleshoot-SIM-card-abnormalities.md @@ -56,7 +56,7 @@ SIM卡状态异常是指通过`sim.getStatus()`这个API查询的值既不是0 步骤3:重启设备,再次查询SIM卡状态,确认是否恢复正常。 -![img](https://gitee.com/no1-wgw/teedoc_with_qpydoc/raw/app_guide/docs/Application_guide/zh/media/network-comm/nic/cellular/%E9%87%8D%E5%90%AF%E5%90%8ESIM%E5%8D%A1%E7%8A%B6%E6%80%81%E6%81%A2%E5%A4%8D%E6%AD%A3%E5%B8%B8.png) +![img](../../media/network-comm/sim/重启后SIM卡状态恢复正常.png) - 当SIM卡状态值是3时 diff --git a/docs/Application_guide/zh/network-comm/sms.md b/docs/Application_guide/zh/network-comm/sms.md index aa2b19b07e1ec512d2c1dfd30e48c405df2f1bc0..b635eb531e2c0f2a4d31b08193b5376776ec1a17 100644 --- a/docs/Application_guide/zh/network-comm/sms.md +++ b/docs/Application_guide/zh/network-comm/sms.md @@ -255,7 +255,7 @@ PDU类型对于SMS-DELIVER,结构图如下: ### 短信接收流程 -短信先从网络接收到短信,之后移动设备终端回复CP-ACK报文到网络,当短信解析完成,移动设备终端再次发送RP-ACK,网络层回复CP-ACK。 +移动设备先从网络侧接收到短信,之后移动设备终端回复CP-ACK报文到网络,当短信解析完成,移动设备终端再次发送RP-ACK,网络层回复CP-ACK。 如下图: @@ -1240,7 +1240,7 @@ SM和ME短信存储空间均已满,导致短信接收不到,只有清除短 * 应用场景7 -短信存储空间为SM,SM存储空间已满的情况下,想保留短信同时也保证短信可以正常接收,可以更换短信接收存储空间为ME。如果ME存储空间也已满。只有删除短信,才能正常接收到短信。 +短信存储空间为SM,SM存储空间已满的情况下,想保留短信同时也保证短信可以正常接收,可以更换短信接收存储空间为ME。如果ME存储空间也已满,只有删除短信,才能正常接收到短信。 * 应用场景8 diff --git a/docs/Application_guide/zh/system/Timer.md b/docs/Application_guide/zh/system/Timer.md deleted file mode 100644 index c947dac69c556c9a4e0271124f927bcdaac67b9d..0000000000000000000000000000000000000000 --- a/docs/Application_guide/zh/system/Timer.md +++ /dev/null @@ -1,614 +0,0 @@ -# 定时器 - -## 概念 - -定时器:一般是指SOC或MCU内部外设器件,这个器件可以周期性引起系统中断。系统可以根据这个信号,切换任务,也可以利用这个信号进行分频输出信号等等操作。 - -硬件上定时器可以分为以下几类: - -* Systick - * 系统滴答定时器,用于提供一个周期性的计时功能,此定时器可以周期的产生中断信号,是系统的心跳时钟,起到切换任务或对任务分配时间片的作用。 -* 基本定时器 - * 没有对外输入/输出,主要用于时基计数以及定时。 -* 通用定时器 - * 除了具备基本定时器功能外,可以对外提供能输入捕捉、输出比较以及连接其他传感器接口的功能。 -* 高级定时器 - * 除了具备通用定时器功能外,可以提供电机控制、数字电源应用、死区时间可编程的互补输出等功能。 -* RTC - * 主要用于提供实时的时间和日期。 -* 看门狗 - * 主要用于监测系统是否出现了异常。 - -## 定时器背景 - -### 介绍 - -定时器可以产生中断,通知CPU当前发生了事件,这样CPU可以不用阻塞等待某一项任务的结果,在等待期间可以运行别的功能。这种方式可以提高效率,对于整体功能来说,系统整体运行更流畅,更便捷,响应更快,用户体验更好,应用更加广泛。 - -### 定时器分类 - -定时器从广泛上分类可分为硬件定时器和软件定时器。硬件定时器是软件定时器的基础,软件定时器在硬件定时器的基础上进行软件上的扩展,理论上是没有个数限制的。但软件定时器不精准,并且当软件定时器数量越多,其差值越大。 - -#### 硬件定时器 - -硬件定时器分为:Systick、基本定时器、通用定时器、高级定时器、RTC定时器、看门狗定时器等。在项目稳定运行过程中,以上定时器各司其职。 - -硬件定时器工作原理概念框架图如下图: - -![image-20230831170457480](../media/system/Timer/2-1.png) - -
图2-1
- -* CLK时钟信号输出到触发控制器。 -* 触发控制器将信号输出到预分频器。 -* 预分频后输出到信号给计数器。 -* 当计数器数值到达自动装载器数值时(根据定时器类型判断处理),如开启使能中断,则定时器产生溢出中断。 - -上述流程即为定时器原理概念概述,以下几类定时器大同小异。 - -##### Systick - -系统滴答定时器,也称为心跳定时器,每次产生Systick中断可以起到切换系统任务的作用,系统以此完成对任务的时间片分配以及任务的切换。切换任务示意图,见图2-2。 - -![image-20230831211006225](../media/system/Timer/2-2.png) - -
图2-2
- -内部结构简图见图2-3。RCC用AHB时钟分频除以8对其提供外部时钟源。 - -![image-20230831211006225](../media/system/Timer/2-3.png) - -
图2-3
- -##### 基本定时器 - -基本功能如下: - -* 自动装载累加计数器。 -* 触发DAC的同步电路。 -* 更新时间产生中断请求。 -* 可编程预分频器。 - -原理概念图见图2-1,时钟从内部或者外部提供给预分频寄存器,经过分频将信号提供给计数寄存器。当计数器达到自动重装载寄存器中的数值时即满足了中断产生的条件,如若开启了中断的功能,此时即可触发中断,完成定时任务。从上可知,定时是通过预分频寄存器,自动重装载寄存器的设置完成的。 - -##### 通用定时器 - -除具备基本定时器功能外,还有以下功能: - -* 向上、向下、向上/向下自动装载计数器。 -* 独立通道。 -* 使用外部信号控制定时器和定时器互连的同步电路。 -* 支持针对定位的增量编码器和霍尔传感器电路。 -* 触发输入作为外部时钟或者按周期的电流管理。 - -原理概念图见图2-1,通用定时器和基本定时器的基本原理是相同的,扩展的功能只是在基本功能上进行了一些简单扩展,这些扩展的功能只是定时器的应用,在此不再赘述。 - -##### 高级定时器 - -除具备通用定时器功能外,还有以下功能: - -* 死区时间可编程的互补输出。 -* 仅在给定周期数后更新定时计数器。 -* 中断信号输入,使计时器的输出信号处于重置状态或已知状态。 -* 设置循环次数,重复计数。 - -原理概念图见2-1,高级定时器和通用定时器、基本定时器的基本原理是相同的,也是对于基本功能的扩展。比较有用的死区时间的功能支持,可以方便PWM的应用。 - -##### RTC定时器 - -实时时钟(RTC)是一个独立的BCD定时器/计数器。其可以将设备从休眠态唤醒用以管理设备的低功率模式。在相应的配置下可以提供时钟日历功能。QuecPython模组重启后RTC时间将被重置,当注网成功后,将会更新RTC时间。其硬件框图如下所示:![image-20230901150953549](../media/system/Timer/2-4.png) - -
图2-4
- - - -##### 看门狗定时器 - -看门狗用于监测和解决由于软件错误导致的故障,当计数器递减到0(或者递增到设定的计数值)时将触发系统复位。其有专用的低速时钟驱动,即使主时钟发生故障也依然有效,通过可配置的时间窗口,即可进行调整看门狗的时间,从上述描述也可指导所谓喂狗即是对计数器重新赋初值(或着计数器清零)。其原理框图如下: - -![image-20230901154440813](../media/system/Timer/2-5.png) - -
图2-5
- -#### 软件定时器 - -软件定时器实现的基础是硬件支持定时任务设置。 - -其实现逻辑是建立一个链表(或者二叉树或者其他的数据结构),设置新的软件定时器时记录到期时间并将其加入到链表中(或者二叉树中)。每一次都选取最近的软件定时器的到期时间并将其设置到硬件定时器中。当触发硬件定时器中断时,即可执行到期的硬件定时任务,在硬件定时任务中既可处理软件定时器的任务。下次到期后选取最近的软件定时器到期时间重新设置到硬件定时器中。如此循环,即可实现软件定时器。从上述原理可以看出软件定时器无法达到硬件定时器的精准,但是可以突破硬件定时器的个数限制。实现逻辑框图如下: - -![image-20230901163248619](../media/system/Timer/2-6.png) - -
图2-6
- -* Step 1 - * 记录当前添加的软件定时器的到期时间,并加入到软件定时器链表中。 -* Step 2 - * 遍历软件定时器链表并排序,选取最小的一个到期时间,将其到期时间设置到硬件定时器中。 -* Step 3 - * 硬件定时器到期,遍历软件定时器链表,执行此定时器注册的事件。并将到期的节点从软件定时器链表中删除。 -* Step 4 - * 判断软件定时器链表是否为空,为空则退出流程。 - -以上只是软件定时器实现的一种简单方式,不是最佳方式,针对不同的场景软件定时器的实现会根据不同的场景进行数据结构的选型和优化。以上只是介绍其实现的基本原理。 - - - -## 定时器接口介绍 - -QuecPython模组定时器分为两种,一种是软件定时器,一种是硬件定时器。硬件定时器用于内核侧,软件定时器QuecPython开放到应用层使用。在QuecPython应用层,定时器又分为了系统定时器和普通定时器。以下仅介绍普通定时器和系统定时器的应用。 - -### 系统定时器 - -QuecPython模组提供底层的定时器接口,当定时器超时会触发定时器绑定的回调函数,在回调函数中不建议做阻塞和费时操作,会影响整体性能。建议在回调函数中仅做发送消息操作,在别的任务中完成业务处理。对于时间精度精度如下表(此表精度仅对于QuecPython接口的系统定时器和普通定时器): - -
表3-1
- - - - - - - - - - - - - - - - - - - - - - - - - - -
型号精度(ms)
Qualcomm10
ASR5
RDA5
UNISOC5
EIGEN5
- - - -#### 创建系统定时器 - -启用定时器前需要先创建定时器,调用如下接口进行创建定时器。 - -```python -osTimer() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import osTimer - -timer = osTimer() - -``` - - - -#### 启动系统定时器 - -创建好定时器后,当要启用定时器时,需调用如下接口启动定时器,时间单位为ms。定时器启动分为单次模式和周期模式。单次模式,定时器只执行一次回调函数,周期模式,定时器会按照设置的周期循环产生超时事件并执行注册的回调函数。QuecPython模组中不建议在任何的回调函数(不仅仅是定时器回调函数中)中做阻塞或者费时操作,否则会影响模组性能。 - -``` -osTimer.start(initialTime, cyclialEn, callback) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import osTimer - -def timer_cb(arg): - print("osTimer Expired!!") -# 创建os定时器 -timer = osTimer() -# 启动定时器,参数依次为时间、是否循环、回调函数 -time_out = 10 -timer.start(time_out * 1000,1,timer_cb) -``` - - - -#### 停止系统定时器 - -当业务完成,暂时不需要定时器时,可以调用如下接口停止定时器,如需要重新使用定时器完成业务只需重新调用启动定时器接口即可。 - -```python -osTimer.stop() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import osTimer -import utime - -time_out = 1 -timer_out_nums = 0 - -# 创建os定时器 -timer = osTimer() -timer_is_runing = True - -def timer_cb(arg): - global timer_out_nums - global timer_is_runing - global timer - timer_out_nums = timer_out_nums + 1 - print("osTimer Expired!! {}".format(timer_out_nums)) - if timer_out_nums >= 10: - timer.stop() - timer_is_runing = False - timer_out_nums = 0 - -if __name__ == "__main__": - - #周期模式启动定时器 - timer.start(time_out * 1000,1,timer_cb) - while timer_is_runing: - utime.sleep(1) - print("waiting timer stop !") - #停止后重新以单次模式启动定时器 - print("will restart timer !") - timer.start(time_out * 1000,0,timer_cb) -``` - - - -#### 删除系统定时器 - -当业务完成之后不再需要定时器时,可以调用如下接口删除定时器。调用此接口后,定时器将被删除,如需要重新启用定时器,需要重新创建定时器并启动定时器。 - -```python -osTimer.delete_timer() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 -import osTimer -import utime - -time_out = 1 -timer_out_nums = 0 - -# 创建os定时器 -timer = osTimer() -timer_is_runing = True - -def timer_cb(arg): - global timer_out_nums - global timer_is_runing - global timer - timer_out_nums = timer_out_nums + 1 - print("osTimer Expired!! {}".format(timer_out_nums)) - if timer_out_nums >= 10: - timer.stop() - timer_is_runing = False - timer_out_nums = 0 - -if __name__ == "__main__": - - #周期模式启动定时器 - timer.start(time_out * 1000,1,timer_cb) - while timer_is_runing: - utime.sleep(1) - print("waiting timer stop !") - - print("will delete timer !") - #删除定时器 - timer.delete_timer() - - #重新创建定时器 - timer1 = osTimer() - - print("will start a new timer !") - #单次模式启动定时器 - timer1.start(time_out * 1000,0,timer_cb) - -``` - -#### 系统定时器应用示例 - -定时器到期后,发送定时器消息到队列,在队列中完成业务。 - -```python -# -*- coding: UTF-8 -*- -#示例 - -import _thread -from queue import Queue -import osTimer -import utime - -class QuecPythonTimer(): - - def __init__(self,timer): - self.timer_out = 10*1000 - self.timer_queue = Queue(100) - self.timer_out_count = 0 - self.timer = timer - self.cycle = 0 - self.is_loop = True - - def timer_set_cycle(self,cycle): - self.cycle = cycle - - def timer_call(self,args): - self.timer_out_count = self.timer_out_count + 1 - print("Will put {} to timer_queue ".format(self.timer_out_count)) - self.timer_queue.put(self.timer_out_count) - - def timer_set_timeout(self,timer_out = 10 * 1000): - self.timer_out = timer_out - - def timer_start(self): - self.timer.start(self.timer_out,self.cycle,self.timer_call) - - def timer_wait_message(self): - while self.is_loop: - data = self.timer_queue.get() - print("Get timer_queue data {}".format(data)) - - -if __name__ == "__main__": - timer = osTimer() - timer = QuecPythonTimer(timer) - - #设置5秒产生一次定时器超时 - timer.timer_set_timeout(5000) - - #设置可以循环产生定时器超时 - timer.timer_set_cycle(1) - - #启动新任务等待定时通知 - _thread.start_new_thread(timer.timer_wait_message, ()) - - #启动定时器 - timer.timer_start() - -``` - - - -### 普通定时器 - -QuecPython模组提供应用层定时器接口,当定时器超时会触发定时器绑定的回调函数,在回调函数中不建议做阻塞和费时操作,会影响整体性能。建议在回调函数中仅做发送消息操作,在别的任务中完成业务处理。时间精度见表3-1。普通定时器最多只支持四个定时器创建。分为单次模式和周期模式。 - -
表3-2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
定时器常量说明
Timer.Timer0定时器0
Timer.Timer1定时器1
Timer.Timer2定时器2
Timer.Timer3定时器3
Timer.ONE_SHOT单次模式,定时器只执行一次
Timer.PERIODIC周期模式,定时器循环执行
- -如上述表3-2所示,普通定时器支持Timer0、Timer1、Timer2和Timer3共四个定时器,每个定时均支持单次模式和周期模式。 - -#### 初始化普通定时器 - -在使用定时器之前需要先初始化定时器,调用如下接口即可初始化定时器。 - -``` -class machine.Timer(Timern) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 - -from machine import Timer -timer1 = Timer(Timer.Timer1) -``` - - - -#### 启动普通定时器 - -初始化定时器后,需要启动定时器才能产生定时器超时事件。调用如下接口即可启动定时器,定期器启动支持设置单词模式和周期模式。单词模式只产生一次定时器超时事件,周期模式会循环(时间间隔为设置的定时器超时时间)产生定时器超时事件。QuecPython模组中不建议在任何的回调函数(不仅仅是定时器回调函数中)中做阻塞或者费时操作,否则会影响模组性能。 - -``` -Timer.start(period, mode, callback) -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 - -from machine import Timer - -timer1 = Timer(Timer.Timer1) - -time_out = 1 -timer_out_nums = 0 -def timer_out_call(args): - global timer_out_nums - timer_out_nums = timer_out_nums + 1 - print("timer will Expired!! {}".format(timer_out_nums)) - -timer1.start(period=time_out*1000, mode=timer1.PERIODIC, callback=timer_out_call) - -``` - - - -#### 停止普通定时器 - -当业务完成后需要停止定时器,可以调用此接口停止定时器。调用此接口后当需要重新启动定时器产生超时事件时,可以重新调用启动定时器接口,重新启动定时器。 - -``` -Timer.stop() -``` - -示例 - -```python -# -*- coding: UTF-8 -*- -#示例 - -from machine import Timer - -timer1 = Timer(Timer.Timer1) - -time_out = 1 -timer_out_nums = 0 -timer_is_runing = True - -def timer_out_call(args): - global timer_out_nums - global timer_is_runing - global timer1 - timer_out_nums = timer_out_nums + 1 - print("timer will Expired!! {}".format(timer_out_nums)) - if timer_out_nums >= 10: - #停止定时器 - timer1.stop() - timer_is_runing = False - timer_out_nums = 0 - -timer1.start(period=time_out*1000, mode=timer1.PERIODIC, callback=timer_out_call) - -``` - -#### 普通定时器应用示例 - -```python -# -*- coding: UTF-8 -*- -#示例 - -import _thread -from queue import Queue -from machine import Timer -import utime - -class QuecPythonTimer(): - - def __init__(self,timer): - self.timer_out = 10*1000 - self.timer_queue = Queue(100) - self.timer_out_count = 0 - self.timer = timer - self.cycle = 0 - self.is_loop = True - - def timer_set_cycle(self,cycle): - self.cycle = cycle - - def timer_call(self,args): - self.timer_out_count = self.timer_out_count + 1 - print("Will put {} to timer_queue ".format(self.timer_out_count)) - self.timer_queue.put(self.timer_out_count) - - def timer_set_timeout(self,timer_out = 10 * 1000): - self.timer_out = timer_out - - def timer_start(self): - self.timer.start(period=self.timer_out,mode=self.cycle,callback=self.timer_call) - - def timer_wait_message(self): - while self.is_loop: - data = self.timer_queue.get() - print("Get timer_queue data {}".format(data)) - -if __name__ == "__main__": - timer1 = Timer(Timer.Timer1) - timer = QuecPythonTimer(timer1) - - #设置5秒产生一次定时器超时 - timer.timer_set_timeout(5000) - - #设置可以循环产生定时器超时 - timer.timer_set_cycle(timer1.PERIODIC) - - #启动新任务等待定时通知 - _thread.start_new_thread(timer.timer_wait_message, ()) - - #启动定时器 - timer.timer_start() -``` - - - -## 定时器常见疑问 - -**问题1:定时器失效有哪些可能?** - -* 检查系统是否压力过大,导致定时器回调函数未能正常执行。 -* 检查是否定时器已经被删除或被停止。 -* 是否虚拟机进行了重启,未重新创建定时器。 - - - -**问题2:定时器是否会因为更新网络时间导致定时器超时时间错乱?** - -* 定时器不会因为更新网络时间导致超时时间错乱 。 - - - -**问题3:关机和深休眠情况下定时器表现怎样?** - -* 关机后定时器不再工作,重启启动后需要重新创建启用定时器。 -* 深休眠后定时器将不再运行,唤醒后定时器也不再起作用,需要重新设置。 - -* 在深休眠情况下RTC可以唤醒模组,正常运行。 - - - -**问题4:硬件定时器软件定时器区别?** - -* 硬定时器系统个数是有限的,软定时器理论上,只要系统资源足够是没有个数限制的。 -* 软定时器实现的基础是硬定时器。 - -**问题5:系统定时器和普通定时器有什么区别** - -* osTimer直接import即可使用,Timer需要从machine模块中引用出来才能使用。 -* 两者包含的方法不同。 -* 在内部原理实现上,两者是相同的,表现一致。 - - - - - diff --git a/docs/Getting_started/en/evb/bg95-evb.md b/docs/Getting_started/en/evb/bg95-evb.md deleted file mode 100644 index 2993de56d70e9a1ea1558110ddd1da8ef41da2de..0000000000000000000000000000000000000000 --- a/docs/Getting_started/en/evb/bg95-evb.md +++ /dev/null @@ -1,155 +0,0 @@ -# BG95 EVB - -## Supported Module List - -- [BG95-M1](https://python.quectel.com/products/bg95) -- [BG95-M3](https://python.quectel.com/products/bg95m3) -- [BG95-M8](https://python.quectel.com/products/bg95m8) - - -## Feature List - -### Overview - -- The QuecPython_BG95_EVB is a compact and portable "pocket-sized" EVB specifically designed for QuecPython. - - -- The main board is equipped with a BG95 series module and a Type-C interface. You can easily develop the EVB with just a USB Type-C cable. - - -- The EVB is also equipped with an expansion board that supports light sensors, UV sensors, VOC sensors, nine-axis sensors, and temperature and humidity sensors. - - -- The EVB is compatible with Raspberry Pi Zero, and the expansion board for Raspberry Pi Zero can be directly used on the QuecPython_BG95_EVB. - - -### Description - -The main components and interface layout of the EVB are shown in the following figure. - -![img](../media/evb/bg95/bg95_layout.png) - -## Resource Download - -- [QuecPython_BG95_Zero EVB Specification and User Guide](https://images.quectel.com/python/2023/08/QuecPython_BG95_Zero%E5%BC%80%E5%8F%91%E6%9D%BF%E8%A7%84%E6%A0%BC%E8%AF%B4%E6%98%8E%E5%8F%8A%E4%BD%BF%E7%94%A8%E6%8C%87%E5%AF%BC%E6%89%8B%E5%86%8C_1.2.pdf) -- [Quectel_BG95_Series_Hardware Design](https://images.quectel.com/python/sites/2/2023/05/Quectel_BG95_Series_Hardware_Design_V1.5.pdf) -- [Quectel_BG95_Series_LPWA_Specification](https://images.quectel.com/python/sites/2/2023/05/Quectel_BG95_Series_LPWA_Specification_V2.0.pdf) -- [Quectel_BG95_Series_Reference_Design](https://images.quectel.com/python/sites/2/2023/05/Quectel_BG95_Series_Reference_Design_V1.3.pdf) -- [Quectel_BG95_3D_Dimensions](https://images.quectel.com/python/2023/05/Quectel_BG95_3D_Dimensions_V1.0.zip) -- [Quectel_BG95_Footprint_Part](https://images.quectel.com/python/2023/05/Quectel_BG95_FootprintPart_V1.2.zip) - - -## Module Resources - -### EVB Interface - -**JP6 Pin Assignment** - -| **Pin Header** | **Number** | **Silkscreen** | **Pin** No. | **Function** | -| -------------- | ---------- | -------------- | ----------- | ------------ | -| JP6 | 1 | PWK_AUTO | 15 | POWERKEY | -| JP6 | 2 | PWK_AUTO | - | 1.8 V | -| JP6 | 3 | VDD_EXT | - | 1.8 V | -| JP6 | 4 | VDD_EXT | 29 | VDD_EXT | -| JP6 | 5 | MODULE_EN | - | 3.6 V | -| JP6 | 6 | MODULE_EN | - | 3.6 V | -| JP6 | 7 | GNSS_EN | - | 3.3 V | -| JP6 | 8 | GNSS_EN | 51 | GNSS_EN | - -- **1 & 2**: Automatic power-on. -- **3 & 4**: VDD_EXT external output or disconnection for power consumption measurement. -- **5 & 6**: Turn on the DC-DC converter to provide power to the module. -- **7 & 8**: Enable active power supply for GNSS. - -**JP7 Pin Assignment** - -| **Pin Header** | **Number** | **Name** | **GPIO Multiplexing** | **Function** | -| -------------- | ---------- | -------- | -------------------------- | ------------ | -| JP7 | 1 | 3V3 | - | 3.3 V Output | -| JP7 | 3 | SDA1 | I2C1_SDA/GPIO14 | | -| JP7 | 5 | SCL1 | I2C1_SCL/GPIO13 | | -| JP7 | 7 | P35 | GPIOX/UART4_TXD | | -| JP7 | 9 | GND | - | Ground | -| JP7 | 11 | P06 | GPIO3/PCM_DIN | | -| JP7 | 13 | P05 | GPIO2/PCM_SYNC | | -| JP7 | 15 | P04 | GPIO1/PCM_CLK | | -| JP7 | 17 | 3V3 | - | 3.3 V Output | -| JP7 | 19 | MO2 | SPI2_MOSI/GPIO8/UART0_TXD | | -| JP7 | 21 | MI2 | SPI2_MISO/GPIO7/UART0_RXD | | -| JP7 | 23 | CLK2 | SPI2-CLK/GPIO5/I2C0_CLK | | -| JP7 | 25 | GND | - | Ground | -| JP7 | 27 | P25 | GPIO9/SPI0_CS | | -| JP7 | 29 | P34 | GPIOX/UART4_RXD | | -| JP7 | 31 | P87 | GPIO20 | | -| JP7 | 33 | P85 | GPIO18/PWM1 | | -| JP7 | 35 | P28 | GPIO12/SPI0_MISO/UART3_RXD | | -| JP7 | 37 | P07 | GPIO4/PCM_DOUT | | -| JP7 | 39 | GND | | Ground | - -**JP8 Pin Assignment** - -| **Pin Header** | **Number** | **Name** | **GPIO Multiplexing** | **Function** | -| -------------- | ---------- | -------- | -------------------------- | ------------ | -| JP8 | 2 | 5V | - | 5 V Output | -| JP8 | 4 | 5V | - | 5 V Output | -| JP8 | 6 | GND | - | | -| JP8 | 8 | TX2 | UART2_TXD | | -| JP8 | 10 | RX2 | UART2_RXD | | -| JP8 | 12 | P37 | GPIOX/I2C_SDA | | -| JP8 | 14 | GND | - | Ground | -| JP8 | 16 | P86 | GPIO19 | | -| JP8 | 18 | P88 | GPIO21 | | -| JP8 | 20 | GND | - | Ground | -| JP8 | 22 | P20 | GPIOX | | -| JP8 | 24 | CS2 | SPI2_CS/GPIO6/I2C0_SDA | | -| JP8 | 26 | P38 | GPIOX | | -| JP8 | 28 | P26 | GPIO10/SPI0_CLK | | -| JP8 | 30 | GND | - | Ground | -| JP8 | 32 | PWM | PWM0/GPIO17 | | -| JP8 | 34 | GND | - | Ground | -| JP8 | 36 | P39 | GPIOX | | -| JP8 | 38 | P27 | GPIO11/SPI0_MOSI/UART3_TXD | | -| JP8 | 40 | P36 | GPIOX/I2C_SCL | | - -The main pin layout of the EVB is shown in the figure below. - -![img](../media/evb/bg95/bg95.png) - -> **Note** -> For more information about QuecPython_BG95_EVB, please visit . - -### EVB Configuration - -The peripheral pin assignments are detailed as follows. - -| No. | Name | Model | Supported | Silkscreen | Remarks | -| --- | -------------------------| -------------| --------| ------| ----------| -| 1 | USB_TYPEC Interface | - | Yes | - | - | -| 2 | SIM Card Slot | SMN-315-ARP7 | Yes | CARD2 | Nano-SIM | -| 3 | LED Indicator (see below)| - | Yes | - | - | - -**On-board LED indicators:** - -- **SIM_CHK**: The SIM_CHK indicator lights up when a SIM card is inserted into the card slot. -- **NET**: Network indicator. -- **PSM**: Sleep mode indicator. -- **PWM**: PWM function indicator. -- **PWR**: Power indicator. - -> Refer to the silkscreen below the module (The module side is the front side) in the EVB figure above for LED indicator locations. - -## Getting Started - -> First, you need a computer running Windows 10 or above. - -- **Step 1: Connect EVB** - -Connect the Type-C port of the EVB to the USB port of your PC with a USB Type-C cable for power supply. - -- **Step 2: Power on EVB** - -Short the two PWK_AUTO pins with a jumper cap to power on the board automatically, or long press the PWK button after power-on. It is recommended that the time interval between power-on and pressing the PWK button should be at least 30 ms. - -After performing the above operations, wait for the power indicator on the main board to light up (silkscreened as PWR. You can refer to LED indicators above). - -**If the PWR indicator is constantly on, the EVB is successfully powered on.** \ No newline at end of file