Żeby odczytać stężenie CO2 z czujnika Sensirion SCD41, wystarczy około dziesięciu linii YAML w ESPHome. Trudniej sprawić, żeby ten odczyt był wiarygodny także po kilku miesiącach. Czujnik sam koryguje swój dryf, ale algorytm, który to robi, zakłada pewne rzeczy o pomieszczeniu. Jeśli pomieszczenie ich nie spełnia, wyniki powoli rozjeżdżają się z rzeczywistością, a w dzienniku nie widać żadnego błędu. Podłączenie i konfiguracja zajmują kilka minut. O tym, czy wartości w Home Assistancie można ufać, decydują kalibracja, przesunięcie temperatury i ciśnienie, więc to im poświęcam najwięcej miejsca.

SCD40, SCD41 czy SCD43

Wszystkie trzy czujniki mają tę samą obudowę, ten sam adres I²C (0x62) i tę samą platformę scd4x w ESPHome. Według noty katalogowej Sensiriona różnią się głównie dokładnością i zakresem, w którym ją gwarantuje producent:

  • SCD40: od 400 do 2000 ppm, dokładność ±(50 ppm + 5% odczytu).
  • SCD41: od 400 do 5000 ppm, ±(50 ppm + 2,5% odczytu) do 1000 ppm i ±(50 ppm + 3%) do 2000 ppm. Ma też tryb pojedynczego pomiaru.
  • SCD43: od 400 do 5000 ppm z dokładnością ±(30 ppm + 3% odczytu), również z trybem pojedynczego pomiaru.

Do miernika zasilanego z sieci, który mierzy bez przerwy, w większości pomieszczeń wystarczy SCD40. SCD41 ma sens, jeśli spodziewasz się wyników powyżej 2000 ppm, na przykład w małej sypialni z zamkniętym oknem, albo jeśli kiedyś zechcesz użyć trybu pojedynczego pomiaru. W przykładach używam SCD41, ale konfiguracja pozostałych dwóch wygląda tak samo.

Podłączenie i zasilanie

Czujnik komunikuje się przez I²C, więc potrzebuje czterech przewodów: VDD, GND, SDA i SCL. Nota katalogowa dopuszcza zasilanie od 2,4 do 5,5 V, ale stawia wysokie wymagania co do jego jakości. Tętnienia nie mogą przekraczać 30 mV, prąd szczytowy przy 3,3 V wynosi typowo 175 mA (maksymalnie 205 mA), a Sensirion zaleca osobny stabilizator LDO dla samego czujnika. Jeśli kupujesz gotowy moduł z czujnikiem, sprawdź na schemacie, czy ma własny stabilizator. Goły czujnik na tej samej linii 3,3 V co ESP32 z nadajnikiem Wi-Fi to dokładnie sytuacja, przed którą ostrzega nota.

Sensirion zaleca zewnętrzne rezystory podciągające na liniach SDA i SCL (w nocie jako przykład podano 10 kΩ). ESPHome domyślnie włącza wewnętrzne podciąganie w ESP32, ale dokumentacja i tak zaleca zewnętrzne rezystory przy dłuższych przewodach albo kilku urządzeniach na magistrali. Sprawdź, czy moduł nie ma ich już na płytce.

Jeszcze jedna zasada ze strony ESPHome: nie zdejmuj ani nie uszkadzaj białej membrany na czujniku.

Konfiguracja w ESPHome

i2c:
  sda: GPIO21
  scl: GPIO22
  scan: true

sensor:
  - platform: scd4x
    id: my_scd41
    measurement_mode: periodic
    update_interval: 60s
    temperature_offset: 4
    altitude_compensation: 220m
    co2:
      name: "CO2"
    temperature:
      name: "Temperatura"
    humidity:
      name: "Wilgotność"

GPIO21 i GPIO22 to typowe domyślne piny I²C w ESP32, ale wpisz te, których faktycznie używasz. Dzięki scan: true po uruchomieniu dziennik urządzenia pokazuje adresy znalezione na magistrali i czujnik powinien się pojawić pod 0x62. Jeśli go tam nie ma, najpierw sprawdź połączenia, a dopiero potem konfigurację.

W trybie periodic czujnik sam mierzy co 5 sekund, a ESPHome co update_interval (domyślnie co 60 sekund) pobiera ostatni wynik. W trybie low_power_periodic pomiar odbywa się co 30 sekund, więc update_interval nie może być krótszy niż 30 sekund. Tryby pojedynczego pomiaru są dostępne tylko w SCD41 i SCD43. Jeśli nie masz konkretnego powodu, zostań przy periodic albo low_power_periodic, bo opisany niżej algorytm kalibracji zakłada jeden z nich albo pojedyncze pomiary co 5 minut.

ESPHome nadaje encji CO2 klasę urządzenia carbon_dioxide, jednostkę ppm i klasę stanu measurement, więc Home Assistant bez dodatkowych ustawień zbiera dla niej statystyki długoterminowe.

