66// LED GPIOs
77#define EXT_LED_GPIO 2
88
9- // INA228 integrated shunt resistance
9+ // INA228 integrated shunt resistance in Ohms
1010#define R_SHUNT 0.015
1111
12- // Max expected current through shunt resistor
12+ // Max expected current through shunt resistor in Amps
1313#define MAX_EXPECTED_CURRENT 0.1
1414#define I2C_ADDR 0x40
1515
16+ // Macros for bit-shifting register reads
17+ #define FLATTEN2 (a2 ) ((a2[0] << 8) + a2[1])
18+ #define FLATTEN3 (a3 ) ((a3[0] << 16) | (a3[1] << 8) | a3[2])
19+ #define FLATTEN3_RESERVED (a3 ) ((a3[0] << 12) | (a3[1] << 4) | (a3[2] >> 4))
20+ #define FLATTEN5 (a5 ) (((uint64_t) a5[0] << 32) | (a5[1] << 24) | (a5[2] << 16) | (a5[3] << 8) | a5[4])
21+
1622// ina228 registers (see datasheet)
1723uint8_t VSHUNT_REG = 0x04 ;
1824uint8_t VBUS_REG = 0x05 ;
@@ -42,11 +48,11 @@ float vshunt, vbus, dietemp, current, power, energy, charge;
4248static void ina228_init () {
4349 // Write to shunt register
4450 uint8_t shunt_msb = (SHUNT_CAL >> 8 ) & 0xFF ;
45- uint8_t shunt_lsb = SHUNT_CAL & 0xff ;
51+ uint8_t shunt_lsb = SHUNT_CAL & 0xFF ;
4652 uint8_t shunt_buf [3 ] = {SHUNT_CAL_REG , shunt_msb , shunt_lsb };
4753 i2c_write_blocking (i2c_default , I2C_ADDR , shunt_buf , 3 , false);
4854
49- // Write to ADC config register (need to enable continuous mode to access accumilation variables energy and charge)
55+ // Write to ADC config register (need to enable continuous mode to access accumulation variables energy and charge)
5056 uint8_t adc_msb = 0xF0 ;
5157 uint8_t adc_lsb = 0x00 ;
5258 uint8_t adc_buf [3 ] = {ADC_CONFIG_REG , adc_msb , adc_lsb };
@@ -55,39 +61,39 @@ static void ina228_init() {
5561
5662static void ina228_read (float * vshunt , float * vbus , float * dietemp , float * current , float * power , float * energy , float * charge ) {
5763 // Buffers for writing register measurments to
58- // Some registers are 2 bytes, some are 3 bytes, the accumilation registers are 5 bytes
64+ // Some registers are 2 bytes, some are 3 bytes, the accumulation registers are 5 bytes
5965 uint8_t buffer_2 [2 ];
6066 uint8_t buffer_3 [3 ];
6167 uint8_t buffer_5 [5 ];
6268
63- // For some of the registers the 4 least significant bits are reserved and always read zero, which is why we shift right 12, 4, then left 4 for vshunt, vbus and current
69+ // For the vshunt, vbus and current registers the 4 least significant bits are reserved and always read zero, so use variant of flatten macro to extract value
6470 i2c_write_blocking (i2c_default , I2C_ADDR , & VSHUNT_REG , 1 , true);
6571 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_3 , 3 , false);
66- * vshunt = (( buffer_3 [ 0 ] << 12 ) | ( buffer_3 [ 1 ] << 4 ) | ( buffer_3 [ 2 ] >> 4 ) ) * VSHUNT_FACTOR ;
72+ * vshunt = FLATTEN3_RESERVED ( buffer_3 ) * VSHUNT_FACTOR ;
6773
6874 i2c_write_blocking (i2c_default , I2C_ADDR , & VBUS_REG , 1 , true);
6975 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_3 , 3 , false);
70- * vbus = (( buffer_3 [ 0 ] << 12 ) | ( buffer_3 [ 1 ] << 4 ) | ( buffer_3 [ 2 ] >> 4 ) ) * VBUS_FACTOR ;
76+ * vbus = FLATTEN3_RESERVED ( buffer_3 ) * VBUS_FACTOR ;
7177
7278 i2c_write_blocking (i2c_default , I2C_ADDR , & DIETEMP_REG , 1 , true);
7379 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_2 , 2 , false);
74- * dietemp = (( buffer_2 [ 0 ] << 8 ) + buffer_2 [ 1 ] ) * DIETEMP_FACTOR ;
80+ * dietemp = FLATTEN2 ( buffer_2 ) * DIETEMP_FACTOR ;
7581
7682 i2c_write_blocking (i2c_default , I2C_ADDR , & CURRENT_REG , 1 , true);
7783 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_3 , 3 , false);
78- * current = (( buffer_3 [ 0 ] << 12 ) | ( buffer_3 [ 1 ] << 4 ) | ( buffer_3 [ 2 ] >> 4 ) ) * CURRENT_FACTOR ;
84+ * current = FLATTEN3_RESERVED ( buffer_3 ) * CURRENT_FACTOR ;
7985
8086 i2c_write_blocking (i2c_default , I2C_ADDR , & POWER_REG , 1 , true);
8187 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_3 , 3 , false);
82- * power = (( buffer_3 [ 0 ] << 16 ) | ( buffer_3 [ 1 ] << 8 ) | buffer_3 [ 2 ] ) * POWER_FACTOR ;
88+ * power = FLATTEN3 ( buffer_3 ) * POWER_FACTOR ;
8389
8490 i2c_write_blocking (i2c_default , I2C_ADDR , & ENERGY_REG , 1 , true);
8591 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_5 , 5 , false);
86- * energy = ((( uint64_t ) buffer_5 [ 0 ] << 32 ) | ( buffer_5 [ 1 ] << 24 ) | ( buffer_5 [ 2 ] << 16 ) | ( buffer_5 [ 3 ] << 8 ) | buffer_5 [ 4 ] ) * ENERGY_FACTOR ;
92+ * energy = FLATTEN5 ( buffer_5 ) * ENERGY_FACTOR ;
8793
8894 i2c_write_blocking (i2c_default , I2C_ADDR , & CHARGE_REG , 1 , true);
8995 i2c_read_blocking (i2c_default , I2C_ADDR , buffer_5 , 5 , false);
90- * charge = ((( uint64_t ) buffer_5 [ 0 ] << 32 ) | ( buffer_5 [ 1 ] << 24 ) | ( buffer_5 [ 2 ] << 16 ) | ( buffer_5 [ 3 ] << 8 ) | buffer_5 [ 4 ] ) * CHARGE_FACTOR ;
96+ * charge = FLATTEN5 ( buffer_5 ) * CHARGE_FACTOR ;
9197}
9298
9399int main ()
@@ -113,7 +119,7 @@ int main()
113119
114120 while (true) {
115121 ina228_read (& vshunt , & vbus , & dietemp , & current , & power , & energy , & charge );
116- printf ("INA228 Measurments:\nVSHUNT: %f\nVBUS: %f\nDIETEMP: %f\nCURRENT: %f\nPOWER: %f\nENERGY: %.9f \nCHARGE: %.9f \n-----------------\n" , vshunt , vbus , dietemp , current , power , energy , charge );
117- sleep_ms (3000 );
122+ printf ("INA228 Measurments:\nVSHUNT: %f V \nVBUS: %f V \nDIETEMP: %f °C \nCURRENT: %f A \nPOWER: %f W \nENERGY: %f J \nCHARGE: %f C \n-----------------\n" , vshunt , vbus , dietemp , current , power , energy , charge );
123+ sleep_ms (1000 );
118124 }
119125}
0 commit comments