Newer
Older
smart-home-server / devices / sensor / bme280_sensor.h
@root root 18 hours ago 2 KB Device. Sensor
#pragma once

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BMP280.h>

/*
	Конфигурация датчика BME280 / BMP280.
*/
struct Bme280Config {
	uint8_t sda_pin = 18;
	uint8_t scl_pin = 19;
	uint8_t i2c_address = 0x76;

	/*
		Через сколько миллисекунд без успешного чтения
		данные считаются устаревшими.
	*/
	uint32_t stale_after_ms = 3000;

	/*
		Интервал чтения датчика.
	*/
	uint32_t read_interval_ms = 1000;

	/*
		Коэффициенты сглаживания EMA.
	*/
	float temperature_ema_alpha = 0.25f;
	float pressure_ema_alpha = 0.20f;
	float humidity_ema_alpha = 0.20f;
};

enum BmeSensorType {
	BME_SENSOR_TYPE_UNKNOWN = 0,
	BME_SENSOR_TYPE_BMP280,
	BME_SENSOR_TYPE_BME280
};

class Bme280Sensor {
public:
	Bme280Sensor();
	~Bme280Sensor();

	/*
		Инициализация собственной I2C-шины и попытка
		подключения BME280/BMP280.
	*/
	bool begin(TwoWire &wire, const Bme280Config &config);

	/*
		Периодическое обновление состояния датчика.
	*/
	void update();

	/*
		Статус датчика.
	*/
	bool is_online() const;
	bool has_valid_data() const;
	bool is_stale() const;

	/*
		Тип найденного датчика.
	*/
	BmeSensorType get_sensor_type() const;
	String get_sensor_type_string() const;

	/*
		Текущие значения.
	*/
	float get_temperature_c() const;
	float get_pressure_hpa() const;
	float get_humidity_percent() const;

	/*
		Есть ли влажность.
		Для BMP280 всегда false.
	*/
	bool has_humidity() const;

	/*
		JSON состояния.
	*/
	String get_state_json() const;

private:
	Bme280Config _config;

	TwoWire *_wire = nullptr;

	Adafruit_BME280 *_bme280 = nullptr;
	Adafruit_BMP280 *_bmp280 = nullptr;

	BmeSensorType _sensor_type = BME_SENSOR_TYPE_UNKNOWN;

	bool _initialized = false;
	bool _online = false;
	bool _has_valid_data = false;

	uint32_t _last_read_attempt_ms = 0;
	uint32_t _last_success_read_ms = 0;

	float _temperature_c = 0.0f;
	float _pressure_hpa = 0.0f;
	float _humidity_percent = 0.0f;

	float _filtered_temperature_c = 0.0f;
	float _filtered_pressure_hpa = 0.0f;
	float _filtered_humidity_percent = 0.0f;

private:
	bool init_bme280();
	bool init_bmp280();

	void update_filtered_temperature(float value);
	void update_filtered_pressure(float value);
	void update_filtered_humidity(float value);
};