Automatyczna samokalibracja i świeże powietrze raz w tygodniu

Automatyczna samokalibracja (ASC) jest domyślnie włączona zarówno w czujniku, jak i w ESPHome (automatic_self_calibration: true). Sensirion opisuje ją tak: algorytm zakłada, że w trakcie pomiarów czujnik przynajmniej raz w tygodniu przez co najmniej 3 minuty ma kontakt ze świeżym powietrzem z zewnątrz, w którym jest około 400 ppm CO2. Najniższą wartość z danego okresu uznaje za te 400 ppm i odpowiednio przesuwa wyniki. Domyślnie pierwsza korekta następuje po początkowym okresie 44 godzin pracy, a kolejne po każdym okresie standardowym, czyli co 156 godzin.

W salonie albo biurze, które co kilka dni się wietrzy, to działa. Problem pojawia się po cichu, gdy założenie jest fałszywe. Jeśli przez cały tydzień stężenie w pomieszczeniu ani razu nie spadnie do poziomu z zewnątrz, ASC i tak uznaje najniższą zmierzoną wartość za 400 ppm i zaniża wyniki. Czujnik pokazuje wtedy dobre powietrze w pokoju, w którym wcale takie nie jest. Sensirion ostrzega też, że przy włączonej ASC stężenia poniżej 400 ppm mogą pogorszyć dokładność.

W poradniku Sensiriona są jeszcze dwie rzeczy ważne przy domowym urządzeniu:

  • Stan ASC jest co jakiś czas zapisywany w pamięci nieulotnej, a odłączanie zasilania może opóźnić kolejne korekty. Czujnik podłączony do inteligentnego gniazdka, które co noc go wyłącza, to kiepski pomysł.
  • Według noty katalogowej podawana długoterminowa dokładność dotyczy pracy z ASC na domyślnych ustawieniach i cotygodniowego kontaktu z powietrzem o stężeniu 400 ppm. ASC można wyłączyć, ale wtedy Sensirion nie gwarantuje już dokładności.

Jeśli pomieszczenie jest regularnie wietrzone, zostaw ASC włączoną. Jeśli nie, wyłącz ją i kalibruj czujnik ręcznie.

Wymuszona kalibracja z poziomu Home Assistanta

Wymuszona kalibracja (FRC) to komunikat dla czujnika: „w powietrzu wokół ciebie jest teraz tyle CO2”. ESPHome ma do tego akcję scd4x.perform_forced_calibration, a najwygodniej wywołać ją z Home Assistanta przyciskiem szablonowym:

button:
  - platform: template
    name: "Kalibruj CO2 do 426 ppm"
    entity_category: config
    on_press:
      - scd4x.perform_forced_calibration:
          value: 426
          id: my_scd41

Wartość 426 pochodzi z dokumentacji ESPHome, która podaje ją jako średnie światowe stężenie CO2 w marcu 2025 roku według NOAA. Na zewnątrz w mieście albo przy ruchliwej ulicy może być więcej, więc jeśli masz zaufany miernik wzorcowy, wpisz jego odczyt.

Sensirion opisuje, jak poprawnie przeprowadzić FRC:

  1. Przez co najmniej 3 minuty czujnik musi pracować w swoim zwykłym trybie pomiaru w powietrzu o stałym i jednorodnym stężeniu CO2. W praktyce chodzi o pomiar na zewnątrz albo przy szeroko otwartym oknie, z dala od ludzi, bo nawet twój oddech podbija odczyt.
  2. Napięcie zasilania ma być takie samo jak podczas normalnej pracy, a kompensację wysokości albo ciśnienia trzeba ustawić przed kalibracją.
  3. Dopiero wtedy naciśnij przycisk. Akcja w ESPHome zatrzymuje pomiar, wysyła polecenie kalibracji i z powrotem uruchamia pomiary.

Sensirion podaje też dwa ograniczenia. Po przylutowaniu albo zamontowaniu czujnika odczekaj co najmniej 5 dni przed pierwszą FRC. Nie przeprowadzaj też FRC częściej niż raz na 4 godziny, bo każda kalibracja zapisuje dane w pamięci EEPROM czujnika i skraca jego żywotność. Pamiętaj o tym, zanim dodasz przycisk kalibracji do panelu, z którego korzysta cała rodzina.

Jeśli wyłączysz ASC, zaplanuj regularne kalibracje ręczne. Sensirion opisuje je jako zastępstwo ASC tam, gdzie świeże powietrze nigdy nie dociera, ale nie podaje konkretnego odstępu dla zastosowań domowych.

Przesunięcie temperatury, czyli skąd domyślne 4 °C

