Większość małych czujników w domowych projektach komunikuje się przez I²C: czujniki temperatury i wilgotności, ciśnienia, CO₂ i natężenia światła, a także małe wyświetlacze OLED i ekspandery wyprowadzeń. Do połączenia ich wszystkich z ESP32 wystarczą dwa przewody. Gdy wszystko działa, jest prosto. Gdy nie działa, przyczyną jest zwykle brakujący lub źle dobrany rezystor podciągający, dwa urządzenia o tym samym adresie, zbyt długie przewody albo niewłaściwe piny.
Poniżej zebrano to, co trzeba wiedzieć, aby uruchomić magistralę i utrzymać ją w dobrej kondycji. Teoria pochodzi ze specyfikacji magistrali I²C firmy NXP (UM10204, wydanie 7.0 z października 2021 roku), a część praktyczna z dokumentacji ESPHome i MicroPythona.
Zrozum działanie magistrali
Magistrala I²C ma dwie linie: SDA (dane) i SCL (zegar). Obie są połączone z dodatnim napięciem zasilania przez rezystor podciągający (albo źródło prądowe). Gdy magistrala jest bezczynna, na obu liniach panuje stan wysoki.
Urządzenia nigdy nie wymuszają na linii stanu wysokiego. Mają wyjścia typu otwarty dren (lub otwarty kolektor), więc mogą tylko ściągnąć linię do stanu niskiego albo ją zwolnić. Z powrotem do stanu wysokiego linię podciąga rezystor. Dlatego bez rezystorów podciągających magistrala w ogóle nie działa. W dokumentacji MicroPythona zachowanie w takiej sytuacji opisano jako nieokreślone: od zawieszenia, przez restart wywołany przez układ nadzorujący, aż po błędne odczyty.
Każdą transmisję rozpoczyna kontroler (tu ESP32), który wskazuje adres jednego urządzenia docelowego. W specyfikacji określono takie prędkości:
- Standard-mode: do 100 kbit/s,
- Fast-mode: do 400 kbit/s,
- Fast-mode Plus: do 1 Mbit/s,
- High-speed mode: do 3,4 Mbit/s.
Czujniki domowe pracują niemal zawsze w trybie Standard-mode lub Fast-mode.
Niektóre urządzenia przytrzymują linię SCL w stanie niskim, aby wstrzymać transmisję na czas przygotowania danych. To tak zwane rozciąganie zegara (clock stretching), w specyfikacji oznaczone jako funkcja opcjonalna.
Sprawdź adresy, czyli dlaczego skanowanie obejmuje zakres 0x08-0x77
Większość urządzeń ma 7-bitowy adres zapisywany szesnastkowo, na przykład 0x44 lub 0x76. W specyfikacji zarezerwowano dwie grupy po osiem adresów, 0000XXX i 1111XXX, do celów specjalnych, takich jak adres wywołania ogólnego i adresowanie 10-bitowe. Zwykłym urządzeniom przypada zakres 0x08-0x77 i właśnie ten zakres jest sprawdzany przez metodę scan() w MicroPythonie.
Każde urządzenie na magistrali musi mieć unikalny adres. Kilka adresów domyślnych z dokumentacji ESPHome:
- BME280 (temperatura, wilgotność, ciśnienie): domyślnie 0x77, alternatywnie 0x76,
- SHT4x (temperatura, wilgotność): 0x44,
- multiplekser TCA9548A: 0x70.
Typowy problem to dwa identyczne czujniki na jednej magistrali. Są trzy rozwiązania:
- Alternatywny adres. Niektóre układy mają pin adresowy lub zworkę lutowaną. BME280 może używać adresu 0x76 lub 0x77, więc dwa takie czujniki zmieszczą się na jednej magistrali.
- Druga magistrala. ESP32 ma dwa sprzętowe kontrolery I²C (0 i 1, według skróconej dokumentacji MicroPythona), a w ESPHome można zdefiniować kilka magistrali o różnych identyfikatorach
id. - Multiplekser. TCA9548A ma 8 kanałów. W ESPHome każdy kanał jest traktowany jak osobna wirtualna magistrala, więc ten sam adres może wystąpić raz na każdym kanale.
Dobierz rezystory podciągające
Wartość rezystora podciągającego jest kompromisem.
- Przy zbyt dużej wartości linia narasta zbyt wolno. Z każdym przewodem, złączem i pinem rośnie pojemność magistrali, a od tej pojemności i wartości rezystora zależy czas narastania sygnału.
- Przy zbyt małej wartości urządzenie nie zdoła ściągnąć linii wystarczająco nisko. Według specyfikacji urządzenia w trybach Standard-mode i Fast-mode muszą przyjąć prąd co najmniej 3 mA przy napięciu stanu niskiego nie większym niż 0,4 V (przy zasilaniu powyżej 2 V).
W specyfikacji podano wzór dla każdej z granic.
Wartość maksymalna: Rp(max) = tr / (0,8473 × Cb)
- tr to maksymalny czas narastania: 1000 ns w trybie Standard-mode i 300 ns w trybie Fast-mode.
- Cb to pojemność magistrali. W obu trybach limit wynosi 400 pF.
Wartość minimalna: Rp(min) = (VDD - VOL(max)) / IOL
Przykład dla magistrali 3,3 V o szacowanej pojemności 100 pF:
- Rp(min) = (3,3 - 0,4) / 0,003 ≈ 0,97 kΩ
- Rp(max) w trybie Standard-mode = 1000 ns / (0,8473 × 100 pF) ≈ 11,8 kΩ
- Rp(max) w trybie Fast-mode = 300 ns / (0,8473 × 100 pF) ≈ 3,5 kΩ
Sprawdzi się każda wartość między minimum a maksimum. Przy pojemności 200 pF maksimum dla trybu Fast-mode spada do około 1,8 kΩ. W dokumentacji MicroPythona jako typowy zakres podano 1-10 kΩ.
Rzeczywistej pojemności zwykle nie da się poznać, więc te liczby służą raczej do sprawdzenia, czy dobór ma sens. Jeśli długa lub mocno obciążona magistrala działa niestabilnie, zmniejsz prędkość albo wartość rezystora, nie przekraczając podanych granic.
Uwzględnij rezystory, które już są na płytkach
Według dokumentacji MicroPythona rezystory podciągające często są już wbudowane w płytkę z mikrokontrolerem albo w moduł z czujnikiem, ale nie ma na to reguły. Sprawdź schematy swoich modułów. Jeśli kilka modułów ma własne rezystory, są one połączone równolegle, a wypadkowa rezystancja jest mniejsza od każdej z nich. Przy wielu modułach może spaść poniżej wartości minimalnej. Na niektórych płytkach rezystory można odłączyć zworką lutowaną.
Wbudowane rezystory opisano w dokumentacji ESPHome:
- W ESP32 wewnętrzne rezystory podciągające na liniach SDA i SCL są domyślnie włączone. Wyłącza się je opcjami
sda_pullup_enabled: falseiscl_pullup_enabled: false. - W ESP8266 wewnętrzne rezystory 10 kΩ są zawsze włączone.
- Przy dłuższych przewodach lub wielu urządzeniach i tak zalecane są rezystory zewnętrzne.
Uważaj na różne napięcia
Rezystor podciągający jest połączony z napięciem zasilania modułu, na którym się znajduje. Jeśli w module rezystory są podłączone do 5 V, na liniach SDA i SCL pojawi się 5 V, czyli takie napięcie trafi do pinów ESP32. Przed podłączeniem takiego modułu sprawdź jego schemat oraz maksymalne napięcie na pinach w nocie katalogowej mikrokontrolera. Najprościej zasilać moduły I²C napięciem 3,3 V, jeśli są do tego przystosowane.
Prowadź magistralę krótko i spokojnie
Od pojemności magistrali zależy, ile urządzeń i jak długie przewody można do niej podłączyć. W specyfikacji limit dla trybów Standard-mode i Fast-mode wynosi 400 pF na linię, wliczając przewody, złącza i piny. Przy większych potrzebach w specyfikacji opisano dwa podejścia:
- mniejsze rezystory (w granicach Rp(min)), a więc szybsze zbocza,
- bufor (na przykład PCA9515) dzielący magistralę na odcinki, przy czym każdy odcinek może mieć do 400 pF.
W praktyce przy długiej lub niestabilnej magistrali najpierw warto obniżyć częstotliwość zegara. Domyślna wartość w ESPHome to i tak ostrożne 50 kHz.
Skonfiguruj magistralę w ESPHome
Poniższa konfiguracja dla klasycznego ESP32 korzysta z typowych pinów domyślnych (GPIO21 dla SDA, GPIO22 dla SCL), skanuje magistralę przy starcie i odczytuje czujnik BME280:
i2c:
sda: GPIO21
scl: GPIO22
scan: true
frequency: 100kHz
id: bus_a
sensor:
- platform: bme280_i2c
i2c_id: bus_a
address: 0x76
temperature:
name: "BME280 Temperatura"
pressure:
name: "BME280 Ciśnienie"
humidity:
name: "BME280 Wilgotność"
Uwagi ze stron ESPHome o magistrali I²C i czujniku BME280:
- Opcja
scanma domyślnie wartośćtrue. Wyniki skanowania przy starcie trafiają do dziennika urządzenia, więc gdy czujnik nie jest wykrywany, tam trzeba zajrzeć najpierw. - Domyślna wartość
frequencyto 50 kHz. Dopuszczalne wartości mieszczą się w zakresie od 10 kHz do 800 kHz. 100 kHz odpowiada trybowi Standard-mode. - Domyślny
timeoutwynosi 100 µs w ESP32 (maksymalnie 13 ms) i 1 s w ESP8266. - Jeśli czujnik ma domyślny adres 0x77, opcję
addressmożna pominąć. - W przypadku BME280 w trybie I²C w dokumentacji ESPHome zaleca się podłączenie pinu CSB do 3 V, aby uniknąć błędu „Communication with BME280 failed!”.
Przeskanuj magistralę w MicroPythonie
Na płytce z MicroPythonem skanowanie zajmuje trzy wiersze:
from machine import Pin, I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)
print([hex(a) for a in i2c.scan()])
Według dokumentacji MicroPythona:
- Metodą
scan()sprawdzane są adresy od 0x08 do 0x77, a w wyniku zwracana jest lista tych, które odpowiedziały. - Urządzenie uznaje się za odpowiadające, gdy po wysłaniu jego adresu ściągnie linię SDA do stanu niskiego.
- Sprzętowy kontroler 0 w ESP32 domyślnie korzysta z SCL na pinie 18 i SDA na pinie 19, ale można użyć dowolnych pinów wyjściowych.
machine.SoftI2Cto implementacja programowa, działająca na dowolnym pinie wyjściowym.- Rzeczywista częstotliwość zegara sprzętowego może być niższa od żądanej. Faktyczna konfiguracja jest widoczna po wypisaniu obiektu
i2cpoleceniemprint.
Pusta lista oznacza, że żadne urządzenie nie potwierdziło swojego adresu. Sprawdź zasilanie, masę, kolejność linii SDA i SCL oraz rezystory podciągające.
Rozwiąż typowe problemy
- Skanowanie nic nie znajduje. Sprawdź, czy czujnik ma zasilanie i wspólną masę z ESP32, czy linie SDA i SCL nie są zamienione i czy na magistrali są gdziekolwiek rezystory podciągające.
- Urządzenie ma inny adres niż oczekiwany. Użyj adresu ze skanowania. Wiele modułów ma fabrycznie ustawiony adres alternatywny.
- Dwa urządzenia, jeden adres. Użyj adresu alternatywnego, drugiej magistrali albo multipleksera TCA9548A.
- Na biurku działa, po montażu nie. Dłuższy przewód to większa pojemność. Obniż częstotliwość, skróć przewody albo zmień rezystory w podanych granicach.
- Sporadyczne przekroczenia czasu przy niektórych czujnikach. Niektóre urządzenia rozciągają zegar. W ESPHome opcja
timeoutustala limit czasu magistrali. W MicroPythonie parametrtimeoutogranicza czas trwania transmisji, a w przypadkuSoftI2Cw dokumentacji opisano go jako czas oczekiwania na koniec rozciągania zegara.