UWB Unit

UWB 是一款集成 UWB(Ultra Wide Band)通信协议的 Unit,该协议使用纳秒级脉冲来定位物体,并确定位置与方向。其设计采用基于 Decawave 的 DW1000 方案的 Ai-ThinkerBU01 收发器模块。内置的 STM32 芯片集成测距算法,可实现 10 cm 定位精度,并支持 AT 命令控制。应用包括:室内资产无线追踪/测距,通过对基站与标签进行三角定位来确定位置(基站解析位置信息并输出给标签)。该 Unit 当前搭载的固件仅支持测距信息传输,暂不支持自定义信息传输。使用时,支持配置 4 个基站设备(使用不同 ID),且同一时间仅允许 1 个标签设备运行。

支持以下产品:

UWBUnit

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 应用示例:

example_anchor.png

UIFLOW2 标签示例:

example_tag.png

core2_uwb_anchor_example.m5f2

stickc_plus2_uwb_tag_example.m5f2

class UWBUnit

构造函数

class UWBUnit(id, port, device_mode, device_id, verbose)

创建一个 UWB 单元对象。

参数:
  • id – UART ID。

  • port – 单元连接到的端口。

  • device_mode – 设备模式。

  • device_id – 设备 ID。

  • verbose (bool) – 请把需要翻译的 PO 条目(含 msgid/msgstr,以及可能的 #, fuzzy#: 行)贴出来或上传文件。我会按规则只返回对应的中文 msgstr 文本(需要保留为空的条目会保持空)。

UiFlow2

init.png

Methods

UWBUnit.get_distance(index)

获取到锚点 ID(0 ~ 3)的距离。

Return (float):

以米为单位的距离。

参数:

index (int) – 锚点 ID(0 ~ 3)。

UiFlow2

get_distance.png

UWBUnit.get_device_id()

获取设备 ID。

Return (int):

设备 ID。

UiFlow2

get_device_id.png

UWBUnit.get_device_mode()

获取设备模式。

Return (int):

设备模式。

UiFlow2

get_device_mode.png

UWBUnit.set_device_mode(mode, id)

设置设备模式和 ID。

参数:
  • mode (int) – 设备模式。选项:- Anchor:UWBUnit.ANCHOR - Tag:UWBUnit.TAG

  • id (int) – 设备 ID。

UiFlow2

set_device_mode.png

UWBUnit.isconnected()

检查 UWB 单元是否已连接。

返回:

如果已连接则为 True,否则为 False。

UiFlow2

isconnected.png

UWBUnit.get_version()

获取 UWB 单元固件版本。

返回:

固件版本。

UiFlow2

get_version.png

UWBUnit.reset()

重置 UWB 单元。

UWBUnit.set_measurement_interval(interval)

设置测量间隔。

参数:

interval (int) – 测量间隔。

UiFlow2

set_measurement_interval.png

UWBUnit.set_measurement(enable)

设置测量输出。

参数:

enable (bool) – 启用或禁用测量输出。

UiFlow2

set_measurement.png

UWBUnit.set_callback(anchor, event, callback)

设置用于锚点状态的回调函数。

参数:
  • anchor (int) – 锚点 ID(0 ~ 3)。

  • event (int) – 锚点状态。选项:- ONLINE:UWBUnit.ONLINE - OFFLINE:UWBUnit.OFFLINE

  • callback – 回调函数。

UiFlow2

set_callback.png

UWBUnit.update()

更新距离和锚点状态。

UiFlow2

update.png

Constants

UWBUnit.UNKNOWN
UWBUnit.ANCHOR
UWBUnit.TAG

设备角色

UWBUnit.OFFLINE
UWBUnit.ONLINE
UWBUnit._mode_map

设备状态