Me había olvidado de esto...
veamos según la hoja de datos hay que seguir estos pasos:
VbusMax = 16V - Esto lo defino yo de acuerdo a mi sistema
VshuntMax = 0,32V - Puede ser 40/80/160 mV
Rshunt = 0.82ohm/5 = 0.164ohm
MaxPosibleI = 0.32V/0.164ohm = 1.95A
MaxExpectedI = 1.5A - Esto es lo que yo considero como máxima corriente esperada en mi sistema.
MinimumLSB = 1.5A/32767 = 45.8uA
MaximumLSB = 1.5A/4096 = 366uA
De esos dos valores elijo uno que este entre los dos, lo más chico posible para tener presicion y en lo posible redondo. Por ejemplo 100uA
CurrentLSB = 100uA
Calibracion = 0.04096 / (100 .10-6 * 0.164) = 2497 - Acá hay que tener en cuenta que el bit 0 del registro de calibracion es siempre 0, por lo que los datos impares se almacenarán como el impar menor más cercano (2496)
PotLSB = 20 x CurrentLSB = 2mW
Con todo esto puedo guardar la calibracion y hacer las converciones de datos Raw en valores reales.
Modifiqué levemente el programa para que quede mejor y cumpla con estas condiciones:
INA219.h
#ifndef INA219_H_
#define INA219_H_
#include "i2c.h"
extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define INA219_WRITE_ADDR (0x80) // 1000000 (A0+A1=GND)
#define INA219_READ_ADDR (0x81)
/*=========================================================================*/
/*=========================================================================
CONFIG REGISTER (R/W)
-----------------------------------------------------------------------*/
#define INA219_REG_CONFIG (0x00)
/*---------------------------------------------------------------------*/
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
/*=========================================================================*/
/*=========================================================================
SHUNT VOLTAGE REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_SHUNTVOLTAGE (0x01)
/*=========================================================================*/
/*=========================================================================
BUS VOLTAGE REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_BUSVOLTAGE (0x02)
/*=========================================================================*/
/*=========================================================================
POWER REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_POWER (0x03)
/*=========================================================================*/
/*=========================================================================
CURRENT REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_CURRENT (0x04)
/*=========================================================================*/
/*=========================================================================
CALIBRATION REGISTER (R/W)
-----------------------------------------------------------------------*/
#define INA219_REG_CALIBRATION (0x05)
/*=========================================================================*/
#define PORT_USED 1
void INA219_init();
unsigned char INA219_read_reg(unsigned char reg, signed short *value);
unsigned char INA219_write_reg(unsigned char reg_address, unsigned short value);
unsigned char INA219_read_reg(unsigned char reg, signed short *value){
int i;
for ( i = 0; i < BUFSIZE; i++ )
{
I2CSlaveBuffer[PORT_USED][i] = 0x00;
}
unsigned char result=0;
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 2;
I2CMasterBuffer[PORT_USED][0] = INA219_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg;
I2CMasterBuffer[PORT_USED][2] = INA219_READ_ADDR;
result=I2CEngine(PORT_USED);
*value = ((I2CSlaveBuffer[PORT_USED][0] << 8) | I2CSlaveBuffer[PORT_USED][1]);
return(result);
}
unsigned char INA219_write_reg(unsigned char reg_address, unsigned short value){
I2CWriteLength[PORT_USED] = 4;
I2CReadLength[PORT_USED] = 0;
I2CMasterBuffer[PORT_USED][0] = INA219_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg_address;
I2CMasterBuffer[PORT_USED][2] = ((value >> 8) & 0xFF);
I2CMasterBuffer[PORT_USED][3] = (value & 0xFF);
return(I2CEngine( PORT_USED ));
}
#endif /* INA219_H_ */
Luego mi main.c me queda:
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
volatile uint32_t msTicks;
__INLINE static void delay_ms (uint32_t delayTicks) {
uint32_t currentTicks;
currentTicks = msTicks; // read current tick counter
while ((msTicks - currentTicks) < delayTicks);
}
#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "uart2.h"
#include <stdio.h>
#include "i2c.h"
#include "INA219.h"
void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}
/*******************************************************************************
** Main Function main()
*******************************************************************************/
int main (void){
signed short data=0;
//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000)) {
while (1);
}
I2C1Init(); // Inicializo el I2C1
UART2_Init(115200); // Inicializo el UART a 115200
UART2_PrintString ("\r\nINA219\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");
UART2_PrintString ("Escribiendo calibración (2497)\r\n");
INA219_write_reg(INA219_REG_CALIBRATION, 2497);
INA219_read_reg(INA219_REG_CALIBRATION, &data);
UART2_PrintString("\r\nConfiguracion leida: ");
uart2_printUint32(data, 10);
delay_ms(2000);
while ( 1 ){
INA219_read_reg(INA219_REG_SHUNTVOLTAGE, &data);
UART2_PrintString("\r\nTens. sht: ");
uart2_printDouble(data * 0.00001, 3); //El LSB es 10uV
delay_ms(2);
INA219_read_reg(INA219_REG_BUSVOLTAGE, &data);
UART2_PrintString("V\tTens. bus: ");
uart2_printDouble((data>>3) * 0.004, 3); //Alineo el resultado y el LSB es 4mV
delay_ms(2);
INA219_read_reg(INA219_REG_POWER, &data);
UART2_PrintString("V\tPot : ");
uart2_printDouble(data * 0.002, 3); //El LSB de potencia me dió 2mW
delay_ms(2);
INA219_read_reg(INA219_REG_CURRENT, &data);
UART2_PrintString("W\tCorr : ");
uart2_printDouble(data * 0.0001, 3); //El LSB de corriente es 100uA
UART2_PrintString("A");
delay_ms(300);
}
}
Algo importante es que la tensión de bus estpa desplazada 3 posiciones en el registro, por ello el desplazamiento que hago en el código. Luego es cuestion de multiplicar cada valor por su LSB.
El LSB de la V de shunt es fijo y es 10uV y el de la V bus es de 4mV. El resto los hemos calculado.
La salida ahora es:

Ahora sí, si hacemos Vbus * I nos da lo mismo que la potencia medida, cosa que antes no sucedía!!!!
Saludos!