INA226 + STM32: pomiar prądu i napięcia przez I2C krok po kroku

INA226 + STM32: pomiar prądu i napięcia przez I2C krok po kroku
Twój projekt działa, ale nie wiesz, ile energii faktycznie pobiera, multimetr w szeregu przeszkadza, a oscyloskopu z sondą prądową nie masz. Pomiar prądu z INA226 na STM32 przez I2C rozwiązuje ten problem bez drogiego sprzętu: scalak sam mierzy natężenie, napięcie i moc, a Ty odbierasz gotowe liczby przez kilka linii kodu w C. Pokażę Ci krok po kroku, jak go podłączyć, skonfigurować rejestry, wyliczyć kalibrację i ustawić linię ALERT, żeby nie pollować magistrali bez potrzeby.

Czym jest układ INA226 i jakie ma kluczowe cechy
To dwukierunkowy scalak pomiarowy Texas Instruments, który potrafi jednocześnie mierzyć prąd elektryczny, napięcie elektryczne na szynie i obliczać moc wszystko przez magistralę I2C albo SMBus. Wewnątrz znajdziesz przetwornik ADC delta-sigma o rozdzielczości 16 bitów, co przekłada się na niską szumność i wysoką dokładność bez żadnej zewnętrznej kalibracji analogowej.
Scalak mierzy napięcie różnicowe na zewnętrznym boczniku i na tej podstawie wylicza natężenie. Egzemplarz wyposażony w rezystor 0,1 Ω ma zakres ±800 mA, a napięcie szyny możesz obserwować w przedziale 0–36 V.
Warto rozumieć, skąd bierze się ta precyzja. Offset wejściowy sięga maksymalnie 10 µV, dryft offsetu to typowo 0,02 µV na stopień, a błąd wzmocnienia przetwornika nie przekracza 0,1%. CMRR na poziomie 126 dB oznacza, że scalak dobrze radzi sobie z sytuacją, gdy sama szyna ma 24 V, a różnica na boczniku to ledwie kilkadziesiąt mikrowoltów.
Zanim przejdziemy dalej, zerknij na tabelę z najważniejszymi parametrami:
| Parametr | Wartość |
|---|---|
| Rezystor bocznikowy (na płytce) | 0,1 Ω |
| Zakres natężenia | ±800 mA |
| Zakres pomiaru napięcia szyny | 0–36 V |
| Zasilanie | 2,7–5,5 V |
| Interfejs | I²C / SMBus |
| Rozdzielczość ADC | 16 bitów |
| Częstotliwość próbkowania | domyślnie 900 Hz, maks. ok. 9 kHz |
| Błąd wzmocnienia ADC | 0,1% maks. |
| Offset wejściowy | 10 µV maks. |
| Liczba adresów (scalak) | 16 adresów |
| Liczba adresów (płytka) | 4 adresy |
| Wymiary PCB | 21 × 19 × 2 mm |
Czym różni się od prostego pomiaru przez ADC mikrokontrolera
Mógłbyś wzmocnić napięcie na boczniku wzmacniaczem operacyjnym i wpuścić je w przetwornik wbudowany w mikrokontroler. Tylko że wtedy sam odpowiadasz za offset wzmacniacza, jego dryft termiczny, napięcie referencyjne i szum zasilania. Tutaj cała ta analogowa robota jest już zrobiona w krzemie i skalibrowana fabrycznie.
Druga sprawa to tak zwany pomiar high-side. Wewnętrzny tor wejściowy znosi na swoich wejściach potencjał do 36 V niezależnie od tego, czym zasilasz logikę. Dzięki temu bocznik wstawiasz w gałąź dodatnią, a obciążenie zachowuje bezpośrednie połączenie z masą – co przy silnikach i przetwornicach oszczędza sporo kłopotów z pętlami masy.
Jakie są korzyści z używania tego czujnika do pomiaru prądu
Pierwsza korzyść jest oczywista: dostajesz gotową liczbę w miliamperach zamiast surowego kodu z przetwornika. Nie musisz pisać żadnego przeliczania napięcia różnicowego ani pilnować, żeby referencja ADC nie odpłynęła z temperaturą.
Druga to jednoczesny wgląd w moc. Rejestr mocy liczy iloczyn wewnętrznie, więc żeby dowiedzieć się, ile watów zjada Twoje urządzenie, nie mnożysz niczego w programie ani nie tracisz cykli na obliczenia zmiennoprzecinkowe w pętli głównej.
Trzecia to dwukierunkowość. Rejestry zwracają liczby ze znakiem, więc widzisz zarówno pobór, jak i zwrot energii to liczy się przy ładowaniu akumulatorów i przy hamowaniu odzyskowym silnika.
Czwarta to sprzętowy próg alarmowy. Zamiast odpytywać magistralę w pętli, ustawiasz limit raz i czekasz na przerwanie. Przy projektach bateryjnych, gdzie mikrokontroler większość czasu śpi, to różnica między kilkoma a kilkudziesięcioma mikroamperami średniego poboru całego systemu.

