bme680_driver/
settings.rs

1use crate::{Celsius, Milliseconds};
2
3/// Einstellungen für das Oversampling von Temperatur, Druck und Feuchtigkeit.
4///
5/// Höhere Oversampling-Raten reduzieren das Rauschen durch Mittelwertbildung in der Hardware,
6/// verlängern jedoch die Messdauer und erhöhen den Stromverbrauch pro Messzyklus.
7#[derive(Debug, Clone, Copy, PartialEq, Default)]
8#[repr(u8)]
9pub enum Oversampling {
10    /// Keine Messung. Deaktiviert den entsprechenden Sensorkanal vollständig.
11    Skipped = 0,
12    /// 1-faches Oversampling (Standard).
13    #[default]
14    X1 = 1,
15    /// 2-faches Oversampling.
16    X2 = 2,
17    /// 4-faches Oversampling.
18    X4 = 3,
19    /// 8-faches Oversampling.
20    X8 = 4,
21    /// 16-faches Oversampling. Maximale Präzision, längste Dauer.
22    X16 = 5,
23}
24
25impl Oversampling {
26    /// Erzeugt eine Instanz aus einem Rohwert (hilfreich beim Parsen von Registern).
27    pub fn from_u8(value: u8) -> Self {
28        match value {
29            1 => Oversampling::X1,
30            2 => Oversampling::X2,
31            3 => Oversampling::X4,
32            4 => Oversampling::X8,
33            5 => Oversampling::X16,
34            _ => Oversampling::Skipped,
35        }
36    }
37}
38
39/// Gruppierte Oversampling-Konfiguration für alle Umwelt-Sensoren.
40///
41/// Nutzen Sie `Oversampling::Skipped`, um Kanäle zu deaktivieren, die für Ihre
42/// Anwendung nicht relevant sind (spart Zeit und Energie).
43#[derive(Default, Debug, Clone, Copy)]
44pub struct OversamplingConfig {
45    /// Oversampling für den Temperatursensor.
46    pub temp_osrs: Oversampling,
47    /// Oversampling für den Luftfeuchtigkeitssensor.
48    pub hum_osrs: Oversampling,
49    /// Oversampling für den Luftdrucksensor.
50    pub pres_osrs: Oversampling,
51}
52
53impl OversamplingConfig {
54    /// Gibt `true` zurück, wenn alle TPH-Sensoren auf `Skipped` stehen.
55    pub fn is_all_skipped(&self) -> bool {
56        self.temp_osrs == Oversampling::Skipped
57            && self.hum_osrs == Oversampling::Skipped
58            && self.pres_osrs == Oversampling::Skipped
59    }
60}
61
62/// Koeffizient für den IIR (Infinite Impulse Response) Filter.
63///
64/// Der Filter glättet kurzfristige Störungen in den Druck- und Temperaturwerten
65/// (z.B. durch zuschlagende Türen oder Luftzüge). Er hat keinen Einfluss auf
66/// Feuchtigkeit oder Gas.
67#[derive(Default, Debug, Clone, Copy)]
68#[repr(u8)]
69pub enum IIRFilter {
70    /// Filter deaktiviert.
71    #[default]
72    IIR0 = 0,
73    IIR1 = 1,
74    IIR3 = 2,
75    IIR7 = 3,
76    IIR15 = 4,
77    IIR31 = 5,
78    IIR63 = 6,
79    IIR127 = 7,
80}
81
82/// Verfügbare Speicherplätze (Slots) für Heizprofile im Sensor (0 bis 9).
83#[derive(Default, Debug, Clone, Copy)]
84#[repr(u8)]
85pub enum GasProfileIndex {
86    #[default]
87    Profile0 = 0,
88    Profile1 = 1,
89    Profile2 = 2,
90    Profile3 = 3,
91    Profile4 = 4,
92    Profile5 = 5,
93    Profile6 = 6,
94    Profile7 = 7,
95    Profile8 = 8,
96    Profile9 = 9,
97}
98
99/// Konfiguration für die Heizplatte des Gassensors.
100#[derive(Default, Debug, Clone, Copy)]
101pub struct GasProfile {
102    /// Index des Profil-Slots im Sensor-Speicher.
103    pub index: GasProfileIndex,
104    /// Zieltemperatur der Heizplatte (typischerweise 300°C bis 400°C).
105    pub target_temp: Celsius,
106    /// Dauer, für die die Temperatur vor der Messung gehalten wird (Aufheizzeit).
107    pub wait_time: Milliseconds,
108}
109
110/// Vollständiges Konfigurationsobjekt für den BME680.
111#[derive(Default, Debug, Clone, Copy)]
112pub struct Config {
113    /// Oversampling-Einstellungen für T, P und H.
114    pub osrs_config: OversamplingConfig,
115    /// IIR-Filter-Einstellung zur Rauschunterdrückung.
116    pub iir_filter: IIRFilter,
117    /// Gassensor-Profil. `None` deaktiviert die Heizung und die Gasmessung (spart ~12mA).
118    pub gas_profile: Option<GasProfile>,
119    /// Aktuelle Schätzung der Umgebungstemperatur.
120    /// Wichtig für die korrekte Berechnung der Heizleistung.
121    pub ambient_temp: Celsius,
122}
123
124impl Config {
125    /// Prüft, ob die Gasmessung laut Konfiguration aktiv ist.
126    pub(crate) fn gas_enabled(&self) -> bool {
127        self.gas_profile.is_some()
128    }
129
130    /// Prüft, ob die Gasmessung deaktiviert ist.
131    pub(crate) fn gas_disabled(&self) -> bool {
132        self.gas_profile.is_none()
133    }
134}
135
136/// Komfortabler Builder zum Erstellen einer `Config`.
137///
138/// Der Builder stellt sicher, dass alle Parameter logisch zusammenhängen und
139/// bietet eine saubere API für die Initialisierung.
140#[derive(Default)]
141pub struct BME680Builder {
142    config: Config,
143}
144
145impl BME680Builder {
146    pub fn new() -> Self {
147        Self::default()
148    }
149
150    /// Setzt das Oversampling für die Temperatur.
151    pub fn temp_oversampling(mut self, os: Oversampling) -> Self {
152        self.config.osrs_config.temp_osrs = os;
153        self
154    }
155
156    /// Setzt das Oversampling für die Luftfeuchtigkeit.
157    pub fn hum_oversampling(mut self, os: Oversampling) -> Self {
158        self.config.osrs_config.hum_osrs = os;
159        self
160    }
161
162    /// Setzt das Oversampling für den Luftdruck.
163    pub fn pres_oversampling(mut self, os: Oversampling) -> Self {
164        self.config.osrs_config.pres_osrs = os;
165        self
166    }
167
168    /// Setzt den IIR-Filter-Koeffizienten.
169    pub fn iir_filter(mut self, filter: IIRFilter) -> Self {
170        self.config.iir_filter = filter;
171        self
172    }
173
174    /// Aktiviert oder deaktiviert das Gasprofil.
175    pub fn gas_profile(mut self, profile: Option<GasProfile>) -> Self {
176        self.config.gas_profile = profile;
177        self
178    }
179
180    /// Setzt die initial geschätzte Umgebungstemperatur für die Heizungsberechnung.
181    pub fn ambient_temp(mut self, temp: Celsius) -> Self {
182        self.config.ambient_temp = temp;
183        self
184    }
185
186    /// Finalisiert den Builder und gibt das `Config` Objekt zurück.
187    pub fn build(self) -> Config {
188        self.config
189    }
190}