#include "bh1750_sensor.h"
Bh1750Sensor::Bh1750Sensor() {
}
bool Bh1750Sensor::begin(const Bh1750Config &config) {
_config = config;
Wire.begin(_config.sda_pin, _config.scl_pin);
/*
Пробуем перевести датчик в выбранный режим измерения.
*/
if (!send_command(_config.measurement_mode)) {
_initialized = false;
_online = false;
return false;
}
_initialized = true;
_online = true;
return true;
}
void Bh1750Sensor::update() {
if (!_initialized) {
return;
}
uint32_t now_ms = millis();
if (now_ms - _last_read_attempt_ms < _config.read_interval_ms) {
return;
}
_last_read_attempt_ms = now_ms;
uint16_t raw_value = 0;
if (!read_measurement(raw_value)) {
_online = false;
return;
}
_online = true;
_has_valid_data = true;
_last_success_read_ms = now_ms;
_last_raw_value = raw_value;
/*
Согласно даташиту:
lux = raw / 1.2
*/
_raw_lux = static_cast<float>(raw_value) / 1.2f;
update_filtered_lux(_raw_lux);
}
float Bh1750Sensor::get_raw_lux() const {
return _raw_lux;
}
float Bh1750Sensor::get_filtered_lux() const {
return _filtered_lux;
}
bool Bh1750Sensor::has_valid_data() const {
return _has_valid_data;
}
bool Bh1750Sensor::is_stale() const {
if (!_has_valid_data) {
return true;
}
uint32_t now_ms = millis();
return (now_ms - _last_success_read_ms) > _config.stale_after_ms;
}
bool Bh1750Sensor::is_online() const {
return _online;
}
String Bh1750Sensor::get_state_json() const {
String json = "{";
json += "\"sensor\":\"bh1750\",";
json += "\"online\":" + String(_online ? "true" : "false") + ",";
json += "\"has_valid_data\":" + String(_has_valid_data ? "true" : "false") + ",";
json += "\"stale\":" + String(is_stale() ? "true" : "false") + ",";
json += "\"i2c_address\":\"0x" + String(_config.i2c_address, HEX) + "\",";
json += "\"data\":{";
json += "\"raw_value\":" + String(_last_raw_value) + ",";
json += "\"raw_lux\":" + String(_raw_lux, 2) + ",";
json += "\"filtered_lux\":" + String(_filtered_lux, 2);
json += "}";
json += "}";
return json;
}
bool Bh1750Sensor::send_command(uint8_t command) {
Wire.beginTransmission(_config.i2c_address);
Wire.write(command);
return (Wire.endTransmission() == 0);
}
bool Bh1750Sensor::read_measurement(uint16_t &raw_out) {
Wire.requestFrom((int)_config.i2c_address, 2);
if (Wire.available() != 2) {
return false;
}
uint8_t msb = Wire.read();
uint8_t lsb = Wire.read();
raw_out = (static_cast<uint16_t>(msb) << 8) | lsb;
return true;
}
void Bh1750Sensor::update_filtered_lux(float new_lux) {
if (!_has_valid_data || _filtered_lux == 0.0f) {
_filtered_lux = new_lux;
return;
}
_filtered_lux =
(_filtered_lux * (1.0f - _config.lux_ema_alpha)) +
(new_lux * _config.lux_ema_alpha);
}