Funpack4-1
——板卡二 自命题:无感智能家居系统
一、项目介绍
本项目依托于Funpack4-1活动,基于DWM3001CDK板卡,实现了一个具有LED指示功能的无感智能家居系统。基于qqice开发的DWM3001CDK的Arduino库,实现了板卡间的距离测量,基于这一距离,改变点亮LED的颜色,控制继电器输出,附有数字IO接口输出,以及串口输出距离信息,并接收控制命令。
项目内容:
1、基于DWM3001CDK,使用UWB进行测距。
2、基于距离控制继电器输出、LED颜色和数字输出。
3、串口输出日志并接收输入。
应用场景
本项目唯一无感智能家居的简单演示。现在,包括苹果、华为、小米等越来越多手机品牌的越来越多的手机和手表等硬件都具有了UWB通信功能。UWB通信基于其超高频率和超宽频带,天然具有抗干扰性强、定位精度高、穿透力强等优点。对于智能家居,人的定位是一个无法避免的问题。传统智能家居需要额外安装传感器,如红外、毫米波雷达等。这些传感器由于供电和探测范围的限制,灵活性较低。但是,UWB芯片体积小、易于集成、功耗低,可以自由集成在蓝牙音箱、中控面板等传统网关形态内,也可以集成在吸顶灯、开关面板等非传统形态内。
二、总体架构
图2 总体结构图
系统总体架构图如图所示,基站和发射端相互通信,发射端同时控制继电器开关,达成控制智能家居的效果,同时对外预留串口,可以作为模块集成入别的系统。
三、软件实现
DWM3001CDK支持多种嵌入式开发环境,官方示例基于SEGGER Embedded Studio,同时也基于拓展支持VS Code。但是以上两种方式开发难度较高,示例较少,且较为复杂。感谢qqice,移植了Arduino框架,本文采用qqice移植的Arduino框架进行开发。
本项目中包含发射端和基站的软件实现,由于基站大部分软件实现与发射端类似,因而不在赘述。
3.1 系统初始化
系统上电后,首先进行简单外设的初始化,包含串口、USB CDC、LED和IO输出。
Serial.begin(115200);
UART_init();
test_run_info((unsigned char *)APP_NAME);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_RED_TOP, OUTPUT);
pinMode(LED_RED_BOT, OUTPUT);
pinMode(SDA, OUTPUT);
然后初始化DW3000,并通过USB CDC打印日志。
selectSPIchannel(SPI1);
spiBegin(PIN_IRQ, PIN_RST);
spiSelect(PIN_SS);
delay(2); // Time needed for DW3000 to start up (transition from INIT_RC to IDLE_RC, or could wait for SPIRDY event)
while (!dwt_checkidlerc()) // Need to make sure DW IC is in IDLE_RC before proceeding
{
UART_puts("IDLE FAILED\r\n");
while (1) ;
}
UART_puts("IDLE OK\r\n");
if (dwt_initialise(DWT_DW_INIT) == DWT_ERROR)
{
UART_puts("INIT FAILED\r\n");
while (1) ;
}
UART_puts("INIT OK\r\n");
// Enabling LEDs here for debug so that for each TX the D1 LED will flash on DW3000 red eval-shield boards.
dwt_setleds(DWT_LEDS_ENABLE | DWT_LEDS_INIT_BLINK);
然后对DW3000进行配置。
/* Configure DW IC. See NOTE 6 below. */
if(dwt_configure(&config)) // if the dwt_configure returns DWT_ERROR either the PLL or RX calibration has failed the host should reset the device
{
UART_puts("CONFIG FAILED\r\n");
while (1) ;
}
UART_puts("CONFIG OK\r\n");
/* Configure the TX spectrum parameters (power, PG delay and PG count) */
dwt_configuretxrf(&txconfig_options);
/* Apply default antenna delay value. See NOTE 2 below. */
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(TX_ANT_DLY);
/* Set expected response's delay and timeout. See NOTE 1 and 5 below.
* As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */
dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);
/* Next can enable TX/RX states output on GPIOs 5 and 6 to help debug, and also TX/RX LEDs
* Note, in real low power applications the LEDs should not be used. */
dwt_setlnapamode(DWT_LNA_ENABLE | DWT_PA_ENABLE);
UART_puts("INIT DONE\r\n");
代码中的config如下
static dwt_config_t config = {
5, /* Channel number. */
DWT_PLEN_128, /* Preamble length. Used in TX only. */
DWT_PAC8, /* Preamble acquisition chunk size. Used in RX only. */
9, /* TX preamble code. Used in TX only. */
9, /* RX preamble code. Used in RX only. */
1, /* 0 to use standard 8 symbol SFD, 1 to use non-standard 8 symbol, 2 for non-standard 16 symbol SFD and 3 for 4z 8 symbol SDF type */
DWT_BR_6M8, /* Data rate. */
DWT_PHRMODE_STD, /* PHY header mode. */
DWT_PHRRATE_STD, /* PHY header rate. */
(129 + 8 - 8), /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
DWT_STS_MODE_OFF, /* STS disabled */
DWT_STS_LEN_64,/* STS length see allowed values in Enum dwt_sts_lengths_e */
DWT_PDOA_M0 /* PDOA mode off */
};
至此,系统初始化结束。
3.2主循环
进入主循环,包含几部分,发射准备,发射,接收,读取延时,滤波并计算距离,最后根据距离控制输出
首先是准备发射和发射部分,代码如下
/* Write frame data to DW IC and prepare transmission. See NOTE 7 below. */
tx_poll_msg[ALL_MSG_SN_IDX] = frame_seq_nb;
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS_BIT_MASK);
dwt_writetxdata(sizeof(tx_poll_msg), tx_poll_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(tx_poll_msg), 0, 1); /* Zero offset in TX buffer, ranging. */
/* Start transmission, indicating that a response is expected so that reception is enabled automatically after the frame is sent and the delay
* set by dwt_setrxaftertxdelay() has elapsed. */
dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);
然后是一个while循环,条件是收到基站回复或者超时,代码如下。
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG_BIT_MASK | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))
{ };
经过清除寄存器标志位,读取数据后,然后读取延时,代码如下
/* Retrieve poll transmission and response reception timestamps. See NOTE 9 below. */
poll_tx_ts = dwt_readtxtimestamplo32();
resp_rx_ts = dwt_readrxtimestamplo32();
/* Read carrier integrator value and calculate clock offset ratio. See NOTE 11 below. */
clockOffsetRatio = ((float)dwt_readclockoffset()) / (uint32_t)(1<<26);
/* Get timestamps embedded in response message. */
resp_msg_get_ts(&rx_buffer[RESP_MSG_POLL_RX_TS_IDX], &poll_rx_ts);
resp_msg_get_ts(&rx_buffer[RESP_MSG_RESP_TX_TS_IDX], &resp_tx_ts);
/* Compute time of flight and distance, using clock offset ratio to correct for differing local and remote clock rates */
rtd_init = resp_rx_ts - poll_tx_ts;
rtd_resp = resp_tx_ts - poll_rx_ts;
tof = ((rtd_init - rtd_resp * (1 - clockOffsetRatio)) / 2.0) * DWT_TIME_UNITS;
此时我们已经获得了本次测距的时差,乘以光速,就是本次测速的距离。同时观察到由于电磁扰动,以及天线和时钟偏移未校准等因素,会导致测得的距离存在厘米级别的抖动。基于使用场景推定测得距离的变化较小,因而采用如下的线性IIR滤波器进行滤波,代码如下。
TX到RX的天线延迟总和需通过实验校准。本例中使用硬编码值(预计偏低,导致距离估计有正误差)。实际应用中,每个设备需单独校准天线延迟以确保测距精度。
使用时钟偏移值校正飞行时间计算,可显著提升SS-TWR精度,尤其当响应者时钟与发起者有PPM级偏差时。若天线延迟未校准,测距会有固定偏移(见注释2)。
tof = ((rtd_init - rtd_resp * (1 - clockOffsetRatio)) / 2.0) * DWT_TIME_UNITS;
distance = tof * SPEED_OF_LIGHT;
distance=distance*0.6+dis_l*0.4;
dis_l=distance;
最后,打印距离,并根据距离控制LED和继电器输出
snprintf(dist_str, sizeof(dist_str), "DIST: %3.2f m", distance);
test_run_info((unsigned char *)dist_str);
Serial.printf("distance:%f", distance);
if(distance<0.25)
{
digitalWrite(SDA,0);
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_BLUE, 1);
digitalWrite(LED_RED_TOP, 1);
digitalWrite(LED_RED_BOT, 1);
}
else if(distance<0.5)
{
digitalWrite(SDA,0);
digitalWrite(LED_GREEN, 1);
digitalWrite(LED_BLUE, 0);
digitalWrite(LED_RED_TOP, 1);
digitalWrite(LED_RED_BOT, 1);
}else if(distance<1)
{
digitalWrite(SDA,1);
digitalWrite(LED_GREEN, 1);
digitalWrite(LED_BLUE, 1);
digitalWrite(LED_RED_TOP, 0);
digitalWrite(LED_RED_BOT, 1);
}else if(distance>1)
{
digitalWrite(SDA,1);
digitalWrite(LED_GREEN, 1);
digitalWrite(LED_BLUE, 1);
digitalWrite(LED_RED_TOP, 0);
digitalWrite(LED_RED_BOT,0);
}
四、效果展示
实物如图,效果请参见视频
五、展望
本项目介绍了一种无感的易于集成的智能家居实现方法,并作了一次低成本的尝试。但是本项目有诸多不足,比如,基于单基站的定位无法避免多路径效应,难以剔除距离跳变,定位距离为一球型,在多层建筑中的适应性可能不佳。