前一阵用esp32-c3制作的传感器集合中数字传感器的结果很准确,但模拟传感器TEMT6000给出的结果比较离谱,这里尝试对其进行校准。

手头上没有专业的照度计,于是淘了个便宜的数字照度传感器BH1750(datasheet),精度达1 lx,范围0~65535 lx,I2C总线。

部署BH1750

接线比较简单。

ESP32-C3 BH1750
GPIO04 SDA
GPIO05 SCL

esphome固件配置如下(完整代码参考这里):

1
2
3
4
5
6
7
8
9
i2c:
sda: GPIO04
scl: GPIO05

sensor:
- platform: bh1750
name: "${upper_devicename} BH1750 Illuminance"
address: 0x23
update_interval: 60s

数据分析

跑了一天结果如下:

2022-10-26_22-08

BH1750和TEMT6000并排放置(那个Bedroom是乱写的)。可见TEMT6000的值偏低,起伏和BH1750大致一致,但是亮度超过340 lx后有截断。

导出一天的数据到csv,用pandas进行数据处理。

2022-10-26_22-58

值得一提的是两个传感器的有效数据不一样,而且采样时间略有差别,数据合并上需要点技巧:具体来说就是要将1分钟以内的时间视为同一条,本来用dt.floor('Min'),后来发现merge_asof中用tolerance可以简单地在合并过程中实现。

然后用scikit-learn对数据进行拟合。先用最简单的线性回归看看效果:

2022-10-26_22-59

Score达0.9599,效果还行。

校准

根据coef_intercept_可以对TEMT6000的代码进行修正了:

1
2
3
4
5
6
7
8
9
sensor:
- platform: adc
pin: GPIO0
name: "${upper_devicename} Illuminance"
update_interval: 60s
unit_of_measurement: lx
filters:
- lambda: |-
return x * 200.0 * 1.725 + 1.72;

参考资料

BH1750 Ambient Light Sensor

pandas.merge_asof