Dostępne moduły pomiarowe z interfejsem I2C
Na rynku spotkasz kilka wariantów z tej samej rodziny i łatwo je pomylić, bo wyglądają podobnie.
- INA219 – starszy, 12-bitowy przetwornik, zakres szyny do 26 V, prostszy i tańszy, ale wyraźnie mniej dokładny przy małych obciążeniach,
- INA226 – 16 bitów, szyna do 36 V, programowalne uśrednianie i czasy konwersji; to złoty środek i o nim jest ten tekst,
- INA228 – 20-bitowy, z licznikiem ładunku w kulombach, przydatny, gdy liczysz zużytą energię przez godziny,
- INA238 – 16 bitów z wbudowaną kompensacją temperatury bocznika, dobry wybór przy dużych mocach.
Alternatywą z zupełnie innej rodziny są scalaki halotronowe typu ACS712 i ACS758. Dają izolację galwaniczną i znoszą dziesiątki amperów, ale mają wyjście analogowe i znacznie gorszą rozdzielczość przy małych wartościach. Do monitorowania płytki z mikrokontrolerem, która pobiera kilkadziesiąt miliamperów, halotron jest po prostu ślepy.
Gdzie znaleźć płytkę z bocznikiem i który wariant wybrać
Do typowego projektu embedded, zasilanie 3,3 V lub 5 V, pobór od miliamperów do jednego ampera, bierz wersję 226 z boczniem 0,1 Ω. Jeśli szukasz gotowego PCB ze złączami goldpin w zestawie, sprawdź czujnik prądu i mocy INA226 dwukierunkowy w sklepie msalamon.pl. Płytka ma rezystancję 0,1 Ω już przylutowaną i obsługuje 4 adresy konfigurowalne zworką.
Na karcie tego produktu znajdziesz też gotowy przykład dla ESP32, kombinacja INA226+ESP32 uruchamia się dosłownie w kilka minut i dobrze nadaje się do sprawdzenia samej płytki, zanim wepniesz ją do docelowego projektu. Jeśli utkniesz, odpowiedzi na nietypowe przypadki najszybciej znajdziesz na forum dyskusyjnym o elektronice, wątków o tej rodzinie scalaków jest tam sporo.

