-
Notifications
You must be signed in to change notification settings - Fork 11
Closed
Labels
bluetoothBT relatedBT related
Description
Версия модуля: 3.3.5
Модель бризера: S4
Версия прошивки (если известна): 02D2
Описание проблемы
Пишу модуль на микропитоне для esp32, планирую использовать ваши наработки по протоколу для формирования сообщений для бризера S4. Начал с сопряжения и не получается его выполнить. Помогите пожалуйста разобраться с логикой обмена сообщениями с бризером.
Порядок действий, которые приводят к проявлению проблемы
- Использую модуль bluetooth (пробовал и с ubluetooth) микропитона https://docs.micropython.org/en/latest/library/bluetooth.html.
- Перевожу бризер в режим сопряжения (светодиод на бризере мигает синим цветом).
- На esp32 (скетч в конце тикета) отправляю команду
ble.connect(1, ubinascii.unhexlify(b'f022a36c3a55')). - Получаю событие об успешном подключении к бризеру.
# _IRQ_PERIPHERAL_CONNECT:
# A successful gap_connect().
Connection_handle:0 addr_type:1 addr:b'f022a36c3a55'
- Отправляю команду запроса статуса
ble.send(ubinascii.unhexlify(b'8010003aa13232b788d5da1ec11843bbaa')). - Ответа на нее не вижу. Пока представляю себе этот процесс так, что бризер должен уведомить esp32, что положил в ее UUID сообщение и возникнет событие, которое успешно обрабатывается, когда проверял обмен сообщениями с телефоном:
# _IRQ_GATTS_WRITE:
# A client has written to this characteristic or descriptor.
buffer = self.ble.gatts_read(self.rx)
ble_msg = buffer.decode('UTF-8').strip()
- Далее пробовал и делать дисконект, и не делать его
ble.disconnect(). Пробовал отправлять как одну команду запроса статуса за один сеанс привязки, так и несколько команд за один сеанс. Для отладки пока команды формирую в отдельном файле кодом из вашего модуля с 8 рандомными байтами. - Бризер выходит из режима сопряжения.
- Получаю событие о дисконнекте (либо получаю его, когда сам сделал дисконнект)
# _IRQ_PERIPHERAL_DISCONNECT:
# Connected peripheral has disconnected.
- На esp32 отправляю команду
ble.connect(1, ubinascii.unhexlify(b'f022a36c3a55'))и сразу же получаю событие о дисконнекте. - Делаю вывод, что сопряжение не удалось.
Вопросы:
- Нужно ли во время сопряжения перед командой запроса состояния бризера отправлять отдельную команду сопряжения ble.pair()? Посмотрел ваш модуль и не увидел, что она отправляется.
Я ее пробовал отправлять, но модуль на микропитоне ее похоже не поддерживает, т.к. получаю в терминале:
Pairing...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "main.py", line 168, in con2br
File "main.py", line 150, in pair
AttributeError: 'BLE' object has no attribute 'gap_pair'
И в описании модуля написано, что на esp32 она не поддерживается, или же pair поддерживается, но не поддерживается bonding...
- Корректную ли команду запроса состояния бризера я отправляю?
- Как вы предполагаете, почему не получается сделать сопряжение?
Логи
Вставьте сюда debug-log, в момент проявления проблемы
Скетч для esp32:
from machine import Pin
from machine import Timer
from machine import soft_reset
from time import sleep_ms, sleep
# import ubluetooth
import bluetooth
import ubinascii
ble_msg = ""
class ESP32_BLE():
def __init__(self, name):
# Create internal objects for the onboard LED
# blinking when no BLE device is connected
# stable ON when connected
self.led = Pin(2, Pin.OUT)
self.timer1 = Timer(0)
self.name = name
# self.ble = ubluetooth.BLE()
self.ble = bluetooth.BLE()
self.ble.active(True)
self.disconnected()
self.ble.irq(self.ble_irq)
self.register()
self.advertiser()
def connected(self):
self.led.value(1)
self.timer1.deinit()
def disconnected(self):
self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.value(not self.led.value()))
def ble_irq(self, event, data):
global ble_msg
if event == 1: # _IRQ_CENTRAL_CONNECT:
# A central has connected to this peripheral
self.connected()
elif event == 2: # _IRQ_CENTRAL_DISCONNECT:
# A central has disconnected from this peripheral.
self.advertiser()
self.disconnected()
elif event == 3: # _IRQ_GATTS_WRITE:
# A client has written to this characteristic or descriptor.
buffer = self.ble.gatts_read(self.rx)
ble_msg = buffer.decode('UTF-8').strip()
elif event == 5: # _IRQ_SCAN_RESULT:
# A single scan result.
addr_type, addr, adv_type, rssi, adv_data = data
print(
'Addr_type:{} addr:{} adv_type:{} rssi:{} adv_data:{}'.format(addr_type, ubinascii.hexlify(addr),
adv_type, rssi,
ubinascii.hexlify(adv_data)))
elif event == 6: # _IRQ_SCAN_DONE:
# Scan duration finished or manually stopped.
print('Scan stopped (duration finished or manually)')
elif event == 7: # _IRQ_PERIPHERAL_CONNECT:
# A successful gap_connect().
print('Connected')
conn_handle, addr_type, addr = data
print('Connection_handle:{} addr_type:{} addr:{}'.format(conn_handle, addr_type, ubinascii.hexlify(addr)))
elif event == 8: # _IRQ_PERIPHERAL_DISCONNECT:
# Connected peripheral has disconnected.
conn_handle, addr_type, addr = data
print('Disconnected')
elif event == 28: # _IRQ_ENCRYPTION_UPDATE:
# The encryption state has changed (likely as a result of pairing or bonding).
conn_handle, encrypted, authenticated, bonded, key_size = data
print('After pairing: ', conn_handle, encrypted, authenticated, bonded, key_size)
def register(self):
# Nordic UART Service (NUS)
NUS_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
RX_UUID = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
TX_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
# BLE_NUS = ubluetooth.UUID(NUS_UUID)
# BLE_RX = (ubluetooth.UUID(RX_UUID), ubluetooth.FLAG_WRITE)
# BLE_TX = (ubluetooth.UUID(TX_UUID), ubluetooth.FLAG_NOTIFY)
BLE_NUS = bluetooth.UUID(NUS_UUID)
BLE_RX = (bluetooth.UUID(RX_UUID), bluetooth.FLAG_WRITE)
BLE_TX = (bluetooth.UUID(TX_UUID), bluetooth.FLAG_NOTIFY)
BLE_UART = (BLE_NUS, (BLE_TX, BLE_RX,))
SERVICES = (BLE_UART,)
((self.tx, self.rx,),) = self.ble.gatts_register_services(SERVICES)
def send(self, data):
self.ble.gatts_notify(0, self.tx, data + '\n')
def advertiser(self):
name = bytes(self.name, 'UTF-8')
adv_data = bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name
self.ble.gap_advertise(100, adv_data)
print(adv_data)
print("\r\n")
# adv_data
# raw: 0x02010209094553503332424C45
# b'\x02\x01\x02\t\tESP32BLE'
#
# 0x02 - General discoverable mode
# 0x01 - AD Type = 0x01
# 0x02 - value = 0x02
# https://jimmywongiot.com/2019/08/13/advertising-payload-format-on-ble/
# https://docs.silabs.com/bluetooth/latest/general/adv-and-scanning/bluetooth-adv-data-basics
def scan(self, duration):
print('Started scanning')
self.ble.gap_scan(duration)
def connect(self, addr_type, mac, scan_duration=2000):
# addr_type values indicate public or random addresses:
# 0x00 - PUBLIC
# 0x01 - RANDOM(either static, RPA, or NRPA, the type is encoded in the address itself)
print('Connecting')
x = 0
while x < 1:
try:
self.ble.gap_connect(addr_type, mac, scan_duration)
# ble.connect(1, ubinascii.unhexlify(b'f022a36c3a55')) breezer
# ble.connect(1, ubinascii.unhexlify(b'a4c337077418')) iphone
ble.send(ubinascii.unhexlify(b'8010003aa13232b788d5da1ec11843bbaa'))
# ble.send(b'\x80\x10\x00:\xa122(?\xfc\xe7\xb9\x16\xd3\x9d\xbb\xaa')
break
except Exception:
pass
sleep(2)
x += 1
print('Failed to connect')
def disconnect(self, conn_handle=0):
self.ble.gap_disconnect(conn_handle)
def pair(self):
print('Pairing...')
self.ble.gap_pair(0)
led = Pin(2, Pin.OUT)
but = Pin(0, Pin.IN)
ble = ESP32_BLE("ESP32BLE_2")
def buttons_irq(pin):
led.value(not led.value())
ble.send('LED state will be toggled.')
print('LED state will be toggled.')
but.irq(trigger=Pin.IRQ_FALLING, handler=buttons_irq)
def con2br():
ble.connect(1, ubinascii.unhexlify(b'f022a36c3a55'))
# ble.pair()
ble.send(ubinascii.unhexlify(b'8010003aa132325b1033dcac14955bbbaa'))
ble.send(ubinascii.unhexlify(b'8010003aa13232810bd0980babd51abbaa'))
# ble.send(ubinascii.unhexlify(b'8010003aa132325b1033dcac14955bbbaa'))
# ble.disconnect()
# con2br()
while True:
if ble_msg.lower() == 'read_led':
print(ble_msg)
ble_msg = ""
print('LED is ON.' if led.value() else 'LED is OFF')
sleep(10)
ble.send('LED is ON.' if led.value() else 'LED is OFF')
elif ble_msg.lower() == 'scan':
print(ble_msg)
ble_msg = ""
ble.scan(30000) # 10K ms == 10 s
elif ble_msg.lower() == 'connect':
print(ble_msg)
ble_msg = ""
# print(ubinascii.unhexlify('f022a36c3a55'))
ble.connect(1, ubinascii.unhexlify(b'f022a36c3a55'))
elif ble_msg.lower() == 'dis':
print(ble_msg)
ble_msg = ""
#if ble.disconnect():
# print('Disconnected')
#else:
# print('Failed to disconnect')
elif ble_msg.lower() == 'req':
print(ble_msg)
ble_msg = ""
ble.send(b'\x80\x10\x00:\xa122(?\xfc\xe7\xb9\x16\xd3\x9d\xbb\xaa')
elif ble_msg != '':
print(ble_msg)
sleep_ms(100)
Metadata
Metadata
Assignees
Labels
bluetoothBT relatedBT related