项目描述
Qorvo 的 DWM3001CDK 是为基于 DW3110 IC 的 DWM3001C 全集成 (UWB) 模块开发的设计套件,可与 Apple U1 和 U2 芯片互操作。DWM3001C 是一款基于Qorvo DW3110 IC的全集成 UWB 收发模块。 集成DW3110 IC、nRF52833 BLE SoC、平面 UWB 天线、加速度计、电源管理和晶振,大幅缩短设计周期。
内部框图
本期活动我才用Qorvo 的 DWM3001CDK 开发板设计一款类似于AirTag的物品查找设备。该设备可实现1.5m以内的物品报警功能.
此任务我采用任务1+自命题方式完成。使用蓝牙连接设备,UWB进行距离显示,LED指示灯与蜂鸣器实现声光提醒。
AirTag 是苹果公司于 2021 年 4 月推出的一款蓝牙定位追踪器,主要用于帮助用户追踪和查找重要物品.
- 精确查找:以通过 iPhone 的“精确查找”功能,获取物品的方向和距离信息。
- 声音提示:如果物品在蓝牙范围内,用户可以通过“查找”应用或 Siri 让 AirTag 发出声音,从而快速找到它。
简短的硬件介绍
本期我才用DWM3001CDK 开发板板载的LED灯和外接了一款有源蜂鸣器来实现整体功能。
板载有LED四个灯,一个有源蜂鸣器组成。并使用官方提供的Qorvo NearbyInteraction软件查看测距与方位。
整体组成
实物框图
软件流程图
在制作功能之前,除去创建了UWB任务初始化之外,还有蜂鸣器的任务,这样我可以在测距的函数中直接调用这个函数实现声光报警。
板载LED初始化,LED初始化有流水灯效果。
void BoardInit(void)
{
bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
peripherals_init();
for (int i = 0; i < 4; i++)
{
//1号灯
bsp_board_led_invert(BSP_BOARD_LED_0);
nrf_delay_ms(100);
//2号灯
bsp_board_led_invert(BSP_BOARD_LED_3);
nrf_delay_ms(100);
//3号灯
bsp_board_led_invert(BSP_BOARD_LED_2);
nrf_delay_ms(100);
//4号灯
bsp_board_led_invert(BSP_BOARD_LED_1);
nrf_delay_ms(100);
}
}
蜂鸣器初始化与任务创建
nrf_gpio_cfg_output(BSP_BUZZ); //引脚初始化
nrf_gpio_pin_set(BSP_BUZZ); // 设置 GPIO 11 高电平
nrf_delay_ms(100); // 延时 500 毫秒
nrf_gpio_pin_clear(BSP_BUZZ); // 设置 GPIO 11 低电平
nrf_delay_ms(100); // 延时 500 毫秒
buzzerQueue = xQueueCreate(5, sizeof(BuzzerCommand_t)); // 创建队列
// 创建蜂鸣器任务
if (xTaskCreate(buzzer_task, "BuzzerTask", BUZZER_TASK_STACK_SIZE, NULL, BUZZER_TASK_PRIORITY, &buzzerTaskHandle) != pdPASS) {
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
#define BUZZER_PWM_PIN 11 // 连接蜂鸣器的 GPIO 引脚
#define BUZZER_TASK_STACK_SIZE 128
#define BUZZER_TASK_PRIORITY 2
typedef struct {
uint32_t duration_ms; // 持续时间
uint8_t state; // 0 = 关闭, 1 = 打开
} BuzzerCommand_t;
static QueueHandle_t buzzerQueue; // 队列句柄
static TaskHandle_t buzzerTaskHandle; // 任务句柄
void buzzer_task(void *pvParameters) {
BuzzerCommand_t cmd;
nrf_gpio_cfg_output(BSP_BUZZ); // 配置为输出模式
while (1) {
if (xQueueReceive(buzzerQueue, &cmd, portMAX_DELAY) == pdPASS) {
if (cmd.state) {
nrf_gpio_pin_set(BSP_BUZZ); // 打开蜂鸣器
} else {
nrf_gpio_pin_clear(BSP_BUZZ); // 关闭蜂鸣器
}
vTaskDelay(pdMS_TO_TICKS(cmd.duration_ms)); // 持续时间
nrf_gpio_pin_clear(BSP_BUZZ); // 关闭蜂鸣器
}
}
}
void buzzer_control(uint8_t state, uint32_t duration_ms) {
BuzzerCommand_t cmd = { .state = state, .duration_ms = duration_ms };
xQueueSend(buzzerQueue, &cmd, portMAX_DELAY);
}
UWB的任务初始化与任务的创建
if (uwb_init() != DWT_SUCCESS) {
APP_ERROR_HANDLER(NRF_ERROR_RESOURCES);
}
DefaultTaskInit();
//探测DW芯片后,驱动程序版本可用
const char ver[] = FULL_VERSION;
const char *drv_ver = dwt_version_string();
const char *mac_ver = uwbmac_get_version();
char str[256];
int sz;
sz = sprintf(str, "Application: %s\r\n", ApplicationName);
sz += sprintf(&str[sz], "BOARD: %s\r\n", BoardName);
sz += sprintf(&str[sz], "OS: %s\r\n", OsName);
sz += sprintf(&str[sz], "Version: %s\r\n", ver);
sz += sprintf(&str[sz], "Modified By: yanqisui\r\n");
sz += sprintf(&str[sz], "%s\r\n", drv_ver);
sz += sprintf(&str[sz], "MAC: %s\r\n", mac_ver);
sz += sprintf(&str[sz], "ACCESSORY_RANGING_ROLE: %s\r\n", (ACCESSORY_RANGING_ROLE) ? "Initiator" : "Responder");
reporter_instance.print(str, sz);
//启动FreeRTOS调度程序。
osKernelStart();
for (;;) {
APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);
}
软件运行逻辑图
功能展示图片及说明
在与手机非常进的时候(距离 <0.1m)
第一个LED0灯会亮,并且蜂鸣器长响,表示物体距离非常近。
在与手机非常进的时候(距离 <0.5m)
第二个LED3灯会亮,并且蜂鸣器50ms响50ms关闭,表示物体距离已接近。
在与手机非常进的时候(距离 <1.0m)
第二个LED3灯会亮,并且蜂鸣器100ms响100ms关闭,表示物体距离已靠近。
在与手机非常进的时候(距离 <1.5m)
第二个LED4灯会亮,并且蜂鸣器关闭,表示物体距离太远。此时应该提醒客户继续更改查找的方向。
主要代码与逻辑实现
if (distance_cm <= 10)
{
bsp_board_led_on(BSP_BOARD_LED_0);
bsp_board_led_off(BSP_BOARD_LED_3);
bsp_board_led_off(BSP_BOARD_LED_2);
bsp_board_led_off(BSP_BOARD_LED_1);
nrf_gpio_pin_set(BSP_BUZZ);// 蜂鸣器常响
}else if(distance_cm <= 50)
{
bsp_board_led_off(BSP_BOARD_LED_0);
bsp_board_led_on(BSP_BOARD_LED_3);
bsp_board_led_off(BSP_BOARD_LED_2);
bsp_board_led_off(BSP_BOARD_LED_1);
buzzer_control(1, 50); // 蜂鸣器响 50ms
buzzer_control(0, 50); // 关闭蜂鸣器 50ms
}else if(distance_cm <= 100){
bsp_board_led_off(BSP_BOARD_LED_0);
bsp_board_led_off(BSP_BOARD_LED_3);
bsp_board_led_on(BSP_BOARD_LED_2);
bsp_board_led_off(BSP_BOARD_LED_1);
buzzer_control(1, 100); // 蜂鸣器响 100ms
buzzer_control(0, 100); // 关闭蜂鸣器 100ms
}else if(distance_cm <= 150){
bsp_board_led_off(BSP_BOARD_LED_0);
bsp_board_led_off(BSP_BOARD_LED_3);
bsp_board_led_off(BSP_BOARD_LED_2);
bsp_board_led_on(BSP_BOARD_LED_1);
}
项目中遇到的难题和解决方法
由于第一次接触UWB的开发,因此在协议上及开发商遇到了不少的困难,虽然这款NRF52833芯片非常强大。对于前期入门的我来说,开发环境都要搭建好久,最后我在官方的代码中和文件的备注中寻找到了一些线索,通过提供的代码示例,外加大模型来给予解释,因此我很快了解了这款框架的运行逻辑,由于我之前没有接触过FreeRtos因此在编写代码还是比较困难。因为现在AI发展非常好,我很多地方的解读,代码的构建让AI来制作,因此我在给AI喂数据的同时,我也了解了很多,也许这就是作中学,学中作的感觉吧!让我受益匪浅。
对本活动的心得体会
本期的活动让我学习了NRF的开发,使用SEGGER Embedded Studio和官方实例代码完成了一项简单的UWB任务,在这学习期间学到了很多关于UWB的知识,同时通过开发板完成了一个能够解决实际生活的DIY制作。因此我非常心满意足。同时也感谢硬禾学堂举办的Funpack4活动。感谢群友的互助与交流。接下来我会继续学习有关UWB相关的知识和制作。继续给大家分享出有趣好玩的作品。本期就到这里。我们下一期活动再见。
感谢您的耐心阅读
由于工程文件较大,使用网盘进行分项
链接: https://pan.baidu.com/s/1JaoKIlNObF3cPFZ3qQLWzg?pwd=15ut 提取码: 15ut