6
6
// LED GPIOs
7
7
#define EXT_LED_GPIO 2
8
8
9
- // INA228 integrated shunt resistance
9
+ // INA228 integrated shunt resistance in Ohms
10
10
#define R_SHUNT 0.015
11
11
12
- // Max expected current through shunt resistor
12
+ // Max expected current through shunt resistor in Amps
13
13
#define MAX_EXPECTED_CURRENT 0.1
14
14
#define I2C_ADDR 0x40
15
15
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
+
16
22
// ina228 registers (see datasheet)
17
23
uint8_t VSHUNT_REG = 0x04 ;
18
24
uint8_t VBUS_REG = 0x05 ;
@@ -42,11 +48,11 @@ float vshunt, vbus, dietemp, current, power, energy, charge;
42
48
static void ina228_init () {
43
49
// Write to shunt register
44
50
uint8_t shunt_msb = (SHUNT_CAL >> 8 ) & 0xFF ;
45
- uint8_t shunt_lsb = SHUNT_CAL & 0xff ;
51
+ uint8_t shunt_lsb = SHUNT_CAL & 0xFF ;
46
52
uint8_t shunt_buf [3 ] = {SHUNT_CAL_REG , shunt_msb , shunt_lsb };
47
53
i2c_write_blocking (i2c_default , I2C_ADDR , shunt_buf , 3 , false);
48
54
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)
50
56
uint8_t adc_msb = 0xF0 ;
51
57
uint8_t adc_lsb = 0x00 ;
52
58
uint8_t adc_buf [3 ] = {ADC_CONFIG_REG , adc_msb , adc_lsb };
@@ -55,39 +61,39 @@ static void ina228_init() {
55
61
56
62
static void ina228_read (float * vshunt , float * vbus , float * dietemp , float * current , float * power , float * energy , float * charge ) {
57
63
// 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
59
65
uint8_t buffer_2 [2 ];
60
66
uint8_t buffer_3 [3 ];
61
67
uint8_t buffer_5 [5 ];
62
68
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
64
70
i2c_write_blocking (i2c_default , I2C_ADDR , & VSHUNT_REG , 1 , true);
65
71
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 ;
67
73
68
74
i2c_write_blocking (i2c_default , I2C_ADDR , & VBUS_REG , 1 , true);
69
75
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 ;
71
77
72
78
i2c_write_blocking (i2c_default , I2C_ADDR , & DIETEMP_REG , 1 , true);
73
79
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 ;
75
81
76
82
i2c_write_blocking (i2c_default , I2C_ADDR , & CURRENT_REG , 1 , true);
77
83
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 ;
79
85
80
86
i2c_write_blocking (i2c_default , I2C_ADDR , & POWER_REG , 1 , true);
81
87
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 ;
83
89
84
90
i2c_write_blocking (i2c_default , I2C_ADDR , & ENERGY_REG , 1 , true);
85
91
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 ;
87
93
88
94
i2c_write_blocking (i2c_default , I2C_ADDR , & CHARGE_REG , 1 , true);
89
95
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 ;
91
97
}
92
98
93
99
int main ()
@@ -113,7 +119,7 @@ int main()
113
119
114
120
while (true) {
115
121
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 );
118
124
}
119
125
}
0 commit comments