Jak podłączyć moduł INA226 do STM32 – piny, przewód i masy
Podłączenie jest proste, ale kilka szczegółów wpływa na poprawność wyniku. Na złączu goldpin znajdziesz: VCC, GND, SDA, SCL, ALERT, A0, A1, VBS, IN+ oraz IN-.
- VCC / GND – zasilanie logiki 2,7–5,5 V,
- SDA / SCL – linie magistrali do mikrokontrolera,
- ALERT – wyjście przerwania, active-low, open-drain,
- A0 / A1 – wyprowadzenia adresowe; zworka decyduje o adresie,
- IN+ / IN- – końcówki bocznika,
- VBS – wejście pomiaru napięcia szyny VBUS; najczęściej mostkowane zwarciem z IN-.
Konkretne połączenia z płytką mikrokontrolera:
- VCC do 3,3 V,
- GND do wspólnej masy,
- SDA do linii danych wybranej magistrali (np. PB7 dla I2C1 na Nucleo),
- SCL do linii zegara (np. PB6),
- ALERT do dowolnego GPIO ze skonfigurowanym przerwaniem EXTI,
- IN+ do strony zasilania,
- IN- do strony obciążenia,
- VBS połączony zwarciem z IN-.
Na obu liniach magistrali potrzebujesz rezystorów pull-up typowo 4,7 kΩ do napięcia zasilania płytki. Egzemplarz ze sklepu msalamon.pl ma je już na laminacie, więc wpinasz go wprost bez dodatkowych elementów.
Jak prowadzić przewód i masy, żeby nie zafałszować wyniku
Każdy przewód ma własną rezystancję i przy setkach miliamperów potrafi dodać kilka miliwoltów spadku. Trzy zasady, które ratują dokładność:
- odcinek między bocznikiem a obciążeniem prowadź jak najkrócej i możliwie grubym drutem,
- masę płytki pomiarowej zepnij z masą mikrokontrolera w jednym punkcie, nie w dwóch różnych miejscach szyny,
- wejścia IN+ i IN- podłącz bezpośrednio do końcówek rezystancji, a nie do dalszych punktów obwodu – inaczej zmierzysz też spadek na okablowaniu.
Jeśli badasz szynę z przetwornicą impulsową, skręć ze sobą oba doprowadzenia idące do wejść różnicowych. Ograniczysz w ten sposób powierzchnię pętli, w którą wpina się zakłócenie z cewki.

Jak skonfigurować transmisję w STM32CubeMX
Otwórz STM32CubeMX, wybierz swój mikrokontroler i w zakładce Pinout and Configuration włącz wybraną magistralę (np. I2C1). Ustaw tryb na I2C. Częstotliwość 100 kHz w zupełności wystarczy – nie ma tu potrzeby pędzić na 400 kHz, bo rejestry są krótkie, a konwersja i tak trwa dłużej niż transmisja.
Dla linii ALERT wybierz GPIO Input z trybem EXTI na opadające zbocze, włącz przerwanie w NVIC i wygeneruj projekt. Jeśli planujesz wiele egzemplarzy na jednej szynie, od razu przewidź sobie w programie tablicę adresów zamiast jednej stałej.

Jak zaprogramować czujnik – rejestry, kalibracja i program w C
Konfigurację wykonujesz zapisem do kilku 16-bitowych rejestrów, a dane odczytujesz z kolejnych. Poniżej rozbijam to na etapy.
Zapis do rejestru – funkcja pomocnicza
Zacznij od funkcji wysyłającej liczbę do dowolnego rejestru przez HAL:

HAL_StatusTypeDef INA226_WriteReg(I2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t reg_addr, uint16_t value) { uint8_t buf[2]; buf[0] = (value >> 8) & 0xFF; buf[1] = value & 0xFF; return HAL_I2C_Mem_Write(hi2c, dev_addr, reg_addr, I2C_MEMADD_SIZE_8BIT, buf, 2, 100); }
Zwróć uwagę na kolejność bajtów. Scalak oczekuje big-endian, a STM32 pracuje w little-endian, więc starszy bajt musisz wysłać jako pierwszy. To najczęstsza przyczyna sytuacji, w której zapis niby przechodzi, a scalak zachowuje się losowo.
Configuration Register
Configuration Register pod adresem 0x00 steruje trybem pracy, czasem konwersji i liczbą uśrednień. Zawiera pola bitowe dla uśredniania (AVG), czasu konwersji napięcia szyny (VBUSCT), czasu konwersji na boczniku (VSHCT) oraz trybu pracy (Mode): ciągły, na żądanie albo power-down.
Uśrednianie to najprostsze narzędzie do walki z szumem. Przy AVG równym 16 pojedynczy wynik jest wyraźnie stabilniejszy, kosztem szesnastokrotnie dłuższego czasu odświeżania. Do monitorowania poboru w systemie bateryjnym śmiało ustaw 64 albo 128 – i tak nie interesują Cię pojedyncze mikrosekundy. Do obserwacji szybkich skoków obciążenia zostaw 1 i skróć czas konwersji.
Tryb power-down przydaje się, gdy Twoje urządzenie usypia. Scalak w tym stanie pobiera pojedyncze mikroampery, a po wybudzeniu wystarczy jeden zapis, żeby wrócić do pracy ciągłej.
Kalibracja rezystora bocznikowego i przeliczanie wartości
Scalak nie zna rezystancji Twojego bocznika – musisz mu ją przekazać przez Calibration Register pod adresem 0x05. Obliczenia wyglądają następująco:
- Ustal maksymalne spodziewane natężenie (np. 0,8 A dla egzemplarza z 0,1 Ω).
- Oblicz Current_LSB – maksimum podzielone przez 2 do potęgi 15.
- Oblicz zawartość rejestru kalibracji – CAL = 0,00512 podzielone przez (Current_LSB razy R_shunt).
#define R_SHUNT_OHM 0.1f
#define MAX_CURRENT_A 0.8f
#define CAL_CONST 0.00512f
float current_lsb = MAX_CURRENT_A / 32768.0f;
uint16_t cal_value = (uint16_t)(CAL_CONST / (current_lsb * R_SHUNT_OHM));
INA226_WriteReg(&hi2c1, INA226_ADDR, 0x05, cal_value);
W praktyce: jeśli chcesz monitorować do 2A albo 1A, po prostu zmieniasz MAX_CURRENT_A i przeliczasz – reszta programu zostaje bez zmian. Dokładnie to samo zrobisz, gdy wymienisz rezystancję bocznikową na inną i zechcesz zmierzyć szerszy zakres.
Dobra praktyka: po zapisie odczytaj rejestr kalibracji z powrotem i porównaj z tym, co wysłałeś. Jedno sprawdzenie na starcie wyłapuje zarówno literówkę w adresie, jak i brak pull-upów na magistrali.
Odczyt prądu, pomiaru napięcia i mocy
Po konfiguracji i kalibracji możesz sięgać po rejestry wynikowe. Oto co każdy z nich daje:
- Shunt Voltage Register (0x01) – napięcie na boczniku, LSB = 2,5 µV, liczba ze znakiem,
- Bus Voltage Register (0x02) – potencjał szyny, LSB = 1,25 mV,
- Power Register (0x03) – moc, LSB = 25 razy Current_LSB,
- Current Register (0x04) – natężenie, LSB = Current_LSB z kalkulacji, liczba ze znakiem.
typedef struct { float current_mA; float voltage_mV; float power_mW; } INA226_Data_t;
HAL_StatusTypeDef INA226_ReadAll(I2C_HandleTypeDef *hi2c, uint8_t dev_addr, float current_lsb, INA226_Data_t *out) {
uint8_t buf[2]; int16_t raw;
HAL_I2C_Mem_Read(hi2c, dev_addr, 0x02, I2C_MEMADD_SIZE_8BIT, buf, 2, 100);
out->voltage_mV = ((int16_t)((buf[0] << 8) | buf[1])) * 1.25f;
HAL_I2C_Mem_Read(hi2c, dev_addr, 0x04, I2C_MEMADD_SIZE_8BIT, buf, 2, 100);
raw = (int16_t)((buf[0] << 8) | buf[1]);
out->current_mA = raw * current_lsb * 1000.0f;
HAL_I2C_Mem_Read(hi2c, dev_addr, 0x03, I2C_MEMADD_SIZE_8BIT, buf, 2, 100);
raw = (int16_t)((buf[0] << 8) | buf[1]);
out->power_mW = raw * 25.0f * current_lsb * 1000.0f;
return HAL_OK;
}
Wyniki możesz od razu wyświetlać przez UART na terminalu albo logować do bufora kołowego. Scalak co chwilę odświeża swoje rejestry, więc zawsze masz świeże dane pod ręką. Jeśli w projekcie masz wyświetlacz OLED, ta sama struktura nadaje się wprost do sformatowania trzech linii tekstu.
Kilka egzemplarzy na jednej magistrali
Zworki A0 i A1 dają cztery kombinacje, więc na jednej szynie zmieścisz cztery punkty kontrolne. To wygodne, gdy chcesz rozdzielić pobór na sekcje: osobno logika, osobno radio, osobno silnik.
W programie trzymaj wtedy tablicę struktur z adresem i własnym Current_LSB dla każdego egzemplarza, bo bocznik w każdym punkcie może mieć inną rezystancję, dobraną do spodziewanego obciążenia.
Jak używać linii ALERT bez ciągłego pollingu
Wejście przerwania pozwala odwrócić logikę odpytywania: ustalasz próg, a urządzenie samo Cię powiadomi, gdy go przekroczy. Konfigurację przeprowadzasz przez Mask/Enable Register (0x06) i Alert Limit Register (0x07). Poniżej przykład ustawienia progu na 700 mA:

float alert_lsb = 0.7f / current_lsb;
uint16_t alert_val = (uint16_t)alert_lsb;
INA226_WriteReg(&hi2c1, INA226_ADDR, 0x07, alert_val);
INA226_WriteReg(&hi2c1, INA226_ADDR, 0x06, 0x8000);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == ALERT_Pin) {
INA226_ReadAll(&hi2c1, INA226_ADDR, current_lsb, &ina_data);
}
}
Wyjście jest open-drain i wymaga podciągnięcia do VCC. Po odczytaniu danych w przerwaniu skasuj flagę przez odczyt Mask/Enable Register – bez tego kolejne zgłoszenie nie przyjdzie.
Mask/Enable obsługuje kilka źródeł alarmu: przekroczenie napięcia różnicowego w górę i w dół, przekroczenie potencjału szyny w obie strony, przekroczenie mocy oraz zwykłą flagę Conversion Ready. Ustawiasz tylko jedno z nich naraz, więc zdecyduj, co w Twoim projekcie jest ważniejsze – limit mocy czy limit natężenia.
W obsłudze przerwania nie rób nic poza ustawieniem flagi i ewentualnym pojedynczym odczytem. Dłuższe transmisje po magistrali wewnątrz callbacku to prosta droga do zakleszczenia, zwłaszcza przy FreeRTOS.
Typowe błędy przy pomiarze prądu na STM32
Przy pierwszym uruchomieniu połowa problemów wynika z jednej z poniższych przyczyn. Sprawdź po kolei:
- Zły adres – napisz skaner magistrali przechodzący przez zakres 0x00–0x7F funkcją HAL_I2C_IsDeviceReady,
- brak podciągnięcia na liniach danych i zegara – typowo 4,7 kΩ do VCC rozwiązuje sprawę; na płytce ze sklepu msalamon.pl te elementy są już na laminacie,
- nieprawidłowa kalibracja – zmierz napięcie miernikiem bezpośrednio na końcówkach bocznika, podziel przez rezystancję i porównaj z Shunt Voltage Register,
- odwrócone wejścia różnicowe – nic się nie uszkodzi, ale wynik będzie ujemny zamiast dodatniego,
- odczyt przed końcem konwersji w trybie triggered – dodaj opóźnienie albo czekaj na flagę Conversion Ready,
- przepięcie na wejściach – potencjał na IN+, IN- i VBS nie może przekroczyć 36 V,
- zbyt duże uśrednianie przy szybkich zmianach – przy AVG 128 przegapisz krótki impuls rozruchowy silnika,
- zimny lut na złączu goldpin – przy rezystancji rzędu ułamka oma nawet kilkadziesiąt miliomów w połączeniu psuje wynik.
Scalak działa też z ESP32 i Arduino – logika rejestrów jest identyczna, zmienia się tylko biblioteka. Doprowadzenie łączące bocznik z obciążeniem trzymaj jak najkrótsze, żeby spadek na nim nie zaburzał wyniku. Przy projektach związanych z optymalizacją zużycia energii precyzyjny odczyt potencjału szyny i natężenia to podstawa.
Jak sprawdzić poprawność miernikiem
Najszybsza weryfikacja: wepnij w szereg z obciążeniem zwykły multimetr w trybie amperomierza i porównaj wskazania. Przy stabilnym obciążeniu rezystancyjnym różnica powinna mieścić się w pojedynczych procentach.
Jeśli rozjazd jest duży i stały, wina leży po stronie stałej kalibracyjnej. Jeśli rozjazd rośnie razem z obciążeniem, winne jest okablowanie albo faktyczna tolerancja rezystancji bocznikowej – te elementy bywają na 1%, ale bywają i gorsze. Możesz wtedy zmierzyć rzeczywistą rezystancję metodą czteropunktową i podstawić ją do wzoru zamiast nominału.