W SCD41 jest wbudowany czujnik temperatury i wilgotności, a sam czujnik w trakcie pomiaru się nagrzewa. Nota katalogowa ustawia domyślne przesunięcie temperatury na 4 °C i wyjaśnia, że właściwa wartość zależy od trybu pomiaru, nagrzewających się elementów w pobliżu, temperatury otoczenia i ruchu powietrza. ESP32 zamknięte w tej samej małej obudowie dokłada swoje ciepło.

Do ustalenia właściwej wartości potrzebujesz termometru wzorcowego i trochę cierpliwości. Zostaw gotowe urządzenie w obudowie, w docelowym trybie pomiaru, aż odczyty przestaną się zmieniać. Potem skorzystaj ze wzoru Sensiriona:

nowe przesunięcie = temperatura z SCD41 - temperatura wzorcowa + obecne przesunięcie

Jeśli na przykład SCD41 pokazuje 24,1 °C, termometr wzorcowy 22,3 °C, a obecne przesunięcie wynosi 4, nowe przesunięcie to 5,8. Zalecany zakres to od 0 do 20 °C. Przesunięcie nie wpływa na pomiar CO2, poprawia tylko temperaturę i wilgotność. Jeśli te dwie wartości cię nie interesują, możesz zostawić ustawienie domyślne.

Wysokość i ciśnienie

SCD41 kompensuje pomiar CO2 względem ciśnienia powietrza i domyślnie zakłada poziom morza (0 m). W ESPHome możesz to poprawić na trzy sposoby:

  • altitude_compensation: wysokość pomieszczenia nad poziomem morza w metrach. Ustawiasz ją raz w urządzeniu, które nie zmienia miejsca.
  • ambient_pressure_compensation: stałe ciśnienie w mbar. Gdy jest ustawione, wysokość jest pomijana.
  • ambient_pressure_compensation_source: identyfikator lokalnego czujnika ciśnienia, na przykład BME280 na tej samej magistrali I²C. Dokumentacja ESPHome zaznacza, że czujnik ciśnienia musi podawać wynik w hPa (liczbowo to samo co mbar). To najdokładniejszy sposób, bo ciśnienie zmienia się też razem z pogodą.

W przykładzie z BME280 dokumentacja ESPHome ustawia dla SCD4x temperature_offset: 0. Niezależnie od tego, jakie przesunięcie wybierzesz, wyznacz je opisaną wyżej metodą.

Od odczytu do automatyzacji w Home Assistancie

Przydatną skalę do oceny wyników podaje niemiecki Federalny Urząd Środowiska (Umweltbundesamt). Jego komisja do spraw powietrza w pomieszczeniach uznaje stężenie CO2 poniżej 1000 ppm za nieszkodliwe, od 1000 do 2000 ppm za podwyższone, przy którym trzeba częściej wietrzyć, a powyżej 2000 ppm za niedopuszczalne.

Automatyzacja oparta bezpośrednio na odczycie będzie się uruchamiać raz po raz, gdy stężenie krąży wokół 1000 ppm. Żeby tego uniknąć, użyj pomocnika progu. Utworzysz go w menu Ustawienia > Urządzenia oraz usługi > Pomocnicy > Utwórz pomocnika (w angielskim interfejsie pomocnik nazywa się „Threshold”). Jako wejście wybierz encję CO2, ustaw górny próg na 1000, a histerezę na 100. Powstały czujnik binarny włączy się powyżej 1100 ppm i wyłączy poniżej 900 ppm.

Ten czujnik binarny ustaw jako wyzwalacz automatyzacji i dodaj opóźnienie. Wtedy jedna osoba, która przez chwilę oddycha tuż przy czujniku, niczego nie uruchomi:

triggers:
  - trigger: state
    entity_id: binary_sensor.salon_co2_wysokie
    to: "on"
    for: "00:05:00"
actions:
  - action: notify.mobile_app_moj_telefon
    data:
      message: "Stężenie CO2 w salonie przekroczyło 1100 ppm. Czas otworzyć okno."

Podmień encję i akcję powiadomienia na własne. Ten sam wyzwalacz może zamiast wiadomości włączyć wentylator w łazience albo rekuperator.

Co sprawdzić, gdy wyniki wyglądają podejrzanie

  • Odczyty w rzadko wietrzonym pokoju przez kilka tygodni powoli spadają: ASC zakłada świeże powietrze, którego czujnik nigdy nie dostaje. Wyłącz ją i kalibruj ręcznie.
  • CO2 skacze, gdy stoisz obok: tak ma być. Przenieś czujnik dalej od miejsc, w których ludzie siedzą i oddychają.
  • Temperatura jest o kilka stopni za wysoka: ustaw przesunięcie temperatury. Na pomiar CO2 nie ma ono wpływu.
  • Po uruchomieniu na magistrali I²C nic nie ma: zanim zaczniesz szukać błędu w konfiguracji, sprawdź przewody SDA i SCL, rezystory podciągające i zasilanie.
  • Wyniki się zmieniły po przeprowadzce albo na wyższym piętrze: popraw altitude_compensation albo dodaj czujnik ciśnienia.