日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

语言 micropython_MicroPython蓝牙BLE例程实操(一)

發(fā)布時(shí)間:2024/9/3 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 语言 micropython_MicroPython蓝牙BLE例程实操(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

藍(lán)牙作為一種短距通信系統(tǒng),無疑是十分優(yōu)秀,也是十分成功的,特別是隨著近年物聯(lián)網(wǎng)的發(fā)展,各種智能設(shè)備廣泛應(yīng)用,藍(lán)牙BLE以其魯棒性、低功耗、低成本等特點(diǎn),逐漸成為各種智能設(shè)備的標(biāo)準(zhǔn)配置。如今,借助于ESP32平臺(tái),MicroPython中也能夠使用藍(lán)牙BLE協(xié)議進(jìn)行通信。這對MicroPython平臺(tái)而言,自然豐富了其生態(tài),增強(qiáng)了其技能,反過來講,藍(lán)牙BLE能夠在MicroPython中得以集成,借助Python語言的易用性,亦將大大降低其入門門檻。

MicroPython中目前只實(shí)現(xiàn)了藍(lán)牙BLE的低階接口。所謂低階接口,是指其只實(shí)現(xiàn)了藍(lán)牙BLE架構(gòu)鏈路層中所涉及的廣播者/掃描者/中心設(shè)備和外設(shè)設(shè)備的功能接口,也實(shí)現(xiàn)了屬性協(xié)議層中的客戶端和服務(wù)器的功能接口,但更上層的各種具體的應(yīng)用配置規(guī)范(Profile),則沒有實(shí)現(xiàn),甚至廣播時(shí)的廣播包的內(nèi)容,都需要自己進(jìn)行組織。這對于一個(gè)藍(lán)牙系統(tǒng),當(dāng)然不夠直接與直觀,但考慮到MicroPython作為一個(gè)通用平臺(tái),且運(yùn)行于資源有限的微控制器/單片機(jī)上,其只負(fù)責(zé)最底層功能接口的構(gòu)建,用戶可以基于此進(jìn)行具體場景,具體應(yīng)用的實(shí)現(xiàn),又是可以理解的。如果過多的涉及具體設(shè)備的業(yè)務(wù)場景,對于不需要藍(lán)牙功能的用戶來說,反而是一種負(fù)擔(dān),消耗了不必要的資源。

下面,我們以一個(gè)實(shí)例來看看在MicoPython中具體怎樣操作藍(lán)牙BLE的各個(gè)低階接口。此實(shí)例運(yùn)行于ESP32平臺(tái),其作為一個(gè)藍(lán)牙BLE外設(shè)設(shè)備,可首先進(jìn)行廣播以供中心設(shè)備,比如手機(jī),進(jìn)行連接。一旦建立起連接,其可以周期性的向中心設(shè)備上報(bào)消息,反過來,中心設(shè)備也可以向其發(fā)送消息,其會(huì)將接收到的消息簡單打印出來。這里,手機(jī)上運(yùn)行Nodic的nRF Connect軟件進(jìn)行操作。

完整代碼如下:

import bluetoothimport randomimport structimport timefrom ble_advertising import advertising_payloadfrom micropython import const_IRQ_CENTRAL_CONNECT = const(1)_IRQ_CENTRAL_DISCONNECT = const(2)_IRQ_GATTS_WRITE = const(3)_FLAG_READ = const(0x0002)_FLAG_WRITE_NO_RESPONSE = const(0x0004)_FLAG_WRITE = const(0x0008)_FLAG_NOTIFY = const(0x0010)_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")_UART_TX = ( bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"), _FLAG_READ | _FLAG_NOTIFY,)_UART_RX = ( bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"), _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,)_UART_SERVICE = ( _UART_UUID, (_UART_TX, _UART_RX),)class BLESimplePeripheral: def __init__(self, ble, name="mpy-uart"): self._ble = ble self._ble.active(True) self._ble.irq(self._irq) ((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,)) self._connections = set() self._write_callback = None self._payload = advertising_payload(name=name, services=[_UART_UUID]) self._advertise() def _irq(self, event, data): # Track connections so we can send notifications. if event == _IRQ_CENTRAL_CONNECT: conn_handle, _, _ = data print("New connection", conn_handle) self._connections.add(conn_handle) elif event == _IRQ_CENTRAL_DISCONNECT: conn_handle, _, _ = data print("Disconnected", conn_handle) self._connections.remove(conn_handle) # Start advertising again to allow a new connection. self._advertise() elif event == _IRQ_GATTS_WRITE: conn_handle, value_handle = data value = self._ble.gatts_read(value_handle) if value_handle == self._handle_rx and self._write_callback: self._write_callback(value) def send(self, data): for conn_handle in self._connections: self._ble.gatts_notify(conn_handle, self._handle_tx, data) def is_connected(self): return len(self._connections) > 0 def _advertise(self, interval_us=500000): print("Starting advertising") self._ble.gap_advertise(interval_us, adv_data=self._payload) def on_write(self, callback): self._write_callback = callbackdef demo(): ble = bluetooth.BLE() p = BLESimplePeripheral(ble) def on_rx(v): print("RX", v) p.on_write(on_rx) i = 0 while True: if p.is_connected(): # Short burst of queued notifications. for _ in range(3): data = str(i) + "_" print("TX", data) p.send(data) i += 1 time.sleep_ms(100)if __name__ == "__main__": demo()

其中,廣播時(shí)的應(yīng)用負(fù)載用單獨(dú)的一個(gè)python模塊進(jìn)行封裝,體現(xiàn)在上述代碼中的如下語句之中:

from ble_advertising import advertising_payload

該模塊的詳細(xì)代碼如下。其中,真正使用到的只有advertising_payload函數(shù),其余函數(shù)可作代碼的單元測試或其它之用,這里沒有使用到。

from micropython import constimport structimport bluetooth# Advertising payloads are repeated packets of the following form:# 1 byte data length (N + 1)# 1 byte type (see constants below)# N bytes type-specific data_ADV_TYPE_FLAGS = const(0x01)_ADV_TYPE_NAME = const(0x09)_ADV_TYPE_UUID16_COMPLETE = const(0x3)_ADV_TYPE_UUID32_COMPLETE = const(0x5)_ADV_TYPE_UUID128_COMPLETE = const(0x7)_ADV_TYPE_UUID16_MORE = const(0x2)_ADV_TYPE_UUID32_MORE = const(0x4)_ADV_TYPE_UUID128_MORE = const(0x6)_ADV_TYPE_APPEARANCE = const(0x19)# Generate a payload to be passed to gap_advertise(adv_data=...).def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0): payload = bytearray() def _append(adv_type, value): nonlocal payload payload += struct.pack("BB", len(value) + 1, adv_type) + value _append( _ADV_TYPE_FLAGS, struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)), ) if name: _append(_ADV_TYPE_NAME, name) if services: for uuid in services: b = bytes(uuid) if len(b) == 2: _append(_ADV_TYPE_UUID16_COMPLETE, b) elif len(b) == 4: _append(_ADV_TYPE_UUID32_COMPLETE, b) elif len(b) == 16: _append(_ADV_TYPE_UUID128_COMPLETE, b) # See org.bluetooth.characteristic.gap.appearance.xml if appearance: _append(_ADV_TYPE_APPEARANCE, struct.pack("

本次實(shí)驗(yàn)中,使用到的開發(fā)板為ESP32-DEVKIT,如下圖所示。不過,理論上只要能正常跑MicroPython,應(yīng)該都可以。使用的MicoPython固件版本為:esp32-idf3-20200902-v1.13.bin,同樣的,只要能支持藍(lán)牙BLE就行。

這里,使用uPyCraft作為MicroPython的交互工具,如下圖所示。

該軟件使用簡單方便,將上述python文件下載到設(shè)備中后,右擊文件,選中run,即可運(yùn)行。設(shè)備開始廣播,以等待連接,此時(shí)uPyCraft下面會(huì)打印出如下狀態(tài)信息:

此時(shí),打開手機(jī)上的nRF Connect軟件,掃描設(shè)備,即可出現(xiàn)如下界面:

下面這個(gè)mpy-uart即是我們自己的MicroPython藍(lán)牙BLE設(shè)備。點(diǎn)擊CONNECT按鈕,設(shè)備即可連接上手機(jī)。之后,設(shè)備會(huì)以一定間隔給手機(jī)上報(bào)消息,打印信息如下:

在手機(jī)上,亦可看到如下界面:

點(diǎn)開下面這個(gè)Nordic UART Service,即可看到如下界面:

其中,Value處的值一直在自增,該值即為設(shè)備上報(bào)過來的值。點(diǎn)擊RX Characteristic后邊的箭頭,亦會(huì)彈出界面,可以輸入適當(dāng)?shù)闹?#xff0c;即會(huì)發(fā)送到設(shè)備上。

如此,一個(gè)完整的例程及其運(yùn)行效果已經(jīng)展示完畢。

接下來,會(huì)在后續(xù)的系列教程中,對上述例程代碼進(jìn)行詳細(xì)分析解釋,敬請關(guān)注吧!

點(diǎn)關(guān)注,不迷路,關(guān)注公眾號(hào): eeemaker小王子,獲取更多內(nèi)容吧。

總結(jié)

以上是生活随笔為你收集整理的语言 micropython_MicroPython蓝牙BLE例程实操(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。