Podsumowanie
Masz już wszystko, żeby podłączyć płytkę do mikrokontrolera przez magistralę i mierzyć prąd elektryczny, napięcie elektryczne oraz moc w kodzie C z HAL. Skonfigurowałeś rejestry, wyliczyłeś stałą kalibracyjną i ustawiłeś linię ALERT tak, żeby nie pollować szyny bez potrzeby.
Jeśli Twój projekt wymaga wyższych zakresów – powiedzmy 2A albo więcej – wystarczy wymienić bocznik i przeliczyć Calibration Register. Reszta programu zostaje bez zmian. To jedna z tych rzeczy, które w tym scalaku po prostu działają elegancko.
Sprawdzi się wszędzie tam, gdzie chcesz monitorować pobór w czasie rzeczywistym: od prostych czujników bateryjnych po systemy zarządzania energią w bardziej złożonych projektach embedded. A gdy wyniki trafią przez UART na monitor komputera, od razu zobaczysz, która część układu zjada najwięcej.
FAQ – najczęstsze pytania
1. Jaki jest domyślny adres modułu? Zależy od ustawienia wyprowadzeń A0 i A1 – zworka decyduje o wartości. Sam scalak obsługuje 16 kombinacji, ale płytka ze sklepu msalamon.pl udostępnia 4 do wyboru. Jeśli nie pamiętasz, co ustawiłeś, uruchom skaner magistrali przez HAL_I2C_IsDeviceReady i sprawdź po kolei.
2. Czy czujnik działa z 5V? Zasilanie logiki mieści się w przedziale 2,7–5,5 V, więc podanie 5V jest bezpieczne. Linie danych i zegara powinny jednak pracować na poziomach logicznych zgodnych z Twoim mikrokontrolerem – przy STM32 zasilonym z 3,3 V podciągaj je do 3,3 V.
3. Co zrobić, gdy wynik natężenia jest zawsze zerowy? Najpierw sprawdź, czy Calibration Register (0x05) ma wpisaną liczbę różną od zera – bez tego Current Register zawsze zwróci zero. Potem zmierz napięcie bezpośrednio na końcówkach bocznika, żeby upewnić się, że w ogóle coś przez niego płynie.
4. Czy mogę użyć tego czujnika z Arduino lub ESP32? Tak, logika rejestrów jest identyczna niezależnie od platformy. Z Arduino i ESP32 korzystasz z bibliotek dostępnych dla tych platform zamiast HAL – sam program konfiguracji rejestrów wygląda tak samo. Gotowy przykład dla ESP32 znajdziesz na karcie produktu.
5. Jak zmienić zakres powyżej 800 mA? Wymień bocznik na mniejszy (np. 0,05 Ω dla zakresu do 1A lub 2A, 0,01 Ω dla 8A) i przelicz zawartość Calibration Register według wzoru z artykułu. Reszta programu nie wymaga żadnej zmiany.
6. Jak często mogę odczytywać dane? Domyślnie nowy wynik pojawia się około 900 razy na sekundę, a przy skróconych czasach konwersji nawet około 9 tysięcy razy. Odpytywanie szybsze niż konwersja nie ma sensu – dostaniesz tę samą liczbę kilka razy pod rząd.
7. Czy potrzebuję złącza śrubowego? Przy obciążeniach do jednego ampera spokojnie wystarczy goldpin z zestawu. Powyżej tej granicy przejdź na złącze śrubowe albo wlutuj doprowadzenia bezpośrednio w otwory – styk listwy zaczyna wtedy wnosić własną rezystancję i grzać się.
8. Czy mogę mierzyć po stronie masy zamiast po stronie plusa? Możesz, tor wejściowy przyjmuje też potencjał bliski zeru. Pomiar high-side jest jednak wygodniejszy, bo obciążenie zostaje bezpośrednio przy masie i nie tworzysz przesunięcia potencjału odniesienia dla reszty elektroniki.

Prezentowaną w artykule elektronikę – w tym moduł czujnika prądu i mocy INA226 – znajdziesz w naszym sklepie sklep.msalamon.pl. Zapraszamy również na nasze social media, gdzie pokazujemy nowości i projekty.


