Dwukierunkowy cyfrowy czujnik prądu/mocy INA226
INA226 jest kolejnym, miniaturowym, dwukierunkowym czujnikiem prądu i mocy, współpracujący z zewnętrznym rezystorem bocznikującym. Można go znaleźć w systemach komputerowych, zasilaczach oraz ładowarkach. Jego działanie polega na pomiarze spadku napięcia na rezystorze bocznikującym, napięcia zasilającego bocznik oraz napięcia zasilania szyny. Na podstawie tych trzech wartości wyznaczana jest wartość prądu oraz mocy pobieranej przez obciążenie. Jest to pierwsza różnica w metodzie pomiaru pomiędzy INA226 a poprzednio opisywanym INA219.
Układ w odróżnieniu od INA219 charakteryzuje się zwiększoną dokładnością ±0.1% oraz 16-bitową rozdzielczością wewnętrznego przetwornika A/C. Parametry te pozwalają na uzyskanie znacznie większej dokładności pomiaru bardzo małych spadków napięcia na rezystorze bocznikującym. Zwiększone jest również dopuszczalne napięcie szyny, które może mieścić się w zakresie od 0V ÷ 36V. Podobnie jak w INA219, rejestry pozwalają na odczyt natężenia prądu i mocy bezpośrednio w amperach i watach. Napięcie zasilania może mieścić się w zakresie 3V ÷ 5V.
INA226 posiada również dodatkowe specjalne rejestry, za pomocą których możemy sterować pinem ALERT do sygnalizacji przekroczenia (lub niedobori) ustawionych wartości granicznych takich jak: pobierana moc, napięcie na rezystorze bocznikującym oraz napięcie szyny.
W przypadku pracy w otoczeniu o sporych zakłóceniach elektromagnetycznych możliwe jest uśrednianie aż 1024 próbek pomiarowych. Konfiguracja parametrów oraz odczyt wyników odbywa się za pośrednictwem szyny I2C mogącej pracować z zegarem do 3,4 MHz.
Zasadniczą różnicą pomiędzy INA219 a INA226 jest sposób wykonywania pomiarów. Jak pamiętamy, INA219 pozwalał na wybór rozdzielczości pomiaru napięcia szyny oraz ilości próbek napięcia na rezystorze bocznikującym. INA226 natomiast pozwala na określenie indywidualnych czasów trwania pomiarów tych wartości w przedziale 140μS ÷ 8.244mS, które wykonuje w żądanej ilości próbek pomiarowych.
INA226 dostępna jest jedynie w obudowie MSOP-10.
Dokumentacja techniczna: https://www.jarzebski.pl/datasheets/INA226.pdf
Dla ułatwienia testowania możemy przylutować układ do przejściówki MSOP-10 na DIP10. Ponieważ INA226 dopuszcza maksymalne napięcie na boczniku do 81.92mV, więc do pomiaru większych wartości prądu musimy skorzystać z nieco mniejszej jego rezystancji. Ja użyłem rezystora bocznikującego o wartości 0.01Ω, tolerancji 1% oraz mocy 3W. W takiej konfiguracji jest możliwy pomiar natężenia prądu do 8A (przy zastosowaniu bocznika 0.1Ω, będzie to 800mA).
Schemat połączeń
Układ zasilamy napięciem 5V z kondensatorem filtrującym 0.1μF. Linie sterujące SCL oraz SDA podłączamy do Arduino, podciągając rezystorami 10kΩ do zasilania. Piny A0 i A1 podłączamy do masy, dzięki czemu INA226 będzie posiadała adres 0x40 na szynie I2C. W odróżnieniu od INA219, dodatkowy pin VBUS mostkujemy z VIN-. Opcjonalnie, możemy wykorzystać wyjście ALERT o którym nieco później.
Oczywiście do VIN+ oraz VIN- podłączamy rezystor bocznikujący i przepuszczamy przez niego obciążenie (maksymalnie 36V / 8A dla rezystora bocznikującego 0.01Ω).
Program
Do obsługi modułów z układami INA226 przygotowałem bibliotekę dla Arduino, którą można pobrać z repozytorium Git: https://github.com/jarzebski/Arduino-INA226
- #include <Wire.h>
- #include <INA226.h>
- INA226 ina;
- void checkConfig()
- {
- Serial.print("Mode: ");
- switch (ina.getMode())
- {
- case INA226_MODE_POWER_DOWN: Serial.println("Power-Down"); break;
- case INA226_MODE_SHUNT_TRIG: Serial.println("Shunt Voltage, Triggered"); break;
- case INA226_MODE_BUS_TRIG: Serial.println("Bus Voltage, Triggered"); break;
- case INA226_MODE_SHUNT_BUS_TRIG: Serial.println("Shunt and Bus, Triggered"); break;
- case INA226_MODE_ADC_OFF: Serial.println("ADC Off"); break;
- case INA226_MODE_SHUNT_CONT: Serial.println("Shunt Voltage, Continuous"); break;
- case INA226_MODE_BUS_CONT: Serial.println("Bus Voltage, Continuous"); break;
- case INA226_MODE_SHUNT_BUS_CONT: Serial.println("Shunt and Bus, Continuous"); break;
- default: Serial.println("unknown");
- }
- Serial.print("Samples average: ");
- switch (ina.getAverages())
- {
- case INA226_AVERAGES_1: Serial.println("1 sample"); break;
- case INA226_AVERAGES_4: Serial.println("4 samples"); break;
- case INA226_AVERAGES_16: Serial.println("16 samples"); break;
- case INA226_AVERAGES_64: Serial.println("64 samples"); break;
- case INA226_AVERAGES_128: Serial.println("128 samples"); break;
- case INA226_AVERAGES_256: Serial.println("256 samples"); break;
- case INA226_AVERAGES_512: Serial.println("512 samples"); break;
- case INA226_AVERAGES_1024: Serial.println("1024 samples"); break;
- default: Serial.println("unknown");
- }
- Serial.print("Bus conversion time: ");
- switch (ina.getBusConversionTime())
- {
- case INA226_BUS_CONV_TIME_140US: Serial.println("140uS"); break;
- case INA226_BUS_CONV_TIME_204US: Serial.println("204uS"); break;
- case INA226_BUS_CONV_TIME_332US: Serial.println("332uS"); break;
- case INA226_BUS_CONV_TIME_588US: Serial.println("558uS"); break;
- case INA226_BUS_CONV_TIME_1100US: Serial.println("1.100ms"); break;
- case INA226_BUS_CONV_TIME_2116US: Serial.println("2.116ms"); break;
- case INA226_BUS_CONV_TIME_4156US: Serial.println("4.156ms"); break;
- case INA226_BUS_CONV_TIME_8244US: Serial.println("8.244ms"); break;
- default: Serial.println("unknown");
- }
- Serial.print("Shunt conversion time: ");
- switch (ina.getShuntConversionTime())
- {
- case INA226_SHUNT_CONV_TIME_140US: Serial.println("140uS"); break;
- case INA226_SHUNT_CONV_TIME_204US: Serial.println("204uS"); break;
- case INA226_SHUNT_CONV_TIME_332US: Serial.println("332uS"); break;
- case INA226_SHUNT_CONV_TIME_588US: Serial.println("558uS"); break;
- case INA226_SHUNT_CONV_TIME_1100US: Serial.println("1.100ms"); break;
- case INA226_SHUNT_CONV_TIME_2116US: Serial.println("2.116ms"); break;
- case INA226_SHUNT_CONV_TIME_4156US: Serial.println("4.156ms"); break;
- case INA226_SHUNT_CONV_TIME_8244US: Serial.println("8.244ms"); break;
- default: Serial.println("unknown");
- }
- Serial.print("Max possible current: ");
- Serial.print(ina.getMaxPossibleCurrent());
- Serial.println(" A");
- Serial.print("Max current: ");
- Serial.print(ina.getMaxCurrent());
- Serial.println(" A");
- Serial.print("Max shunt voltage: ");
- Serial.print(ina.getMaxShuntVoltage());
- Serial.println(" V");
- Serial.print("Max power: ");
- Serial.print(ina.getMaxPower());
- Serial.println(" W");
- }
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Initialize INA226");
- Serial.println("-----------------------------------------------");
- // Default INA226 address is 0x40
- ina.begin();
- // Configure INA226
- ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
- // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
- ina.calibrate(0.01, 4);
- // Display configuration
- checkConfig();
- Serial.println("-----------------------------------------------");
- }
- void loop()
- {
- Serial.print("Bus voltage: ");
- Serial.print(ina.readBusVoltage(), 5);
- Serial.println(" V");
- Serial.print("Bus power: ");
- Serial.print(ina.readBusPower(), 5);
- Serial.println(" W");
- Serial.print("Shunt voltage: ");
- Serial.print(ina.readShuntVoltage(), 5);
- Serial.println(" V");
- Serial.print("Shunt current: ");
- Serial.print(ina.readShuntCurrent(), 5);
- Serial.println(" A");
- Serial.println("");
- delay(1000);
- }
Wynik działania programu
Wykorzystanie sygnału ALERT
INA226 posiada jeszcze bardzo przydatną funkcję jaką jest sygnał ALERT. Możemy określić, czy sygnał na tym wyjściu ma być aktywny po przekroczeniu zadanej wartości (lub kiedy znajduje się poniżej tej wartości). Rodzaj badanej wartości wybiera się za pomocą wybranej funkcji:
- dla napięcia na szynie:
- enableBusOvertLimitAlert();
- enableBusUnderLimitAlert();
- setBusVoltageLimit(v = float);
- dla napięcia na boczniku:
- enableShuntOverLimitAlert();
- enableShuntUnderLimitAlert();
- setShuntVoltageLimit(v = float);
- dla poboru mocy:
- enableOverPowerLimitAlert();
- setPowerLimit(p = float);
Możliwe jest również określenie, czy aktywnym sygnałem jest stan wysoki, czy niski za pomocą funkcji: setAlertInvertedPolarity(true / false). W domyślnych ustawieniach, sygnał ALERT jest podawany tak długo, jak długo występują podane warunki pomiarowe. W przykładzie jest to przekroczenie 130mW (w momencie podłączenia drugiej diody do obciążenia, zapali się dioda niebieska)
- #include <Wire.h>
- #include <INA226.h>
- INA226 ina;
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Initialize INA226");
- Serial.println("-----------------------------------------------");
- // Default INA226 address is 0x40
- ina.begin();
- // Configure INA226
- ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
- // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
- ina.calibrate(0.01, 4);
- // Enable Bus Over-Voltage Alert
- // ina.enableBusOvertLimitAlert();
- // ina.enableBusUnderLimitAlert();
- // ina.setBusVoltageLimit(3.33);
- // Enable Shunt Over-Voltage Alert
- // ina.enableShuntOverLimitAlert();
- // ina.enableShuntUnderLimitAlert();
- // ina.setShuntVoltageLimit(0.0055);
- // Enable Power Over-Limit Alert
- ina.enableOverPowerLimitAlert();
- ina.setPowerLimit(0.130);
- // ina.setAlertInvertedPolarity(true)
- }
- void loop()
- {
- Serial.print("Bus voltage: ");
- Serial.print(ina.readBusVoltage(), 5);
- Serial.println(" V");
- Serial.print("Bus power: ");
- Serial.print(ina.readBusPower(), 5);
- Serial.println(" W");
- Serial.print("Shunt voltage: ");
- Serial.print(ina.readShuntVoltage(), 5);
- Serial.println(" V");
- Serial.print("Shunt current: ");
- Serial.print(ina.readShuntCurrent(), 5);
- Serial.println(" A");
- Serial.println("");
- delay(1000);
- }
Całości smaku dodaje możliwość ustawienia sygnału ALERT z "zatrzaskiem". Sygnał ALERT będzie tak długo aktywny (nawet po ustaniu warunku pomiarowego), aż do momentu odczytania rejestru za pomocą funkcji isAlert() i ewnetualnego obsłużenia zdarzenia w programie:
- #include <Wire.h>
- #include <INA226.h>
- INA226 ina;
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Initialize INA226");
- Serial.println("-----------------------------------------------");
- // Default INA226 address is 0x40
- ina.begin();
- // Configure INA226
- ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
- // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
- ina.calibrate(0.01, 4);
- // Enable Power Over-Limit Alert
- ina.enableOverPowerLimitAlert();
- ina.setPowerLimit(0.130);
- ina.setAlertLatch(true);
- }
- void loop()
- {
- Serial.print("Bus voltage: ");
- Serial.print(ina.readBusVoltage(), 5);
- Serial.println(" V");
- Serial.print("Bus power: ");
- Serial.print(ina.readBusPower(), 5);
- Serial.println(" W");
- Serial.print("Shunt voltage: ");
- Serial.print(ina.readShuntVoltage(), 5);
- Serial.println(" V");
- Serial.print("Shunt current: ");
- Serial.print(ina.readShuntCurrent(), 5);
- Serial.println(" A");
- if (ina.isAlert())
- {
- // Latch will be removed here
- Serial.println("ALERT");
- }
- Serial.println("");
- delay(1000);
- }
Materiały dodatkowe
Biblioteka INA226: https://github.com/jarzebski/Arduino-INA226
Dokumentacja techniczna: https://www.jarzebski.pl/datasheets/INA226.pdf
Reklama
Komentarze
Wszystko pieknie tylko gdzie mozna nabyc ina226 w naszym kraju ??
INA226 jedynie chyba na Farnell - ja tam zamawiałem bez problemu: http://pl.farnell.com/texas-instruments/ina226aidgst/current-monitor-10msop/dp/1924807
INA219 znajdziesz na w sklepie ElTy: https://elty.pl/pl/p/INA219AIDR-SOP8-/1010
Dzieki za info ....
Cześć,
W ubiegłym tygodniu dotarły do mnie sample INA226 z TI i wszystko ładnie zadziałało. Dzięki za zwrócenie uwagi i opisanie tego scalaka - okazało się, ze jest idealny na potrzeby mojego małego projektu.
Pozdrawiam
Jarlath
http://www.jarlath.net
Cześć.
A czy jest jakiś sposób na pomiar prądu oraz mocy dla wyższczego domowego napięcia 240 V.
Pozdrawiam
Grzegirz
Nie spotkałem się z takimi układami bezpośredniego napięcia, ale pomocny może okazać się ten wpis: http://forum.arduino.cc/index.php/topic,19287.0.html
Chętnie bym coś takiego wykonał ale skąd wziąć rezystorki current sense ?
Skąd zamówić INA już wiem z poprzednich komentarzy ale takie rezystory to tez problem
Pozdrawiam
Na http://pl.farnell.com znajdziesz odpowiednie :)
Z kąd wziąść bibliotekę INA226 do eagle?
Hej,
a co z pomiarem prądu przy PWM? Trzeba stosować RC czy będzie działać dobrze bez niego?
Z zastosowaniem filtra RC czemu nie?
Przez przypadek kupiłem ina326, czy można go uczuć podobny sposób, chodzi mi o mierzenie aperarzu z pomocą bocznika 60mv 200a, A dzięki arduino zapisywanie tego w jakieś bazie danych
Pewnie można, ale nota katalogowa INA326 nie da Ci wyników na i2c, tylko wystawi napięcie do pomiaru pinem analogowym
Thanks for this great Arduino library. This worked on the first try and the data is clearly presented. Great Job.
Hello, thank you for great job. I have question. Can I connect few INA226 to arduino. How to set address in program different from default.
Thank you
Please open INA226.h - Header file and change the address in line #20. To control more than one device you should add typedef enum with all neded addresses.
Czy ktoś próbował obsługi tego w bascomie. Chciał bym go dodać ale nie wiem od czego zacząć.
W opisie podano "dodatkowy pin VBUS mostkujemy z VIN-".
Czy nie powinno być "z VIN+" (przy założeniu że pomiędzy VBUS a VIN+ nic nie mamy wpięte).
Pozdrawiam i dziękuję za świetne opisy i biblioteki
.. do których pojawiają się nawet linki w komentarzach na AliExpress :)
Chciałbym wykorzystać układ INA216 w popularnym module ładowarki (rozładowarki) dla ogniwa 18650 i dzięki temu uzyskać/potwierdzić charakterystyki prądów i napięć oraz wyliczyć rezystancję wewnętrzną.
http://nowyelektronik.pl/index.php?id_product=88349&controller=product
W instrukcji układu jak i temacie powyższego artykułu jest "Bi-Directional/Dwukierunkowy".
W jaki sposób można uzyskać informację o kierunku prądu ?
Przykładowo w układzie MAX471 jest dodatkowy pin wyjściowy.
1. Czy w tym układzie INA226 mamy jakiś rejestr z bitem kierunku (direction) dostępny przez i2C ?
2. Czy schemat konfiguracji układu (z pierwszej strony instrukcji) będzie poprawny zarówno dla trybu rozładowania (przez LOAD) jak i dla tryby ładowania (bez LOAD) ?
http://www.ti.com/lit/ds/symlink/ina226.pdf
Dziękuję za odpowiedź.
Hura! Udało mi się połączyć te 2 moduły :)
Ogniwo się ładuje a moduł INA226 (z Ebaya) pokazuje co trzeba.
Do bocznika na płytce 0.1Ω dolutowałem równolegle dwa szeregowo połączone rezystory 0.01Ω (wyciągnięte z rozładowanej baterii do laptopa) co daje sumarycznie 0.0167Ω.
Bus voltage: 4.13750 V
Bus power: 1.14000 W
Shunt voltage: -0.00460 V
Shunt current: -0.27520 A
Pytanie o kierunek prądu już nieaktualne bo jak widać powyżej uzyskujemy wartości ze znakiem (minus) :)
Moduł z INA226 można kupić na Ali już za 2$. Szkoda tylko że VBUS nie ma większego zakresu (jest do 36V) to by idealnie pasował do mierzenia napięcia i mocy w obwodzie zasilania e-bike na pakietów większych niż 10s. Ale to nie problem bo można zastosować dzielnik rezystorowy. Tylko w tym przypadku będzie trzeba zmienić lekko program.
No i jeszcze potwierdzenie, że działa również w obwodzie z Load :)
Bus voltage: 3.68750 V
Bus power: 2.46000 W
Shunt voltage: 0.01114 V
Shunt current: 0.66680 A
Jutro przeanalizuję jeszcze wielkość bocznika tak aby pomiar był optymalny, błędy najmniejsze oraz przy założeniu, że spadek na boczniku nie wpływa negatywnie na odczyt napięcia ogniwa przez układu TP4056.
Do kitu ten wynalazek, biblioteka z przykładowym szkicem pół Atmegi 328P zajmuje. Jeśli głównym zadaniem urządzenia jest pomiar prądu to ok, ale jak ma to być dodatkowa funkcja to tylko Mega :/
Witam,
Właśnie robię projekt z wykorzystaniem Twojej biblioteki i mam małą sugestię: w obecnej postaci jakikolwiek problem z komunikacją z modułem INA (np. z jakichkolwiek przyczyn nieobecnym) powoduje zawieszenie się programu. Wszystko to za sprawą procedury readRegister16, która zawiera taką oto linijkę:
while(!Wire.available()) {};
Jeśli wire nie jest available, ta pętla będzie się wykonywać bez końca. Proponuję zastąpić ją taką:
while (!Wire.available() && millis() - waittime
Słuchajcie, pojawił mi się dziwny problem z tymi układami, może ktoś jest w stanie coś podpowiedzieć: robię urządzenie, w którym ma być wykorzystanych szesnaście tych układów, z wykorzystaniem wszystkich dostępnych adresów. Z konieczności (brak miejsca) nie kupowałem gotowych modułów z INA, tylko same układy scalone na aliexpress, ale lutowałem je zgodnie ze sztuką, nie robiłem tego pogrzebaczem ani transformatorówką.
I nie wiem, czy kupiłem jakąś felerną serię od chińczyka, czy jednak te układy są tak bardzo wrażliwe na ESD, ale niemal we wszystkich z kupionych 20 sztuk układów, linia adresowa A1 zachowuje się tak, jakby wisiała w powietrzu. Linią A0 mogę ustawiac adres, ale poruszam się tylko w przestrzeni czterech adresów, A1 obojętnie do czego bym nie podpiął, zachowuje się jak podłączona do Vcc. Na płytce nie ma zwarcia, układy sprawdzałem po kolei i problem występuje właściwie na wszystkich.
Dziękuję za bibliotekę, działa :)
Mam jeden problem z INA226. Przy braku jakiegokolwiek odbioru wykazuje mi ppobór prądu -0.00020A. Sprawdzałem przy różnym próbkowaniu - przy pojedynczym pomiarze odczyt faluje od 0.00000 do -0.00040. Przy usrednianiu 1024 blad jest chyba staly i wynosi te -0,00020A
Czy to jest kwestia jakiejs kalibracji? Akura chce mierzy male prady i taki blad zakloca mi pomiary :)
Dzień drobny
Mam dziwny problem z INA226 - napięcie mierzy poprawnie, a prąd zawyża prawie 3x. Jako obciążenia użyłem rezystora 100Ohm/5W, zasilanie mały akumulatorek LiPol - w chwili testu 3.9V. Dwa multimetry wskazują jak powinno być czyli około 0.04A, INA około 0.09A!
Używam Pańskich bibliotek i Arduino NANO (to zresztą chyba bez znaczenia).
Próbowałem różnego oversamplingu etc i nic się nie zmienia poza szumem - skala błędu nie zmienia się. Rezystora bocznikowego nie wylutowywałem, próbowałem go zmierzyć i wydaje się mieć poprawną oporność...
Ma Pan może co może być źródłem błędu?
Ps. Update do poprzedniego wpisu.
Żeby otrzymać poprawny pomiar prądu, muszę zdefiniować wartość rezystora ina.calibrate(0.02385, 4);
Hello,
I have this problem... want to use yours INA226_simple.ino
Arduino: 1.6.3 (Windows 7), Board: "Arduino Nano, ATmega328"
In file included from ina226.ino:10:0:
... fatal error: DWire.h: No such file or directory
#include
...where find dwire.h and dserial.h?
thx
^
Cześć, jestem Muharrem
Używam rezystora bocznikowego 500 A.
setcalibr A (0.00015,500);
Robię, a maksymalny prąd wynosi 22,9 Co jeszcze muszę zmienić?