Arduino Mikrocontroller Tutorials - Module

Strom Sensor (Bsp. INA226)

Bild INA226

Der INA226 von Texas Instruments ist ein Stromsensor nach dem Prinzip der Messung des Spannungsabfalls über einen Shunt Widerstand und der Berechnung des Stroms mit Hilfe des ohmschen Gesetzes (I=U÷R).

Neben der Messung des Stroms kann mit dem IC auch die Leistung berechnet und ausgegeben werden. Dazu wird mit einer zweiten Messung der Spannungsabfall am Verbraucher (VBUS) gemessen und mit der zuvor ermittelten Stromstärke intern mit der Formel P=U×I die Leistung berechnet.

Der einzelne INA226 IC kann sowohl auf der HIGH-Side als auch auf der LOW-Side zur Strommessung eingesetzt werden. Da auf dem Breakoutboard der Eingang VBUS fest mit dem VOUT Anschluß verbunden ist, kann mit dem Modul jedoch die Leistung nur High-Side gemessen werden.

Mit dem eingebauten Shunt von 0,1Ω kann das Modul Ströme bis 800mA bei einer Verbraucherspannung von 0-36V messen. Der Stromverbrauch des ICs liegt bei rund 360µA.

Pinbelegung
VCC Spannungsversorgung + (2,7-5,5V)
GND Masse -
ALERT Wird auf LOW gesetzt wenn ein zuvor festgelegtes Eriegnis
überscritten bzw. unterschritten wird.
SDA I2C Datenleitung
SCL I2C Clockleitung
A0/A1 Lödpads um die I2C Adresse einzustellen.
Mit offenem Eingang ist die Adresse in 0x40
VIN Eingang für die Strommessung (+/-)
VOUT Ausgang der Strommessung (+/-)
Funktionsschaubild INA226

Register des INA226

Address Pointer Register

Bei der I2C Kommunikation landet man zunächst immer in einem Adress Poiter Register. Hier stellt man dann ein, von welchem Register man Daten empfangen will oder welches Register beschrieben werden soll. Das Register hat die Größe von einem Byte.

0x00 → Configuration Register (default)
0x01 → Shunt Voltage Register
0x02 → Bus Voltage Register
0x03 → Power Register
0x04 → Current Register
0x05 → Calibration Register
0x06 → Mask/Enable Register
0x07 → Alert Limit Register

Configuration Register (0x00)

In diesem 16 Bit Register werden verschiedene Grundeinstellungen gespeichert. Die Bits haben dabei folgende Bedeutung:

MSB Reset Bit
0 : Messbetrieb (default)
1 : Reset. Alle Register und Einstellungen werden wie beim Neustart gelöcht.
14-12 Bits D14 bis D12 werden nicht genutzt
11-9 Averaging Mode
Anzahl der Messungen aus welchen zunächst ein Durchscnittswert gebildet und dann in die Ergebnisregister übertragen wird.
000 : 1 Messung (default)
001 : 4 Messungen
010 : 16 Messungen
011 : 64 Messungen
100 : 128 Messungen
101 : 256 Messungen
110 : 512 Messungen
111 : 1024 Messungen
8-6 Bus Voltage Conversion Time
Zeit welche für eine Messung verwendet wird.
000 : 140µs
001 : 204µs
010 : 332µs
011 : 588µs
100 : 1,100ms (default)
101 : 2,116ms
110 : 4,156ms
111 : 8,244ms
5-3 Shunt Voltage Conversion Time
Zeit welche für eine Messung verwendet wird.
000 : 140µs
001 : 204µs
010 : 332µs
011 : 588µs
100 : 1,100ms (default)
101 : 2,116ms
110 : 4,156ms
111 : 8,244ms
2-LSB Operating Mode
Hier wird der Betriebsmodus eingestellt.
000 : Sleep Modus
001 : Messung Shunt Spannung anfordern
010 : Messung Bus Spannung anfordern
011 : Messung Shunt und Bus Spannung anfordern
100 : Sleepmodus (default)
101 : Kontinuierliche Shunt Spannungsmessung
110 : Kontinuierliche Bus Spannungsmessung
111 : Kontinuierliche Shunt und Bus Spannungsmessung (default)

