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的皮。