動機
MicroPytohn
をインストールした Raspberry Pi Pico W
を Mac から BLE REPL
しようとすると、幾つかのエラーに遭遇しました。
その時の対処法について残しておきます。
ESP32他 の MicroPython でも同様と思われる。
macOS 14.7.5
Python 3.11.11
upydev 0.4.3
upydevice 0.3.8
packaging 24.2
MicroPython v1.24.1 on 2024-11-29; Raspberry Pi Pico W with RP2040
BLE REPL
するための準備として、
-
ここの 次の3つのファイルを
Raspberry Pi Pico W
に配置しておくble_advertising.py
,ble_uart_peripheral.py
,ble_uart_repl.py
-
Raspberry Pi Pico W
にて、import ble_uart_repl; ble_uart_repl.start()
を実行しておく
(main.py
に書いておけば(リ)ブート時に自動起動される)
-
Mac に
upydev
をインストールしておく
(pip install upydev
を実行)
エラー 1
% upydev scan -bl
Traceback (most recent call last):
File "/opt/homebrew/bin/upydev", line 19, in <module>
from packaging import version
ModuleNotFoundError: No module named 'packaging'
対処法
インストール済みででしたが、アンインストールして再インストールした。
(pip install packaging -U
ライブラリの最新化で対処できたと思われる)
% pip install packaging
Requirement already satisfied: packaging in /opt/homebrew/lib/python3.11/site-packages (24.0)
% pip uninstall packaging
Found existing installation: packaging 24.0
Uninstalling packaging-24.0:
Would remove:
/opt/homebrew/lib/python3.11/site-packages/packaging-24.0.dist-info/*
Proceed (Y/n)? y
Successfully uninstalled packaging-24.0
% pip install packaging
Collecting packaging
Downloading packaging-24.2-py3-none-any.whl.metadata (3.2 kB)
Downloading packaging-24.2-py3-none-any.whl (65 kB)
Installing collected packages: packaging
Successfully installed packaging-24.2
エラー 2
% upydev scan -bl
Bluetooth Low Energy scan:
Scanning...
BleDevice/s found: 3
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ NAME ┃ UUID ┃ RSSI ┃ Services ┃
┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ mpy-repl ┃ 856C4A83-B2D3-339F-8CE2-xxxxxxxxxxxx ┃ -56 ┃ ┃
┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
Traceback (most recent call last):
File "/opt/homebrew/bin/upydev", line 1034, in <module>
handle_action(args)
File "/opt/homebrew/bin/upydev", line 499, in handle_action
debugging_action(args, unknown_args, command_line=' '.join(sys.argv[1:]),
File "/opt/homebrew/lib/python3.11/site-packages/upydev/debugging.py", line 1045, in debugging_action
print('┃{0:^20} ┃ {1:^40} ┃ {2:^10} ┃ {3:^40} ┃'.format(dev.name, dev.address,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported format string passed to NoneType.__format__
対処法
上記エラーログにあるdebugging.py
のソースコードを修正した。
(1行追加)
+ if dev.name is None: dev.name = '(None)'
print('┃{0:^20} ┃ {1:^40} ┃ {2:^10} ┃ {3:^40} ┃'.format(dev.name, dev.address,
int(dev.rssi), ','.join(services)))
これで無事に検索できるようになった。
% upydev scan -bl
Bluetooth Low Energy scan:
Scanning...
BleDevice/s found: 2
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ NAME ┃ UUID ┃ RSSI ┃ Services ┃
┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ (None) ┃ 4256B44A-5C48-2353-4E15-xxxxxxxxxxxx ┃ -60 ┃ ┃
┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ mpy-repl ┃ 856C4A83-B2D3-339F-8CE2-xxxxxxxxxxxx ┃ -62 ┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
エラー 3
% blerepl -t 856C4A83-B2D3-339F-8CE2-xxxxxxxxxxxx
Traceback (most recent call last):
File "/opt/homebrew/bin/blerepl", line 63, in <module>
dev.connect(show_servs=args.v, debug=args.v)
File "/opt/homebrew/lib/python3.11/site-packages/upydevice/bledevice.py", line 1320, in connect
return self.as_connect(**kargs).result()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/unsync/unsync.py", line 144, in result
return self.concurrent_future.result(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.11/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py", line 456, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.11/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
File "/opt/homebrew/lib/python3.11/site-packages/upydevice/bledevice.py", line 1309, in as_connect
if hasattr(self.ble_client._peripheral, 'name'):
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'BleakClient' object has no attribute '_peripheral'
対処法
上記エラーログにあるbledevice.py
のソースコードを修正した。
(2行変更、2行追加)
async def as_connect(self, n_tries=5, show_servs=True, debug=False):
await self.connect_client(n_tries=n_tries, debug=debug)
if self.connected:
self.get_services(log=show_servs)
- if hasattr(self.ble_client._peripheral, 'name'):
+ if hasattr(self.ble_client, '_peripheral') and hasattr(self.ble_client._peripheral, 'name'):
if callable(self.ble_client._peripheral.name):
self.name = self.ble_client._peripheral.name()
- else:
+ elif hasattr(self.ble_client, '_device_info') and hasattr(self.ble_client._device_info, 'get'):
self.name = self.ble_client._device_info.get('Name')
+ else:
+ self.name = '(None)'
if self.name in _WASPDEVS:
self.len_buffer = 20
else:
raise DeviceNotFound('BleDevice @ {} is not reachable'.format(self.UUID))
これで無事に接続できるようになった。
% blerepl -t 856C4A83-B2D3-339F-8CE2-xxxxxxxxxxxx
BleREPL connected
MicroPython v1.24.1 on 2024-11-29; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
- CTRL-k to see keybindings or -h to see help
- CTRL-s to toggle shell/repl mode
- CTRL-x or "exit" to exit
rp2@e66138528394892c:~ $ (Ctrl+S)
>>> import sys
>>> sys.version
'3.4.0; MicroPython v1.24.1 on 2024-11-29'
>>> (Ctrl+X)
>>> closing...
>>>
logout
Connection to (None) closed.
%
しかし、
これで BLE REPL
できるようになったが、まだ次のエラーが出る。
エラー 4
% upydev scan -bl
Bluetooth Low Energy scan:
Scanning...
BleDevice/s found: 1
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ NAME ┃ UUID ┃ RSSI ┃ Services ┃
┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
/opt/homebrew/lib/python3.11/site-packages/upydev/debugging.py:1036: FutureWarning: BLEDevice.metadata is deprecated and will be removed in a future version of Bleak, use AdvertisementData instead
if hasattr(dev, 'metadata'):
/opt/homebrew/lib/python3.11/site-packages/upydev/debugging.py:1037: FutureWarning: BLEDevice.metadata is deprecated and will be removed in a future version of Bleak, use AdvertisementData instead
if isinstance(dev.metadata, dict):
/opt/homebrew/lib/python3.11/site-packages/upydev/debugging.py:1038: FutureWarning: BLEDevice.metadata is deprecated and will be removed in a future version of Bleak, use AdvertisementData instead
if 'uuids' in dev.metadata.keys():
/opt/homebrew/lib/python3.11/site-packages/upydev/debugging.py:1041: FutureWarning: BLEDevice.metadata is deprecated and will be removed in a future version of Bleak, use AdvertisementData instead
for serv in dev.metadata['uuids']]
/opt/homebrew/lib/python3.11/site-packages/upydev/debugging.py:1048: FutureWarning: BLEDevice.rssi is deprecated and will be removed in a future version of Bleak, use AdvertisementData.rssi instead
int(dev.rssi), ','.join(services)))
ググってみたが、有効な対処法が見つからず。
致命傷では無いので とりあえずスルー。
エラー 5
⭐️ REPL
で Ctrl+D
すると例外が発生する。
% blerepl -t 856C4A83-B2D3-339F-8CE2-xxxxxxxxxxxx
BleREPL connected
MicroPython v1.24.1 on 2024-11-29; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
- CTRL-k to see keybindings or -h to see help
- CTRL-s to toggle shell/repl mode
- CTRL-x or "exit" to exit
rp2@e66138528394892c:~ $ (Ctrl+S)
>>> (Ctrl+D) ⭐️
Unhandled exception in event loop:
File "/opt/homebrew/Cellar/python@3.11/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/events.py", line 84, in _run
self._context.run(self._callback, *self._args)
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/input/vt100.py", line 162, in callback_wrapper
callback()
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/application/application.py", line 714, in read_from_input_in_context
context.copy().run(read_from_input)
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/application/application.py", line 694, in read_from_input
self.key_processor.process_keys()
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/key_binding/key_processor.py", line 273, in process_keys
self._process_coroutine.send(key_press)
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/key_binding/key_processor.py", line 188, in _process
self._call_handler(matches[-1], key_sequence=buffer[:])
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/key_binding/key_processor.py", line 323, in _call_handler
handler.call(event)
File "/opt/homebrew/lib/python3.11/site-packages/prompt_toolkit/key_binding/key_bindings.py", line 127, in call
result = self.handler(event)
^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/upydev/shell/keybindings.py", line 766, in paste_mode_exit
dev.reset()
File "/opt/homebrew/lib/python3.11/site-packages/upydevice/bledevice.py", line 1558, in reset
return self.un_reset(**kargs).result()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/unsync/unsync.py", line 144, in result
return self.concurrent_future.result(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.11/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py", line 456, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.11/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
File "/opt/homebrew/lib/python3.11/site-packages/upydevice/bledevice.py", line 1553, in un_reset
await self.as_reset(**kargs)
File "/opt/homebrew/lib/python3.11/site-packages/upydevice/bledevice.py", line 750, in as_reset
await self.as_write_char(self.writeables['Nordic UART RX'],
File "/opt/homebrew/lib/python3.11/site-packages/upydevice/bledevice.py", line 399, in as_write_char
await self.ble_client.write_gatt_char(uuid, data)
File "/opt/homebrew/lib/python3.11/site-packages/bleak/__init__.py", line 786, in write_gatt_char
await self._backend.write_gatt_char(characteristic, data, response)
File "/opt/homebrew/lib/python3.11/site-packages/bleak/backends/corebluetooth/client.py", line 326, in write_gatt_char
await self._delegate.write_characteristic(
File "/opt/homebrew/lib/python3.11/site-packages/bleak/backends/corebluetooth/PeripheralDelegate.py", line 196, in write_characteristic
await future
Exception disconnected
Press ENTER to continue...
同時に、Raspberry Pi Pico W
は リセット(ソフトブート)される。
>>>
MPY: soft reboot
Unhandled exception in IRQ callback handler
Traceback (most recent call last):
File "/lib/ble_uart_peripheral.py", line 66, in _irq
File "/lib/ble_uart_peripheral.py", line 94, in _advertise
OSError: [Errno 19] ENODEV
MicroPython v1.24.1 on 2024-11-29; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>>
原因は、
REPL で Ctrl+D
すると ソフトブートされる。これは正しい動作
⇨ ブートにより、BLE通信が切断される
⇨ Mac側のblerepl
コマンドで例外が発生
REPL でCtrl+D
しなければ問題ない。
以上