Shunt Voltage Register (0x01)

Der Analog zu Digital Converter misst zuerst die Shunt Spannung zwischen VIN und VOUT. Die Auflösung der Messung der Shuntspannung beträgt fest eigestellt 2,5µV pro Bit. Das Ergebnis des ADC (bzw. der Durchschnittswert falls mehrere Messungen im Configuartion Register eingestellt sind) wird als 16 Bit Integer (int) Wert gespeichet und kann daher Werte von -32768 bis 32767 annehmen. Der maximal messbare Spannungsabfall sind daher 32767 Bits x 2,5µV = 81,92 mV.

Bus Voltage Register (0x02)

Als zweites misst der ADC die Spannung zwischen VBUS (im Modul = VOUT) und GND. Der Messwert wird ebenfalls als Integer (int) Wert gespeichert, kann aber - da gegen GND gemessen wird - nur positive Werte anehmen. Die Auflösung beträgt fest eingestellt 1,25mV pro Bit.

Current Register (0x04)

Der Wert in diesem Register wird nicht gemessen sondern vom INA226 mit der Formel

Current = Shunt Voltage × Calibration ÷ 2048

berechnet. Der feste Rechenwert 2048 dient dazu den Wert des 'Calibration Registers' wieder zu reduzieren. Da im 'Calibration Register' keine Kommazahlen gespeichert werden können wurde der eigentliche Rechenwert zuvor um den den Faktor 2048 erhöht.

Der Umrechungsfaktor bzw. die Auflösung des Speicherinhalts zum weiteren Verwenden ist vom Shunt-Widerstand der Schlatung abhängig und wird folgendermaßne festgelegt.

maximal messbare Stromstärke = max Shuntspannung (81,92mV) ÷ Shunt (0,1Ω ) = 819mA ≈ 800mA

Stromstärke pro Bit = maximal messbare Stromstärke (800mA) ÷ 32767 = 0,024 mA pro Bit

Calibration Register (0x05)

In diesem Register ist der komplette Umrechnungfaktor zum Berechnen der Stromstärke gespeichert. Also die Auflösung um von dem binären Speicherinhalt die Stromstärke zu erhalten sowie den Faktor um diese Stromstärke wieder auf einen verwendbaren Wert mit Kommastellen zu bringen. Als default ist in diesem Register der Wert 0 gespeichert. Daher ist auch das 'Current Register' und das 'Power Register' default 0.

Der Registerinhalt ist abhängig von dem verwendeten Shunt-Widerstand und wird nach dem ohmschen Gesetz I = U ÷ R folgendermaßen berechnet. (Der Faktor 2048 dient dazu den 'Calibartion' Registerinhalt auf ein größeren Wert zu erhöhen. Bei der späteren Berechnung des 'Current' Registers wird der Wert wieder um diesen Faktor reduziert).

Stromstärke = Current × 0,000024 A/Bit = (Shunt Voltage × 0,0000025 V/Bit) ÷ 0,1Ω

Current = Shunt Voltage × 0,0000025 ÷ 0,000024 ÷ 0,1Ω = Shunt Voltage × Calibration ÷ 2048

Calibration = (0,000025 ÷ 2048) ÷ (0,000024 × 0,1) = 0,00512 ÷ (0,000024 × 0,1Ω) = 2133

Power Register (0x03)

Der Wert in diesem Register entspricht der Leistung des Verbrauchers und wird vom INA226 intern mit der Formel

Power = (Current × Bus Voltage) ÷ 20000

berechnet. Das eigentliche Ergebnis wird hier durch 20000 dividiert um eine geeignetere Größe für den 16Bit Speicherplatz zu erhalten. Beim Verwenden dieses Registerwertes muss man den den Speicher daher wieder erhöhen. Der Umrechnungsfaktor dazu ist:

Leistung = Power × Umrechnungsfaktor

Leistung = Bus Voltage × 0,00125 V/Bit × Current × 0,000024 A/Bit = Bus Voltage × Currrent ÷ 20000 × Umrechnungsfaktor

Umrechnungsfaktor = 0,00125 V/Bit × 0,000024 A/Bit × 20000 = 0,000024 × 25 = 0,0006 W/Bit

