# ESP32 BLE - Beacon Locating **Repository Path**: walkline/esp32-ble-beacon_locating ## Basic Information - **Project Name**: ESP32 BLE - Beacon Locating - **Description**: 信标定位测试 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 1 - **Created**: 2021-08-03 - **Last Updated**: 2025-05-08 ## Categories & Tags **Categories**: hardware **Tags**: MicroPython, iBeacon ## README

ESP32 BLE - Beacon Locating

### 项目介绍 使用开发板进行信标定位功能测试 ### 获取完整项目 因为项目中使用了子模块 [MicroPython BLE Library](https://gitee.com/walkline/micropython-ble-library) 和 [MicroPython Beacon Library](https://gitee.com/walkline/micropython-beacon-library),所以要获取完整项目代码需要如下操作 #### 克隆方式 ```bash $ git clone --recursive https://gitee.com/walkline/esp32-ble-beacon_locating.git ``` #### 下载压缩文件方式 ```bash $ cd esp32-ble-beacon_locating $ git submodule update --init --recursive ``` > 由于项目结构相对复杂,向开发板上传文件会有一定难度,所以推荐使用 [ab 工具](https://gitee.com/walkline/a-batch-tool) 进行批量上传 #### 不用获取完整项目方式 如果烧录`firmware/`目录下提供固件,那么固件里已经集成了上述两个子模块,就可以使用普通方式获取项目了 ### 使用开发板测试代码 这里使用了一块`esp32 开发板`和一块`esp32c3 32s开发板`进行测试 #### 上传代码 * 使用集成了子模块的固件 ```bash $ ab abc-nolib ``` * 使用官方固件 ```bash $ ab ``` * 不使用`ab`工具 ```bash # 使用相关软件上传完整项目代码 drivers/button.py libs/ble/ble/ libs/beacon/beacon/ utils.py config.py main.py ``` #### 进入`信标模式` 第一次上传代码之后重新上电进入`扫描模式`,这时按住开发板上的`BOOT`按键超过 3 秒会重新上电,并进入`信标模式`,此时开发板上的 Led 常亮 使用`ab`工具进入`repl`模式 ```bash $ ab --repl ``` 查看完整输出内容 ```bash activating ble... W (4841) BTDM_INIT: esp_bt_controller_mem_release not implemented, return OK I (4841) BTDM_INIT: BT controller compile version [501d88d] I (4851) coexist: coexist rom version 9387209 I (4851) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08 I (4971) system_api: Base MAC address is not set I (4971) system_api: read default base MAC address from EFUSE I (4971) BTDM_INIT: Bluetooth MAC: 7c:df:a1:c2:a3:0e GAP procedure initiated: stop advertising. ble activated advertising... GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=160 adv_itvl_max=160 >>> ``` #### 进入`扫描模式` 开发板上的 Led 常亮代表当前为`信标模式`,这时按住开发板上的`BOOT`按键超过 3 秒会重新上电,并进入`扫描模式`,此时开发板上的 Led 熄灭 完整输出内容 ```bash activating ble... I (32694) BTDM_INIT: BT controller compile version [1342a48] I (32694) system_api: Base MAC address is not set I (32694) system_api: read default base MAC address from EFUSE I (32704) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07 ble activated scanning... GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=0 duration=forever ``` #### 查看数据 使用两块开发板分别进入`信标模式`和`扫描模式`,并查看`扫描模式`开发板的输出内容 ```bash [7C:DF:A1:C2:A3:0E] rssi: -54, dis: 1.584893 [7C:DF:A1:C2:A3:0E] rssi: -60, dis: 3.162278 [7C:DF:A1:C2:A3:0E] rssi: -53, dis: 1.412538 [7C:DF:A1:C2:A3:0E] rssi: -55, dis: 1.778279 [7C:DF:A1:C2:A3:0E] rssi: -57, dis: 2.238721 [7C:DF:A1:C2:A3:0E] rssi: -53, dis: 1.412538 [7C:DF:A1:C2:A3:0E] rssi: -54, dis: 1.584893 ``` > `dis`代表两块开发板通过参数计算所得的距离,单位:米 > 还可以使用一个`扫描模式`对应多个`信标模式`开发板的方式进行数据查看 ### 附录 #### 安信可 ESP32C3 开发板针脚 ##### 板载元器件 | Led1 (R) | Led1 (G) | Led1 (B) | Led2 | Led3 | Key2 | | :-: | :-: | :-: | :-: | :-: | :-: | | IO3 | IO4 | IO5 | IO18 | IO19 | IO9 | ##### 可用 GPIO | | 编号 | | :-: | :- | | 12F | 0, 1, 2, 3, 4, 5, 8, 9, 10, 18, 19, 20, 21 | | 13 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18, 19, 20, 21 | | 13U | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18, 19, 20, 21 | | 32S | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 17, 18, 19, 20, 21 | #### `libs/`子模块折腾记录 由于最近刚刚掌握了`git submodule`的使用方法,而且这个项目非常适合使用子模块,所以为此特意进行了一番研究(还特意搞了一个`ab`工具出来。。。) ##### Round 1 一上来直接想当然的就这样添加了一个子模块 ```bash $ git submodule add https://gitee.com/walkline/micropython-ble-library ble-lib/ble ``` 结果是`import`不支持带`-`号的路径 凸-_-凸 ##### Round 2 经过一番思考,最终将子模块路径定为`libs/ble`和`libs/beacon`,然后为了兼容 [不用获取完整项目方式](#不用获取完整项目方式) 使用了如下的骚操作 ```python try: from ble.tools import BLETools # 首先尝试从固件中导入模块 from ble.beacon.client.ibeacon import iBeacon except: from libs.ble.ble.tools import BLETools # 如果失败了就从用户分区导入 from libs.beacon.ble.beacon.client.ibeacon import iBeacon ``` 看似没问题啊?那就赶紧尝试一下吧! 找了块板子,特意刷了不带`ble`模块的固件,使用`ab`工具上传文件,打开`Thonny`,输入代码 ```python >>> from libs.ble.ble.tools import BLETools Traceback (most recent call last): File "", line 1, in File "libs/ble/ble/__init__.py", line 2, in File "libs/ble/ble/tools.py", line 8, in ImportError: no module named 'ble' >>> ``` 惊喜不?`tools.py`第 8 行代码如下 ```python from ble.const import BLEConst ``` ##### Round 3 难到还要去改`libs/`下的代码?没有通用性啊! 最后根据`包导入顺序`这个思路找到`sys.path`这个列表,先看一下详情 ```python >>> import sys >>> help(sys) object is of type module __name__ -- sys path -- ['', '/lib'] argv -- [] version -- 3.4.0 version_info -- (3, 4, 0) implementation -- (name='micropython', version=(1, 12, 0), mpy=10757) platform -- esp32 byteorder -- little maxsize -- 2147483647 exit -- stdin -- stdout -- stderr -- modules -- {'flashbdev': } print_exception -- >>> ``` [查看文档](https://docs.micropython.org/en/latest/library/usys.html#usys.path) 得知,这里的`sys.path`就是导入模块时的搜索路径,默认是``和`/lib`(据说`PyBoard`还有`0:/lib`和`1:/flash`等不同分区下的路径,这里不做考虑),既然是个列表那就可以自己添加路径了,所以尝试了如下方法 ```python >>> import sys >>> sys.path.append('libs/ble') >>> sys.path.append('libs/beacon') >>> from ble.tools import BLETools >>> ``` 貌似成功了?重启设备再来一次! ```python >>> import sys >>> sys.path.append('libs/ble') >>> sys.path.append('libs/beacon') >>> from ble.tools import BLETools >>> from ble.beacon.client.ibeacon import iBeacon Traceback (most recent call last): File "", line 1, in ImportError: no module named 'ble.beacon' >>> ``` ##### Round 4 着实迷惑了一阵啊!!! 这个问题的关键就是`sys.path`里增加路径增加的顺序,先增加了`libs/ble`,然后`import ble.beacon`的时候命中了`libs/ble/ble`这个路径,在这个路径下肯定是找不到`beacon`的,尝试如下 ```python >>> import sys >>> sys.path.append('libs/beacon') # 颠倒了顺序 >>> sys.path.append('libs/ble') >>> from ble.beacon.client.ibeacon import iBeacon Traceback (most recent call last): File "", line 1, in File "libs/beacon/ble/beacon/client/ibeacon/iBeacon.py", line 11, in ImportError: no module named 'ble.const' >>> ``` 倒是印证了前边的猜测,可是怎么解决呢? ##### Round 5 可用但不合理的方法,是一次性导入模块中的全部文件 假设`libs/ble/ble/__init__.py`中有如下代码 ```python from .const import * from .tools import * from .characteristics import * from .descriptors import * from .profile import * from .services import * ``` 那么我们可以做如下的尝试 ```python >>> import sys >>> sys.path.append('libs/ble') >>> from ble import * >>> sys.path.remove('libs/ble') >>> sys.path.append('libs/beacon') >>> from ble.beacon.client.ibeacon import iBeacon >>> ``` 几乎完美啊!除了一次性导入了这么多模块 ```python >>> print('\n'.join(sys.modules)) ble.characteristics.__characteristic ble.beacon.client.ibeacon.iBeacon ble.profile ble.descriptors.descriptors ble.beacon.client ble.descriptors.__descriptor flashbdev ble.descriptors ble.characteristics ble.characteristics.characteristics ble.beacon.client.ibeacon ble.services ble.services.__service ble.const ble.tools ble ble.services.services ble.beacon ``` ##### Round Final 最终的解决方案是,给 [MicroPython Beacon Library](https://gitee.com/walkline/micropython-beacon-library/tree/libs/) 新开了一个`libs`分支,调整目录结构,去掉了最外层的`ble`目录并修改几个文件中的导入路径,然后尝试如下 ```python >>> import sys >>> sys.path.append('libs/ble') >>> sys.path.append('libs/beacon') >>> from ble.tools import BLETools >>> from beacon.client.ibeacon import iBeacon >>> >>> print('\n'.join(sys.modules)) flashbdev beacon beacon.client.ibeacon ble.tools beacon.client.ibeacon.iBeacon ble.const ble beacon.client >>> ``` 至此完美解决 ### 合作交流 * 联系邮箱: * QQ 交流群: * 走线物联:163271910 * 扇贝物联:31324057

走线物联扇贝物联