DIY低功耗BLE传感器 - 软件篇
TODO
MCU端
广播协议
一开始两眼一抹黑,甚至差点想去买个现成的BLE开关看看人家的协议长啥样,不过还好偶然找到了BTHome,这是一个开放的BLE传感器协议,生态做的挺全的,已经集成在Home Assistant里了。
基于沁恒EVT包里的 Broadcaster DEMO魔改了一下,广播数据如下:
static uint8_t advertData[] = {
0x02, 0x01, 0x06, // Flags
14, // length
0x16, // service data - 16bit uuid
0xD2 ,0xFC, // uuid
0b01000100, // BTHome info, trigger based, unencrypted
0x00, // type, packet id
0x00, // packet id value
0x02, // type, temperature
0x00, 0x00, // temperature value
0x0C, // type, voltage, resolution 0.001 V
0x00, 0x00, // voltage value
0x3A, // type, button
0x00, // value, 0 = none, 1 = pressed
0x04, // length
0x09, // complete local name
'D', 'I', 'Y', // local name
};
传感器数据按照BTHome标准,是按照ID排序的,否则Home Assistant会报Warning。
Packet ID (0x0
) 是用来帮助去重的,因为广播没有ACK机制,为了尽量保证送达,发送端肯定不能只发一帧,肯定至少狂发好几帧一样的报文。加上Packet ID之后一方面能滤掉重复报文,另一方面也能避免两帧内容相同但实际不重复的报文被当成重复的。
Temperature (0x02
) 是温度传感器数据,目前先用片内的温度传感器凑合一下,等SHT40好使了之后再使用SHT40的数据。
Voltage (0x0C
) 是电池电压,因为我们是电池直接供电,所以可以用内部电池电压采样通道,简单换算一番即可。
uint16_t getBatVoltage(void) {
ADC_InterBATSampInit();
// (ADC/512-3)*1.05 * 1000 (mv)
// 1050 * ADC / 512 - 3150
uint16_t raw = ADC_ExcutSingleConver();
uint32_t converted = (raw * 1050) / 512 - 3150;
return (converted & 0xffff);
}
Button (0x3A
) 就是按键了,1代表按下。
BTHome,一开始使用esphome代理,发现效果稀烂
BLE
两个按键一个用了PB22,正好兼作为BOOT按键。下载程序使用串口,本来是想着体积比A口小,焊接比C口容易,还能顺便输出调试信息,没留电源输入引脚是懒得做双电源OR-ing。
广播参数
Home Assistant 集成
一层一层剥开Home Assistant的皮。