Mask/Enable Register

In diesem Register werden die Einstellung für der ALERT Pin vorgenommen. Also ob es ein unteres oder ein oberes Limit ist, ob die Shunt Spannung oder die Bus Sapnnung überwacht wird usw.
Falls der ALERT Ausgang verwendet werden können die Einstellungen dem Datenblatt des INA226 entnommen werden.

Alert Limit Register

Hier wird das Limit bzw. die Grenze eingegeben. Wird die Grenze über- oder unterschritte (ahängig der Einstellungen im 'Mask/Enable Register') wird der ALERTPIN auf Low gesetzt.

I2C Kommunikation

Der INA226 hat mehrere Register die über I2C von außen zugänglich sind. Standardmäßig greift I2C mit dem ersten übertragenen Byte auf das Address Pointer Register zu. In diesem Register wird dann ein Pointer zu einem der anderen Register gesetzt. Das dann folgende Übertragungsbyte wird in das verwiesene Register geschrieben oder Daten von dort angefordert.

Registereinträge ändern

Zum ändern von Registereinträgen wird mit Wire.beginTransmission(Adresse) der INA226 Slave über seine I2C Adresse angesprochen und zum Lesen aufgefordert. Das erste Byte landet im 'Address Pointer Register'. Dort kann man dann den Pointer für die folgenden Daten beispielsweise auf das 'Configuration Register (0x00)' setzten. Die beim INA226 verwendendeten Register sind 16 Stellen lang. Es müssen also jeweils zwei weitere Bytes übertragen werden. Mit Wire.endTransmission() wird die I2C Übertragung durch den Mikrocontroller (Master) beendet.

Wire.beginTransmission(0x40); // I2C Adresse des INA226 = 0x40 Wire.write(0x00); // Pointer im Addressregister auf 'Configuration Register' setzen Wire.write(B00001001); // MSB (Bits 15-8) setzen Wire.write(B00100111); // LSB (Bits 7-0) setzen Wire.endTransmission();

Registereinträge anfordern

Auch hier müssen wir zunächst das Pointer Register mit dem Verweis auf ein Messwerteregister (z.B. Shunt Voltage Resgier (0x01) beschreiben.

Wire.beginTransmission(0x40); // I2C Adresse des INA226 = 0x40 Wire.write(0x01); // Pointer im Addressregister auf 'Shunt Voltage Register' setzen Wire.endTransmission();

Wenn der Pointer für die folgenden Übertragung gesetzt ist können die Messwerte mit Wire.requestFrom(Adresse, Anzahl erwarteter Bytes) angefordert werden. Bei der I2C Übertragung werden die Daten immer Byteweise übertragen. Um das 16 bit Register des Messwerts zu übertragen werden also zwei Bytes gesendet. Zuerst das HighByte, dann das LowByte.

Wire.requestFrom(0x40, 2); unsigned int messWert = Wire.read() << 8 ; // High Byte 8 Stellen nach links schieben messWert = messWert | Wire.read(); // Low Byte hinzufügen

Programmcode

#include "Wire.h" void setup() { Serial.begin(9600); Wire.begin(); } void loop() { // 'Calibration Register' einstellen Wire.beginTransmission(0x40); Wire.write(0x05); // Pointer im 'Address Register' auf 'Calibration Register' setzen Wire.write(B00001000); // MSB (Bits 15-8) des setzen Wire.write(B01010101); // LSB (Bits 7-0) des setzen Wire.endTransmission(); // Pointer auf das 'Current Register' stellen Wire.beginTransmission(0x40); Wire.write(0x04); // Pointer im 'Address Register' auf 'Current Register' setzen Wire.endTransmission(); // Messwert auslesen (2 Byte) Wire.requestFrom(0x40, 2); int messWert = Wire.read() << 8 ; // High Byte 8 Stellen nach links schieben messWert = messWert | Wire.read(); // Low Byte hinzufügen // Messwert ausgeben float I = messWert * 0.024 ; // Auflösung 0,024mA pro Binärschritt. Ausgabe in mA Serial.print("Stromstärke: " + String(I, 5) + " mA"); delay(250); }