简单的温度外设

ble 环境温度设备: examples/ble_temperature.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

from mpython_ble.gatts import Profile
from mpython_ble import UUID
from mpython_ble.services import Service
from mpython_ble.characteristics import Characteristic
from mpython_ble.application import Peripheral
import time
import struct
import random

# 实例profile
profile = Profile()
# 实例Service 环境传感器服务(0x181A)  
# org.bluetooth.service.environmental_sensing
env_sense_service = Service(UUID(0x181A))
# 实例 Characteristic 温度特征(0x2A6E),权限为可读,通知  
# org.bluetooth.characteristic.temperature
temp_char = Characteristic(UUID(0x2A6E), properties='rn')
# 环境传感器服务添加温度特征
env_sense_service.add_characteristics(temp_char)

# 将服务添加到profile
profile.add_services(env_sense_service)

# 实例BLE外设
perip_temp = Peripheral(name=b'mpy_temp', profile=profile, adv_services=[env_sense_service.uuid])
# 开始广播
perip_temp.advertise(True)

t = 25
i = 0
while True:
    # Write every second, notify every 10 seconds.
    time.sleep(1)
    i = (i + 1) % 10
    # Data is sint16 in degrees Celsius with a resolution of 0.01 degrees Celsius.
    # Write the local value, ready for a central to read.
    perip_temp.attrubute_write(temp_char.value_handle, struct.pack('<h', int(t * 100)), notify=i == 0)
    # Random walk the temperature.
    t += random.uniform(-0.5, 0.5)

中央设备连接温度外设

中央设备ble连接上面示例的温度设备: examples/ble_temperature_central.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

from mpython_ble.application import Centeral
from mpython_ble import UUID
import time
import struct


def convert_temperature(bytes_):
    """温度值还原"""
    # 对bytes拆包,转为整形数据。字节的储存顺序为little-endian,无符号整形,2字节。
    # 除100,还原浮点型
    temperature = struct.unpack("<H", bytes_)[0]/100
    return temperature


# 实例BLE中央设备
temp_centeral = Centeral()

# 扫描 temperature device 并连接
while True:
    temp_profile = temp_centeral.connect(name=b'mpy_temp')
    if temp_centeral:
        break
    time.sleep(2)

print("Connected temperature device. gatt profile:")
# print service
for service in temp_profile:
    print(service)


def temperature_notify_callback(value_handle, notify_data):
    """温度特征值的通知事件的回调函数"""
    global temp_characteristic
    # 判断是否为温度特征句柄值
    if value_handle == temp_characteristic.value_handle:
        temperature = convert_temperature(notify_data)
        print("temperature notify: {}" .format(temperature))


for service in temp_profile:
    # 查询 environmental_sensing 服务
    if service.uuid == UUID(0x181A):
        print("find environmental_sensing service (0x181a)")
        for characteristics in service:
            print("find temperature characteristic (0x2a6e)")
            if characteristics.uuid == UUID(0x2A6E):
                temp_characteristic = characteristics
                temperature_bytes = temp_centeral.characteristic_read(temp_characteristic.value_handle)
                print("temperature value is: {}" .format(convert_temperature(temperature_bytes)))
                # 设置温度特征值的回调函数
                temp_centeral.notify_callback(temperature_notify_callback)

Nordic UART

通过 Nordic UART 服务的应用,实现与上位机位端(手机或电脑)的串口通信。

examples/uart_peripheral.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# The MIT License (MIT)
# Copyright (c) 2020, Tangliufeng for labplus Industrie

# Nordic UART 服务的外围设备的示例
# 中央设备端可用手机APP,"nRF Conenct" 或 "nRF Toolbox",配合使用

from mpython_ble.application import BLEUART
import time

uart = BLEUART(name=b'ble_uart')


def rx_irq():
    """串口接收中断函数定义"""
    print('Receive: ', uart.read().decode().strip())


uart.irq(handler=rx_irq)    # 串口中断

# 发送数据
nums = [4, 8, 15, 16, 23, 42]
i = 0

try:
    while True:
        uart.write(str(nums[i]) + '\n')
        i = (i + 1) % len(nums)
        time.sleep_ms(1000)
except KeyboardInterrupt:
    pass

uart.close()

使用 "nRF Connect" 、"nRF Toolbox"等上位机软件或app inventor自己制作APP,来收发BLE UART的数据。

_images/uart_nrfconenct.gif

nRF Connect 查看UART gatt

_images/uart_nrftoolbox.gif

nRF Toolbox 演示与UART与上位机的通讯应用

人机交互设备-翻页笔

ppt翻页笔: examples/ble_ppt_remote.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# The MIT License (MIT)
# Copyright (c) 2020, Tangliufeng for labplus Industrie

# 蓝牙PPT翻页笔
# 下一页: A键  / 上一页: B键

from mpython_ble.application import HID
from mpython_ble.hidcode import KeyboardCode
from mpython import oled, button_a, button_b
import time
import music

ppt_remote = HID(name=b'ble_ppt')  # 实例 BLE HID设备

oled.DispChar("蓝牙ppt翻页笔", 20, 10)
oled.DispChar("说明:下页A键 下页B键", 0, 30)
oled.show()

# 初始化button_before标记变量
btn_a_stat_before = button_a.value()
btn_b_stat_before = button_b.value()

while True:
    # 读取button_a,button_b状态
    btn_a_stat_current = button_a.value()
    btn_b_stat_current = button_b.value()
    time.sleep_ms(20)

    # 检测A键按下时,发送键盘按键码,"PgUp"
    if button_a.value() == btn_a_stat_current:
        if btn_a_stat_before ^ btn_a_stat_current:
            if btn_a_stat_before == 1:
                ppt_remote.keyboard_send(KeyboardCode.PAGE_UP)
                music.pitch(2000, 50, wait=False)
                print("pressed Page Up!")
            btn_a_stat_before = btn_a_stat_current

    # 检测B键按下时,发送键盘按键码,"PgDown"
    if button_b.value() == btn_b_stat_current:
        if btn_b_stat_before ^ btn_b_stat_current:
            if btn_b_stat_before == 1:
                ppt_remote.keyboard_send(KeyboardCode.PAGE_DOWN)
                music.pitch(2000, 50, wait=False)
                print("pressed Page Down!")
            btn_b_stat_before = btn_b_stat_current

Beacon

iBeacon: examples/ibeacon.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# The MIT License (MIT)
# Copyright (c) 2020, Tangliufeng for labplus Industrie

# iBeacon 示例
# 手机使用nRF Beacon app配合示例演示Beacon功能

from mpython_ble.application.beacon import iBeacon
from mpython_ble import UUID

# Proximity UUID 
uuid = UUID("01122334-4556-6778-899a-abbccddeeff0")

# 构建iBeacon 对象
beacon = iBeacon(proximity_uuid=uuid, major=1, minor=2)

# 开始广播
beacon.advertise(Toggle=True)