Strom Sensor (Bsp. 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 (+/-) |
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);
}