项目介绍
本项目是Funpack第四期板卡二的任务3实现.
任务目标是把DWM3001CDK当作蓝牙开发板, 外接一个6x10的像素屏幕和温湿度传感器, 在像素屏幕上实时显示温度或湿度,还可以连接到手机实时展示数据.
实现思路
通过I2C与温湿度传感器通信, 读取温湿度数据.再用一个IO引脚连接到WS2812像素屏幕上, 实时显示温度或者湿度, 使用板子上自带的一个按钮通过长按切换温度或者湿度的显示.
最后再使用Adafruit的bluefruit蓝牙库,配置蓝牙参数. 在设备订阅characteristic后,每隔一秒钟刷新一次数据.
Bootloader烧写
下载Work-on-DWM3001CDK, 找到其中DWM3001CDK使用的bootloader,使用JFlashLite 烧录到开发板上.此时USB插在开发板的J9接口, 即远离Qorvo模组的那个micro USB接口
测试点灯程序
bootloader烧录完毕后, 终于可以继续愉快的使用Arduino API来开发了. 使用Arduino 最经典的例子, 也是大家最喜欢的程序Blink!
程序烧录后, 观察到红色LED亮一秒,灭一秒, 并且控制台输出toggle;
点亮像素屏+蓝牙
一颗LED点亮了, 那么再点60颗吧,顺便再看看蓝牙是怎么个回事.
使用Adafruit_NeoPixel库, 打开neopixel示例, 这是一个蓝牙和像素屏幕结合的例子,可以使用官方提供的App自定义像素屏幕颜色和内容.
理论上说我们只要配置其中的引脚即可, 但是如何知道引脚号呢.
#define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))
在DWM3001CDK-QANI_FreeRTOS示例工程里面, 使用PIN_MASK来组合Port和PIN得到最终引脚号, 那么先来试试吧.
根据搜索到的资料, 我想用P0.27这个SPI_MOSI脚,
代入NRF_GPIO_PIN_MAP得到的还是27
烧录完程序以后, 怎么不亮? 万用表测了一下没有供电, 豁然明白,右侧的是树莓派给开发板供电的示意图, 所以我不可能取到电,于是用板子上给DWM3001C模块供电的跳线处取电.
这下供电正常了,可还是不亮,那么问题出在数据IO上.经过一番排查,发现Arduino里面用的引脚号被做了一层映射.
pinMode之类的函数使用的引脚序号其实是一个索引, 定义在variant.cpp里面
找到27引脚的索引值21, 使用21作为数据脚号码.
重新烧录程序后, 使用adafruit app, 找到neopixel选项卡, 为屏幕添加点颜色.
检查他的源码发现他储存了一个屏幕buffer,然后依次setPixel去修改像素的颜色. 这样对我来说太麻烦了.
记得adafruit有一个matrix库(刚才neopixel上面就是neomatrix,当时没注意), 可以让像素屏幕像普通LCD屏幕一样绘制文字和图像.
所以下载Adafruit_NeoMatrix库打开示例工程, 烧录以后显示不正常.
根据以往的经验,要么是屏幕宽高错误, 要么是LED的走线弄错了.走线排查比较麻烦, 先从宽高入手.
对调宽高烧录程序以后, 终于看到了howdy字样, 不过由于字体尺寸问题,文字最底部被裁切了.小问题,后面换一个字体就好了.
读取温湿度计示数
又是一个Adafruit的库,Adafruit_HTU21DF库中已经写好了传感器的初始化和数据读取.
这次仔细检查默认的I2C引脚到底在开发板上位于什么地方后接线,烧录测试程序.
看到串口已经在输出当前温湿度了.
蓝牙调试
在前面点亮像素屏幕时候已经接触了蓝牙, 并且不用官方的app, 直接使用nRF Connect也可以和开发板通信.
找到UART Service,发送字符V,成功获取当前开发板信息.
以前用过NimBLE这样的蓝牙库,但是折腾一番以后没有在这块板子上跑起来, 编译的时候提示Flash大小不够,于是放弃了这个路线.
感谢adafruit开源, 找到了他的bluefruit_playground示例, 里面有我们需要的一切.
已经封装好了温度和湿度的service和characteristic.
BLEAdafruitTemperature bleTemp;
BLEAdafruitHumid bleHumid;
对温湿度读取部分代码稍作修改
void setup(){
// ...省略部分代码
bleTemp.begin(measure_temperature, 1000); // 每秒钟更新一次
bleHumid.begin(measure_humid, 1000); // 每秒钟更新一次
// ...省略部分代码
}
void loop{
// ...省略部分代码
// 更新温湿度值
temperature = htu.readTemperature();
humidity = htu.readHumidity();
// ...省略部分代码
}
uint16_t measure_temperature(uint8_t* buf, uint16_t bufsize) {
float temp = temperature;
memcpy(buf, &temp, 4);
return 4;
}
uint16_t measure_humid(uint8_t* buf, uint16_t bufsize) {
float humid = humidity;
memcpy(buf, &humid, 4);
return 4;
}
继续使用nRF Connect, 连接开发板以后刚好有两个Service的两个Characteristic支持Notify操作, 这两个应该就是代码中定义的温湿度Characteristic
上位机小程序
不想在电脑上安装Android Studio那一堆臃肿的环境和SDK, 还有极其折磨人的gradle.
手机App索性使用微信小程序来开发吧.
在D老师(DeepSeek)的悉心指导下, 再对他的代码稍作修改直接画好了界面.(D老师对微信小程序的API使用还停留在过去, 需要适配新版本API)
逻辑部分就不劳烦D老师了, 对微信小程序蓝牙部分的API还是有一些印象的.
具体步骤为以下描述:
检查权限->打开蓝牙->找到需要的设备->获取Service->订阅Characteristic
成果展示
为了让示数明显一些, 用风枪开低温吹一吹传感器.
观察到温湿度明显变化.
心得体会
本次活动让我体验了nrf芯片的开发过程, 感慨到Arduino的伟大,让我这样的业余爱好者也能够实现电子制作了.
后续烧录UWB固件,借了一个iPhone体验了一把UWB功能, 科技改变世界.
特别感谢
- 感谢本次活动参与者qqice提供的如何在开发板上跑Arduino的教程, 让我在打算放弃本期活动的时候又重拾了信心.
- 感谢电子森林和德捷联合举办的这次活动.
- 感谢Adafruit开源的大量工程和硬件.
- 感谢DeekSeek老师