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}