如何从零开始实现TDOA技术的 UWB 精确定位系统(一)

前言

这是一个系列文章,将向你介绍如何从零开始实现一个使用TDOA技术的 UWB 精确定位系统。

重要提示( 劝退说明 ):

Q:做这个定位系统需要基础么?

A:文章不是写给小白看的,需要有电子技术和软件编程的基础

Q:你的这些硬件/软件是开源的吗?

A:不是开源的。这一系列文章是授人以"渔",而不是授人以"鱼"。文章中我会介绍怎么实现UWB定位系统,告诉你如何克服难点,但不会直接把PCB的Gerber文件给你去做板子,不会把软件的源代码给你,不会把编译好的固件给你。我不会给你任何直接的结果,我只是告诉你方法。

Q:我个人对UWB定位很兴趣,可不可以做出一个定位系统?

A:如果是有很强的硬件/软件背景,并且有大量的时间,当然可以做得出来。文章就是写给你看的!

Q:我是商业公司,我想把UWB定位系统搞成一个商业产品。

A:当然可以。这文章也是写给你看的。如果你想自己从头构建整个系统,看了我的文章后,只需要画电路打板;构思软件结构再编码。就这样,所有的难点我都会在文中提到,并介绍了解决方法。你不需要招人来做算法研究。如果你想省事省时间,可以直接购买我们的电路图(AD工程文件),购买我们的软件源代码,然后快速进入生产环节。(网站: uwbhome.top

从2016年开始,我在所的公司开始了UWB定位项目,到2021年底正式停止这个项目。现在得到老板的许可,解密了。所以我把整个项目的过程写出来。

如果你对 UWB 定位有兴趣,你看了这一系列的文章之后,应该可以自己实现一个 UWB 定位系统。

如果你是商业使用,建议购买我们的技术(顺便广告一下,肯定要比自己从头来做要便宜, 主要是省事见效快,所以你可能要掉的坑,我们都趟过了。网站: uwbhome.top)。

最近这几年,UWB很火。炒了很久,日常生活中似乎也没有见到大规模的应用。但是在一些特定的领域,应用越来越广泛,例如煤矿井下定位/化工生产行业定位等等,这些高危的行业都看到了UWB的好处,所以应用得越来越多。

UWB的无线特点,我就不多写了,网上已经有太多介绍。

UWB芯片

目前,应用比较广泛的是爱尔兰的DecaWave公司UWB芯片。好久没关注这个领域,前段时间访问DecaWave的网站,发现变了,变成Qorvo的一个部门。据说是被苹果收购之后改名叫Qorvo。

我们使用的是DW1000这个芯片,这芯片确实很厉害。先不说它在UWB相关技术如何,在低功耗上,真的是太厉害了。曾经我们有一块开发板,我在测试低功耗的时候,不小心把芯片设置为深度休眠,然后怎么弄,发现芯片都没反应,还以为芯片坏了,扔在一边不管了。但是过了几个星期,把这块"坏"板子捡回来测试,突然发现这芯片又好了。原来,因为模板上有几个小电容,虽然断电了,但是小电容还在给芯片供电,所以芯片一直在休眠中,过了几个星期,小电容没电了,芯片彻底没电,再次上电复位,芯片又正常了。

以下是 DW1000 的技术数据:

  • Supports 110 kbit/s, 850 kbit/s & 6.8 Mbit/s data rates
  • 6 frequency bands supported with center frequencies from 3.5 GHz to 6.5 GHz
  • Transmit Power ?14 dBm or ?10 dBm
  • Transmit Power Density < ?41.3dBm / MHz
  • Preamble Length 64 μs to 4 ms
  • Supports Packet Sizes up to 1023 bytes
  • Modulation: BPM with BPSK
  • Integrated FEC and CRC insertion and checking
  • SPI interface to host controller (20 MHz max)
  • Allows easy integration with wide range of μControllers
  • Single Supply Voltage 2.8 V to 3.6 V
  • Low Power Consumption
  • Transmit mode from 31 mA*
  • Receive mode from 64 mA*
  • 2 μA watchdog timer mode
  • 100 nA deep sleep mode
  • Media Access Techniques
  • FDMA: 6 channels
  • CDMA: 12 different channel codes
  • Supports both two way ranging and one way ranging, using Time of Flight (TOF) and time difference of arrival (TDOA) methods
  • Fabricated in 90 nm CMOS
  • Industrial temperature range -40°C to +85°C
  • 6 mm x 6 mm 48 pin QFN package
  • Hardware & software applications support material available from DecaWave

DecaWave为DW1000提供了很多的例程,如何发送UWB数据包,如何接收UWB数据包,还有几个TOF测距的代码。DecaWave提供的开发板 trek1000 套件,还提供了一个TOF定位的样板系统的源代码。淘宝上很多卖DW1000开发板的店号称提供源代码的,他们提供的应该都是这些代码。

官方开发板 TREK1000 套件,带有4块板子

技术难点一:TDOA技术

TDOA是什么?TDOA的英文全称是Time Difference of Arrival (到达时间差)。其实我们经常使用的GPS/北斗导航,手机(接收终端)使用的定位技术就是TDOA。手机端的GPS芯片根据接收到的卫星的信号的时间差,计算手机所以位置。GPS/北斗使用的是下行TDOA定位,就是由被定位的终端自己计算自己的坐标。

我们使用上行 TDOA 定位

我们要做的不一样,被定位的人或物,携带一个标签(Tag),这个Tag不断的发送UWB信号。在定位区域我们会部署一些基站(Anchor),这些基站会收到Tag发出的UWB信号。我们会有一台电脑运行一个软件叫定位引擎(RTLE),Anchor把收到的UWB信号转换成一些网络数据把发送给定位引擎,定位引擎根据这些数据包计算出标签的坐标。

业内也有做 UWB 下行TDOA定位的。如果做下行TDOA,要求终端要有比较强的计算能力,对终端的电力消耗也是一个考验。GPS系统发布这么多年,以前的体积都很大,这些应用得越来越多,才逐步小型化。如果做 UWB 的下行 TDOA 定位,难点会比较多。

关于TDOA的技术的数学原理,网上已经有很多资料介绍,这里还是简单提一下。

假设一个Tag发出的UWB信号被两个Anchor收到,这两个Anchor收到的时间不一样,有一个时间差。UWB信号是无线电波,它在空中飞行的时间与光速差不多,这个时间差,可以换算为距离差,也就是Tag与这两个Anchor之间的距离的差。根据这个距离差,我们可以在这两个Anchor的周围画出一条曲线,这个曲线上所有的点到两个Anchor之间的距离之差都等于前述的距离差。这是双曲线的一半。

如果有3个Anchor,Tag发出的信号就可以得到3个时间差。画出3条曲线,这3条曲线的交点,就是Tag的坐标。定位引擎要做的事,就是列出几个方程,然后解方程,得到坐标。

原理上确实很简单的。麻烦的地方在于解方程。因为实现中,会有干扰/误差之类的因素影响,3条曲线的交点不是重合。我们需要的是快速计算出近似值,尽量靠近数字上的曲线交点。

当初我们刚开工的时候,到网上一搜,找到很多论文。几乎每一篇论文的作者都会说我这个算法如何如何牛X,并引用很多数据来证明,再写上一堆让人看不明白的数学公式。到后面介绍如何写定位引擎的时候再细说TDOA技术。

技术难点二:时钟同步

既然要用时间差定位,那各个基站得统一时间。大家如果看过战争电影,应该还会有映像,首长安排好各部队的任务后,会说"我们12点准时发起战斗,大家来对一下表"。是的,如果大家的表不一致,有的表已经12点过了,有的表还没到12点,这就乱套了。

各个基站的时间统一了,收到标签发来的UWB信号时,基站会记录下什么时间收到的,然后各个基站把这个时间送到定位引擎,定位引擎再根据这些时间的差来计算坐标。

当初我们在做技术调研的时候,联系过Decawave,他们有无线时钟同步的方案,要10多万美元,还不是代码,只是方案哦。

后来,我们想出了解决办法,发现其实无线时钟同步的方案很简单,就看你能不能想到。

这两个技术难点:TDOA算法、时钟同步方案,在2016/2017年的时候,确实比较难。我猜有很多公司想做UWB定位,但是调研之后,被这两个拦路虎挡住了。只要肯专研,这些难题总是会被解决的。所以现在做UWB定位的公司越来越多。

等你看完我的这一系列文章后,就会发现这两个"难点"其实也没那么难。

我们的目标是什么

折腾一通之后,得到些什么?或者说,我们都要折腾些什么?

简单点说,我们做一个使用 TDOA技术的UWB精确定位系统

被定位的人或物,携带一个标签(Tag),这个Tag不断的发送UWB信号。在定位区域我们会部署一些基站(Anchor),这些基站会收到Tag发出的UWB信号。

我们会有一台电脑运行一个软件叫定位引擎(RTLE),Anchor把收到的UWB信号转换成一些网络数据把发送给定位引擎,定位引擎根据这些数据包计算出标签的坐标。

这个过程就是标准的TDOA定位过程,很简单吧。

这个过程中,涉到的硬件有两样:标签、基站;涉及到的软件有:标签固件、基站固件、定位引擎。

当然,上面所说的是简化版。商品化的产品应该还要有一些其他软件:

  • 标签配置程序
  • 基站配置程序
  • 定位引擎管理程序

例如我们需要对UWB通讯换一个频道,难道要把标签固件和基站硬件重新编译,再刷到板子中?如果用一个配置程序设置一下频道参数,这样不是更方便么。

还有,我们要给固件加一个新功能,难道要把板子拆下来,接上JTag重新刷固件?直接网络升级固件不是更方便么。

定位的过程,在真实环境也更复杂。通常,UWB芯片DW1000的最大通讯范围是200米~300米。如果我们要定位的区域很大,怎么办?一般是划分多个小区域,这些小区域组合成一个大区域。所以,定位引擎要支持多区域定位。

硬件设计和选型

硬件方面,我们要做的是两个东西:标签、基站。

硬件选型最重要的是两个元件:UWB芯片、MCU。

UWB芯片我们使用DW1000。玩电子的都知道,射频电路的设计一向都比较难。所以模电工程师比数电工程师更值钱,越老越值钱。所以,我们不直接使用 DW1000 芯片,而是使用模组 DWM1000。原厂把DW1000封装成一个模组,射频部分我们不用操心了,模组有一组SPI接口,我们可以愉快的把它接到MCU的GPIO上。

DWM1000

MCU的选型。我们使用的主控MCU是STM32F103系列,这个系列的芯片在几年前非常的火。如果是现在选型,我肯定是选ESP32。ESP32又便宜,性能又好,扩充性也强。2020年左右的时候,ST的芯片涨价,我们深受其苦。我们定位基站用的STM32F103RET6,正常价格也就14元左右,最高的时候涨到500元左右,比我们的基站出货价格还高,好疯狂。

因为之前使用的是STM32F103,所以本文的介绍也以它为例来说明。如果用ESP32的话,还有很多细节的工作要做。例如,ESP32有WIFI和蓝牙,那就涉及到如何配网。ESP32也可以外加一个芯片,搞成有线的以太网连接,那又涉及到有线无线双连接,在网络中会有两个IP地址,这些都有不少细节要考虑。所以我们就先不考虑ESP32的事了,还是用STM32F103算了。

无论是基站还是标签,因为使用了DWM1000模块,硬件设计主要是数字电路部分,都是典型的电路,基本上没有什么难度。

基站硬件设计

基站的功能会比较多,对RAM和Flash要求要高一些,所以MCU选STM32F103RET6。

另外,需要连接网络,网络接口芯片使用W5500,这个芯片也是使用SPI接口连接MCU。我之前在好几个项目中使用过W5500,对它比较熟悉,所以就选它了。当然,如果你选择其他熟悉的网络接口芯片,也没问题。

供电部分,如果是个人做实验,直接使用DC12V,或者DC5V都可以。我们在产品中使用POE供电,POE受电芯片使用的是TI 的 TPS23753A,并使用隔离型设计保护基站电路。

其实我们最初的版本是使用DC 12V供电的,我一直想搞成POE供电。画了好几版电路,打了几次样,POE一直没搞定。后来我们团队扩大,增加了一位专门做硬件的同学,最后是他搞定的POE。

第一款量产的基站,使用12V供电

基站的电路图

以下是成品基站的照片

这是上面的电路图对应的PCBA

这是上面的电路图对应的PCBA

这是上面的电路图对应的PCBA

这个基站是尝试WIFI连接,加了一个WIFI模块

这张照片是在示范如何把基站外壳打开,正好可以对比一下人手和外壳的大小

请原谅,我无法把基站电路的AD工程文件放上来,那要留着卖钱。但是我放了一张基站电路的高清图片,你可以自己照着画一份。

电路中使用了24C64,目的是为了保存基站配置。后来固件使用Flash模拟EEPROM,就把24C64取消了。

如果你是DIY弄着玩,板子不用搞得很小。外壳必须要有!DW1000和晶振对温度非常敏感,我们测试过,没有外壳的时候,如果有人从裸板的旁边经过,都会导致DW1000的时钟发生很大的变化

再放一张我们最新版的量产基站的照片给大家欣赏一下,POE供电受电,双网口,集成网络交换机芯片,可以多个基站手拉手级联。

双网口基站,POE供电受电,集成交换机芯片,可级联

基站的这个集成度,只能机器贴片了,如果手工焊接,是个很艰巨的工作。

标签硬件设计

标签我们使用工牌款式,适应范围会广一些。实际上,很多最终用户用的就是工牌款式的标签,使用中的反响还好。

标签的MCU使用STM32F103CBT6,这款芯片面积小一些,RAM和Flash也小。其实开始我们想用STM32F10C8T6,后来发现Flash太小了。因为我们要支持在线的固件升级,那么Flash至少要比固件大两倍,因为除了正在运行中的固件,还要留空间放新上传的固件。还要留一些空间放配置参数。

标签的供电使用800mah锂聚合物电池,充电芯片使用TP4057。这个充电芯片便宜,接口简单。也正因为如此,它不是一个完整的电池管理芯片,它仅仅只是充电,并且还是LDO方式的充电。充电的过程中,把输入的DC 5V转为电池需要的3.5V~4.2V,这两个电压差之间的能量都变成热了。如果充电电流设计得太大,会很热;如果充电电流小,需要的充电时间又会很长。

后期我想换成DC-DC的充电芯片,但是项目停止了,也就算了。如果使用DC-DC的充电芯片,发热会小得多,我们可以把充电电流设计得大一点,充电需要的时间会少得多。但是成本会增加一些,可能还会需要增加一个大电感。

我们还设计了一个无线充电功能,如果你是个人弄着玩,这部分可以不搞。无线充电使用TI 的 BQ51013 芯片。这个芯片支持QI无线充电标准。

考虑到多种用途,标签增加一些小功能:

  • 光敏电阻,用于检测环境光亮度
  • MPU6050三维加速度计
  • 分压电阻检测电池电压

MPU6050的驱动没有弄好,固件的其他功能影响太大,量产的时候我们屏蔽了。由于人手不够,要做的事太多,所以MPU6050一直没空折腾,最后干脆就不贴了,在板子上空着。

分压电阻检测电池电压,可以大致上了解剩余电量。如果有条件的,最好能上一个电量检测的芯片。现在应该有合适的电源管理芯片,集充电/放电/电量管理为一体的芯片。开始的时候,为了省电,分压电阻我们使用1M欧的,后来发现不行,有离散性的误差,有得板子测得准,有的板子有很大误差。因为STM32的ADC内阻并不很大。后来我们改为 100K 欧,这个问题才算解决。

标签的设计上,需要多方面考虑低功耗,尽可能节省电力消耗,让标签的待机时间长一些。

标签的电路图

标签的PCB正面

标签的PCB 3D图

标签的PCBA实物照片

标签的最低功耗达到13.3uA

使用示波器监视标签的电流

标签的最低功耗达到13.3uA,这是标签处于休眠状态时的电流。我们还使用示波器查看标签工作期间的电流消耗情况。从照片中可以清楚的看到标签的几个工作过程:先是处于休眠状态,然后MCU醒来电流增加,DW1000醒来电流又增加,发射UWB数据包(时间短/电流大),再次休眠。

在这里,DW1000醒来到发射的间隔时间有点长,这是等DW1000进入稳定的工作状态。应该还可以把这个等待缩短一些,再节省一点电。

还值得提一下的是,因为工牌很薄,为了节省空间,DWM1000是从背面焊接的。如果从正面焊,PCBA要高些。

我们的工牌标签改版几十次,每次都会有些小差别,但是基本的电路还是那个样子。这些照片供你参考。

标签也可以做成手环款式的。

我们给客户OEM的标签,还有装在车上的。

无论如何,基础的电路还是那个样子。所以,固件写好之后,基本上都是兼容的,一个固件兼容所有型号的标签。

有一个客户希望做一款带显示的手环标签,打算加OLED,显示时间以及显示一些收到的消息,还加上振动马达。研究了一下,发现STM32F103不够用。要显示消息,肯定得有汉字,那得弄一个汉字库,STM32的那个小小Flash肯定装不下。大Flash版本的STM32不好买,还贵。就打算用ESP32来做MCU,还可以顺便加上WiFi和蓝牙支持。后来客户那边的项目停了,再后来,我们这边的项目也停了,就没搞下去了。

如果你是商业使用,建议使用ESP32作为MCU。最好把基站/标签的MCU都换成ESP32,这样的话,统一起来,代码上有可以复用的地方。ESP32便宜性能强,真是个好东西。

第一篇先写到这里吧

相关推荐
Wanliang Li32 分钟前
Linux电源管理——CPU Hotplug 流程
linux·嵌入式硬件·嵌入式·armv8·电源管理·cpuhotplug
憧憬一下2 小时前
PCI/PCIe设备INTx中断机制和MSI中断机制
arm开发·嵌入式硬件·嵌入式·linux驱动开发·pci/pcie
委员2 天前
基于NodeMCU的物联网电灯控制系统设计
单片机·物联网·嵌入式·nodemcu··lu_asr01·gy-302
憧憬一下3 天前
PCIe_Host驱动分析_设备枚举
arm开发·嵌入式硬件·嵌入式·pcie·linux驱动开发
憧憬一下5 天前
PCIe_Host驱动分析_地址映射
arm开发·嵌入式硬件·嵌入式·linux驱动开发·pci/pcie
aspirestro三水哥10 天前
Linux: 通过/proc/pid/stack查看程序卡在内核的什么地方
linux·运维·服务器·嵌入式
@启智森11 天前
【C语言】浮点数的原理、整型如何转换成浮点数
c语言·开发语言·嵌入式·float·int·浮点数
@启智森11 天前
【Uboot】Uboot启动流程分析
linux·c++·嵌入式·uboot·启动·底层
不想写代码的我11 天前
基于ZYNQ-7000系列的FPGA学习笔记11——IP核之单端RAM读写
笔记·学习·fpga开发·嵌入式·zynq
7yewh11 天前
嵌入式 linux Git常用命令 抽补丁 打补丁
linux·arm开发·git·嵌入式硬件·ubuntu·嵌入式·嵌入式软件