UWB Unit
UWB 是一款集成 UWB(Ultra Wide Band)通信协议的 Unit,该协议使用纳秒级脉冲来定位物体,并确定位置与方向。其设计采用基于 Decawave 的 DW1000 方案的 Ai-ThinkerBU01 收发器模块。内置的 STM32 芯片集成测距算法,可实现 10 cm 定位精度,并支持 AT 命令控制。应用包括:室内资产无线追踪/测距,通过对基站与标签进行三角定位来确定位置(基站解析位置信息并输出给标签)。该 Unit 当前搭载的固件仅支持测距信息传输,暂不支持自定义信息传输。使用时,支持配置 4 个基站设备(使用不同 ID),且同一时间仅允许 1 个标签设备运行。
支持以下产品:
MicroPython 锚点示例:
1# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8from unit import UWBUnit 9 10 11label0 = None 12label4 = None 13label1 = None 14label5 = None 15label2 = None 16label6 = None 17label3 = None 18label7 = None 19circle0 = None 20circle1 = None 21circle2 = None 22circle3 = None 23uwb_0 = None 24 25 26def uwb_0_0_online_event(args): 27 global \ 28 label0, \ 29 label4, \ 30 label1, \ 31 label5, \ 32 label2, \ 33 label6, \ 34 label3, \ 35 label7, \ 36 circle0, \ 37 circle1, \ 38 circle2, \ 39 circle3, \ 40 uwb_0 41 circle0.setColor(color=0x33FF33, fill_c=0x33FF33) 42 43 44def uwb_0_1_online_event(args): 45 global \ 46 label0, \ 47 label4, \ 48 label1, \ 49 label5, \ 50 label2, \ 51 label6, \ 52 label3, \ 53 label7, \ 54 circle0, \ 55 circle1, \ 56 circle2, \ 57 circle3, \ 58 uwb_0 59 circle1.setColor(color=0x33FF33, fill_c=0x33FF33) 60 61 62def uwb_0_2_online_event(args): 63 global \ 64 label0, \ 65 label4, \ 66 label1, \ 67 label5, \ 68 label2, \ 69 label6, \ 70 label3, \ 71 label7, \ 72 circle0, \ 73 circle1, \ 74 circle2, \ 75 circle3, \ 76 uwb_0 77 circle2.setColor(color=0x33FF33, fill_c=0x33FF33) 78 79 80def uwb_0_3_online_event(args): 81 global \ 82 label0, \ 83 label4, \ 84 label1, \ 85 label5, \ 86 label2, \ 87 label6, \ 88 label3, \ 89 label7, \ 90 circle0, \ 91 circle1, \ 92 circle2, \ 93 circle3, \ 94 uwb_0 95 circle3.setColor(color=0x33FF33, fill_c=0x33FF33) 96 97 98def uwb_0_0_offline_event(args): 99 global \ 100 label0, \ 101 label4, \ 102 label1, \ 103 label5, \ 104 label2, \ 105 label6, \ 106 label3, \ 107 label7, \ 108 circle0, \ 109 circle1, \ 110 circle2, \ 111 circle3, \ 112 uwb_0 113 circle0.setColor(color=0xFF0000, fill_c=0xFF0000) 114 115 116def uwb_0_1_offline_event(args): 117 global \ 118 label0, \ 119 label4, \ 120 label1, \ 121 label5, \ 122 label2, \ 123 label6, \ 124 label3, \ 125 label7, \ 126 circle0, \ 127 circle1, \ 128 circle2, \ 129 circle3, \ 130 uwb_0 131 circle1.setColor(color=0xFF0000, fill_c=0xFF0000) 132 133 134def uwb_0_2_offline_event(args): 135 global \ 136 label0, \ 137 label4, \ 138 label1, \ 139 label5, \ 140 label2, \ 141 label6, \ 142 label3, \ 143 label7, \ 144 circle0, \ 145 circle1, \ 146 circle2, \ 147 circle3, \ 148 uwb_0 149 circle2.setColor(color=0xFF0000, fill_c=0xFF0000) 150 151 152def uwb_0_3_offline_event(args): 153 global \ 154 label0, \ 155 label4, \ 156 label1, \ 157 label5, \ 158 label2, \ 159 label6, \ 160 label3, \ 161 label7, \ 162 circle0, \ 163 circle1, \ 164 circle2, \ 165 circle3, \ 166 uwb_0 167 circle3.setColor(color=0xFF0000, fill_c=0xFF0000) 168 169 170def setup(): 171 global \ 172 label0, \ 173 label4, \ 174 label1, \ 175 label5, \ 176 label2, \ 177 label6, \ 178 label3, \ 179 label7, \ 180 circle0, \ 181 circle1, \ 182 circle2, \ 183 circle3, \ 184 uwb_0 185 186 M5.begin() 187 Widgets.fillScreen(0x222222) 188 label0 = Widgets.Label("Anchor0", 0, 4, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 189 label4 = Widgets.Label("label4", 0, 120, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu12) 190 label1 = Widgets.Label("Anchor1", 80, 4, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 191 label5 = Widgets.Label("label5", 80, 120, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu12) 192 label2 = Widgets.Label("Anchor2", 160, 4, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 193 label6 = Widgets.Label("label6", 160, 120, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu12) 194 label3 = Widgets.Label("Anchor3", 240, 4, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 195 label7 = Widgets.Label("label7", 240, 120, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu12) 196 circle0 = Widgets.Circle(38, 50, 15, 0xFF0000, 0xFF0000) 197 circle1 = Widgets.Circle(118, 52, 15, 0xFF0000, 0xFF0000) 198 circle2 = Widgets.Circle(193, 51, 15, 0xFF0000, 0xFF0000) 199 circle3 = Widgets.Circle(273, 51, 15, 0xFF0000, 0xFF0000) 200 201 uwb_0 = UWBUnit(2, port=(33, 32), device_mode=UWBUnit.TAG, verbose=False) 202 uwb_0.set_callback(0, uwb_0.ONLINE, uwb_0_0_online_event) 203 uwb_0.set_callback(1, uwb_0.ONLINE, uwb_0_1_online_event) 204 uwb_0.set_callback(2, uwb_0.ONLINE, uwb_0_2_online_event) 205 uwb_0.set_callback(3, uwb_0.ONLINE, uwb_0_3_online_event) 206 uwb_0.set_callback(0, uwb_0.OFFLINE, uwb_0_0_offline_event) 207 uwb_0.set_callback(1, uwb_0.OFFLINE, uwb_0_1_offline_event) 208 uwb_0.set_callback(2, uwb_0.OFFLINE, uwb_0_2_offline_event) 209 uwb_0.set_callback(3, uwb_0.OFFLINE, uwb_0_3_offline_event) 210 uwb_0.set_measurement_interval(5) 211 uwb_0.set_measurement(True) 212 213 214def loop(): 215 global \ 216 label0, \ 217 label4, \ 218 label1, \ 219 label5, \ 220 label2, \ 221 label6, \ 222 label3, \ 223 label7, \ 224 circle0, \ 225 circle1, \ 226 circle2, \ 227 circle3, \ 228 uwb_0 229 M5.update() 230 uwb_0.update() 231 label4.setText(str(uwb_0.get_distance(0))) 232 label5.setText(str(uwb_0.get_distance(1))) 233 label6.setText(str(uwb_0.get_distance(2))) 234 label7.setText(str(uwb_0.get_distance(3))) 235 236 237if __name__ == "__main__": 238 try: 239 setup() 240 while True: 241 loop() 242 except (Exception, KeyboardInterrupt) as e: 243 try: 244 from utility import print_error_msg 245 246 print_error_msg(e) 247 except ImportError: 248 print("please update to latest firmware")
MicroPython 标签示例:
1# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8from hardware import * 9from unit import UWBUnit 10 11 12label0 = None 13label1 = None 14uwb_0 = None 15 16 17anchor_id = None 18 19 20def btnA_wasClicked_event(state): # noqa: N802 21 global label0, label1, uwb_0, anchor_id 22 anchor_id = (anchor_id + 1) % 4 23 uwb_0.set_device_mode(UWBUnit.ANCHOR, anchor_id) 24 label1.setText(str(uwb_0.get_device_id())) 25 26 27def setup(): 28 global label0, label1, uwb_0, anchor_id 29 30 M5.begin() 31 label0 = Widgets.Label("label0", 29, 36, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu24) 32 label1 = Widgets.Label("0", 44, 98, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu72) 33 34 BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btnA_wasClicked_event) 35 36 anchor_id = 0 37 uwb_0 = UWBUnit(2, port=(33, 32), device_mode=UWBUnit.ANCHOR, device_id=0, verbose=False) 38 print(uwb_0.isconnected()) 39 print(uwb_0.get_version()) 40 if (uwb_0.get_device_mode()) == 1: 41 label0.setText(str("Anchor")) 42 else: 43 label0.setText(str("Tag")) 44 label1.setText(str(uwb_0.get_device_id())) 45 46 47def loop(): 48 global label0, label1, uwb_0, anchor_id 49 M5.update() 50 51 52if __name__ == "__main__": 53 try: 54 setup() 55 while True: 56 loop() 57 except (Exception, KeyboardInterrupt) as e: 58 try: 59 from utility import print_error_msg 60 61 print_error_msg(e) 62 except ImportError: 63 print("please update to latest firmware")
UIFLOW2 Anchor 应用示例:
UIFLOW2 标签示例:
stickc_plus2_uwb_tag_example.m5f2
class UWBUnit
构造函数
Methods
- UWBUnit.get_distance(index)
获取到锚点 ID(0 ~ 3)的距离。
- Return (float):
以米为单位的距离。
- 参数:
index (int) – 锚点 ID(0 ~ 3)。
UiFlow2

- UWBUnit.get_device_id()
获取设备 ID。
- Return (int):
设备 ID。
UiFlow2

- UWBUnit.get_device_mode()
获取设备模式。
- Return (int):
设备模式。
UiFlow2

- UWBUnit.set_device_mode(mode, id)
设置设备模式和 ID。
UiFlow2

- UWBUnit.isconnected()
检查 UWB 单元是否已连接。
- 返回:
如果已连接则为 True,否则为 False。
UiFlow2

- UWBUnit.get_version()
获取 UWB 单元固件版本。
- 返回:
固件版本。
UiFlow2

- UWBUnit.reset()
重置 UWB 单元。
- UWBUnit.set_callback(anchor, event, callback)
设置用于锚点状态的回调函数。
- 参数:
UiFlow2

- UWBUnit.update()
更新距离和锚点状态。
UiFlow2

Constants
- UWBUnit.UNKNOWN
- UWBUnit.ANCHOR
- UWBUnit.TAG
设备角色
- UWBUnit.OFFLINE
- UWBUnit.ONLINE
- UWBUnit._mode_map
设备状态





