以前作ったESP32のBLE通信ソフトですが僕にとっては必要十分だったみたいで、
気が付けば2024年の今でも同じソースコードで使っています。
そこで以前WindowsC#で挫折したBLE接続ですが最近PythonのBLEAKで使える様に
なったそうなので挑戦してみる事にしました。
#実行に必要なリソース
ESP32とArduinoIDE開発環境(以前作った奴です)
Windows機とPython開発環境(Bleakをインストールしてください
#機能
ESP32とSerial通信ぽい事をします(サンプルプログラムミみたいな感じです
#使い方
ESP32側もコンパイルして動作させておきます
Windows機からは「ESP32_BLE_SERVER」に接続して通信を行います。
通信するだけのソフトなので、後はお好きな様にどーぞ
#問題点
接続・切断テストを行っていますが、全ての条件が網羅できていない様です。
私はあまりPythonの事をよく判っていません。
WindowsBLE.py
import asyncio
import bleak
from bleak import BleakClient
import time
import threading
async def run1(CONNECTNAME):
global hitDevice
print( "BLE search [" + CONNECTNAME + "] start" )
devices = await bleak.BleakScanner.discover()
for d in devices:
if d.name ==CONNECTNAME :
hitDevice = d
print( "BLE hit [" + CONNECTNAME + "]" )
def BLEreceivecallback( self, data ):
print(data.decode())
async def run2( address, loop ):
global BLEsendMessage, BLELoop, hitUUID
async with BleakClient(address, loop=loop) as client:
for service in client.services:
for c in service.characteristics:
if( service.description=='Vendor specific' ):
print(f"{service.uuid}: {service.description}: {f'{c.properties},{c.uuid}' }")
hitUUID = c.uuid
if hitUUID==None :
return
print( "BLE connect [" + hitDevice.name + "]" )
await client.start_notify( hitUUID, BLEreceivecallback)
while BLELoop:
if BLEsendMessage!=None :
await client.write_gatt_char( hitUUID, BLEsendMessage)
BLEsendMessage = None
await asyncio.sleep(0.0001)
x = await client.is_connected()
if x!=True :
print("BLE disconnect")
return
await client.stop_notify(hitUUID)
def send_thread():
global threadLoop, BLEsendMessage
count = 0
while threadLoop:
msg = f"{count}"
print( msg )
BLEsendMessage = bytearray()
BLEsendMessage.extend( map(ord, msg+"\x00" ) )
count = count + 1
time.sleep(1)
threadLoop = True
BLEsendMessage = None
thread = threading.Thread(target=send_thread)
thread.start()
BLELoop = True
while BLELoop:
hitDevice = hitUUID = None
loop1 = asyncio.get_event_loop()
loop1.run_until_complete(run1( 'ESP32_BLE_SERVER' ))
if hitDevice!= None :
loop2 = asyncio.get_event_loop()
loop2.run_until_complete(run2( hitDevice.address, loop2))
threadLoop = False
print( "end" )
あとがき
以前WindowsのC#でBLE通信に挑戦したのですが挫折しました。
今回Pythonで何とか通信できましたのでBLE/UDPの通信ブリッジを作って、
UDPのPC内通信で.Net C#に繋いでGUIプログラムを作ろうと思います。