Strom und Leistungsmessung mit dem INA226

Gepostet von am 12. Januar 2016, 23:46

Bei eigenen Projekten ist es meistens gut zu wissen, wie viel Strom benötigt wird. Besonders bei Akku-betriebenen Schaltungen ist es wichtig, um die Akkulaufzeit abzuschätzen und bei niedriger Spannung das System herunterzufahren bevor der Akku ausfällt. Gleichzeitig lässt sich dadurch die Lebensdauer des Akkus verlängern.

Daten per I2C auslesen

Bei Systemen mit I2C-Bus können die Daten wie Spannung, Strom und Leistung über diesen Bus ausgelesen werden. Ich verwende dazu den Baustein INA226 von Texas Instruments.

Beschaltung des INA226

Die Beschaltung ist relativ einfach. Es muss nur ein zusätzlicher Shunt verbaut werden. Ich verwende hier einen mit 10 mOhm. Damit können Ströme bis 8,192 A gemessen werden, da der INA226 beim Shunt einen Messbereich von +- 81,92 mV hat.

Beschaltung INA226

Konfiguration

Nach einem Reset bzw. Power-Up sind alle Register des INA226 bereits so gesetzt, dass er funktioniert. Lediglich im Register 05h muss noch der entsprechende Wert für den Shunt gesetzt werden, dass Strom und Leistung richtig berechnet werden. Mit den 15-bit Auflösung bei der Strommessung erreicht man 250 µA/Bit. Mit den Formeln aus dem Datenblatt errechnet sich ein Kalibrierwert von 2048 = 0800h.

Programmierung

Im weiteren Betrieb müssen dann nur noch die folgenden Register ausgelesen werden. Register 02h enthält den Wert für die Spannung. Der Wert hat eine Auflösung von 1,25 mV / Bit. Das heißt, wenn man denn ausgelesenen Wert mit 0,00125 multipliziert erhält man die Spannung in V. Register 04h enthält den Wert für die Stromstärke. Dieser muss mit dem oben festgesetzten Wert von 250 µA / Bit, also mit 0,00025, multipliziert werden, damit man den Strom in A erhält. Im Register 03h steht die aktuelle Leistung. Dazu wird der Stromwert erst mit 25 und dann mit dem Spannungswert multipliziert. Der hier ausgelesene Wert muss mit 0,0625 multipliziert werden, damit man die Leistung in W erhält.

Beispielcode für Beaglebone Black

Im Folgenden findest du einen Beispielcode für den Beaglebone Black. Der INA226 muss mit dem I2C2 vom Beaglebone Black verbunden sein und dieser muss aktiviert sein.

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>

int read_reg16(int file, char reg)
{
	char buf[2]={0};
	int x;

	buf[0]=reg;
	write(file,buf,1);	// set read register
	read(file,buf,2);	// read 2 bytes
	x=((buf[0])<<8)+buf[1];	// combine bytes

	return x;
}

int main(void)
{
	int file;
	int addr=0x40;		// adress of INA226
	char buf[10]={0};
	int x;

	printf("INA226\n");
	if((file=open("/dev/i2c-1",O_RDWR))<0)	// open i2c-bus
	{
		perror("cannot open i2c-1");
		exit(1);
	}
	if(ioctl(file, I2C_SLAVE, addr)<0)	// open slave
	{
		perror("cannot open slave address");
		exit(1);
	}
	buf[0]=0x05;
	buf[1]=0x08;
	buf[2]=0x00;	// set shunt resistor 10 mOhm
	write(file,buf,3);

	x=read_reg16(file, 0x02);
	printf("   Spannung: %f V (%i)\n",(float)x*0.00125, x);
	x=read_reg16(file, 0x04);
	printf("   Strom:    %f A (%i)\n",(float)x*0.00025, x);
	x=read_reg16(file, 0x03);
	printf("   Leistung: %f W (%i)\n",(float)x*0.00625, x);

	close(file);

	return 0;
}

Update 18.01.2016

Ansteuerung mit i2c-dev

Es hat sich herausgestellt, dass es sinnvoller ist, den I2C-Bus gleich mit der i2c-dev-Library von Linux anzusteuern. Diese Library bringt Funktionen mit denen direkt Bytes und Words aus I2C-Geräten ausgelesen werden können. Bevor die Library verwendet werden kann, müssen allerdings die passenden header-Dateien installiert werden. Das geschieht mit folgendem Befehl:

sudo apt-get install libi2c-dev

Allerdings liefert der INA226 beim Auslesen mit i2c_smbus_read_word_data() die Bytes in vertauschter Reihenfolge. Deshalb gibt es nicht die Funktion swap_bytes(), die die Bytes wieder in die richtige Reihenfolge bringt.
Das komplette Programm sieht dann so aus:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>

unsigned short int swap_bytes(unsigned short int input)
{
	return (((input & 0xff) << 8) | ((input >> 8) & 0xff));
}

int main(void)
{
	int file;
	int addr=0x40;		// adress of INA226
	int x;

	printf("INA226\n");
	if((file=open("/dev/i2c-1",O_RDWR))<0)	// open i2c-bus
	{
		perror("cannot open i2c-1");
		exit(1);
	}
	if(ioctl(file, I2C_SLAVE, addr)<0)	// open slave
	{
		perror("cannot open slave address");
		exit(1);
	}
	i2c_smbus_write_word_data(file,0x05,swap_bytes(0x0800));	// set shunt resistor 10 mOhm

	x=swap_bytes(i2c_smbus_read_word_data(file, 0x02));
	printf("   Spannung: %f V (%i)\n",(float)x*0.00125, x);
	x=swap_bytes(i2c_smbus_read_word_data(file, 0x04));
	printf("   Strom:    %f A (%i)\n",(float)x*0.00025, x); // 10 mOhm
	x=swap_bytes(i2c_smbus_read_word_data(file, 0x03));
	printf("   Leistung: %f W (%i)\n",(float)x*0.00625, x); // 10 mOhm

	close(file);

	return 0;
}

auf dem Raspberry Pi

Das Programm läuft ohne Änderungen auch auf dem Raspberry Pi. Bevor der I2C-Bus verwendet werden kann, muss er aktiviert werden. Das geschieht mit dem Programm raspi-config.


Kategorien ,

Stichworte INA226,I2C,Texas Instruments,Beaglebone Black,Raspberry Pi


Kommentare

Kommentarfunktion für diesen Artikel geschlossen.