main/task_ina219.c

changeset 34
40231d010111
parent 30
7448b8dd4288
equal deleted inserted replaced
33:5bd5f6668f71 34:40231d010111
6 6
7 #include "config.h" 7 #include "config.h"
8 8
9 9
10 static const char *TAG = "task_ina219"; 10 static const char *TAG = "task_ina219";
11
12 /*
13 * Global settings for the INA219 boards.
14 */
15 #define BUS_RANGE INA219_BUS_RANGE_32V
16 #define GAIN_SHUNT INA219_GAIN_0_125
17 #define U_RES INA219_RES_12BIT_4S
18 #define I_RES INA219_RES_12BIT_2S
11 19
12 SemaphoreHandle_t xSemaphoreINA219 = NULL; ///< Semaphore INA219 task 20 SemaphoreHandle_t xSemaphoreINA219 = NULL; ///< Semaphore INA219 task
13 EventGroupHandle_t xEventGroupINA219; ///< Events INA219 task 21 EventGroupHandle_t xEventGroupINA219; ///< Events INA219 task
14 INA219_State *ina219_state; ///< Public state for other tasks 22 INA219_State *ina219_state; ///< Public state for other tasks
15 23
52 ina219_state->Battery.fake = (ina219_b_dev.i2c_dev.addr == 0) ? true:false; 60 ina219_state->Battery.fake = (ina219_b_dev.i2c_dev.addr == 0) ? true:false;
53 ina219_state->Battery.address = ina219_b_dev.i2c_dev.addr; 61 ina219_state->Battery.address = ina219_b_dev.i2c_dev.addr;
54 ina219_state->Battery.error = INA219_ERR_NONE; 62 ina219_state->Battery.error = INA219_ERR_NONE;
55 if (ina219_b_dev.i2c_dev.addr) { 63 if (ina219_b_dev.i2c_dev.addr) {
56 ESP_LOGI(TAG, "Configuring INA219 Battery"); 64 ESP_LOGI(TAG, "Configuring INA219 Battery");
57 ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, 65 ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, BUS_RANGE, GAIN_SHUNT, U_RES, I_RES, INA219_MODE_CONT_SHUNT_BUS));
58 INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS));
59 ESP_LOGI(TAG, "Calibrating INA219 Battery"); 66 ESP_LOGI(TAG, "Calibrating INA219 Battery");
60 ESP_ERROR_CHECK(ina219_calibrate(&ina219_b_dev, (float)I_MAX_CURRENT, (float)I_SHUNT_RESISTOR_MILLI_OHM / 1000.0f)); 67 ESP_ERROR_CHECK(ina219_calibrate(&ina219_b_dev, (float)I_MAX_CURRENT, (float)I_SHUNT_RESISTOR_MILLI_OHM / 1000.0f));
61 } 68 }
62 69
63 ina219_state->Solar.valid = false; 70 ina219_state->Solar.valid = false;
64 ina219_state->Solar.fake = (ina219_s_dev.i2c_dev.addr == 0) ? true:false; 71 ina219_state->Solar.fake = (ina219_s_dev.i2c_dev.addr == 0) ? true:false;
65 ina219_state->Solar.address = ina219_s_dev.i2c_dev.addr; 72 ina219_state->Solar.address = ina219_s_dev.i2c_dev.addr;
66 ina219_state->Solar.error = INA219_ERR_NONE; 73 ina219_state->Solar.error = INA219_ERR_NONE;
67 if (ina219_s_dev.i2c_dev.addr) { 74 if (ina219_s_dev.i2c_dev.addr) {
68 ESP_LOGI(TAG, "Configuring INA219 Solar"); 75 ESP_LOGI(TAG, "Configuring INA219 Solar");
69 ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, 76 ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, BUS_RANGE, GAIN_SHUNT, U_RES, I_RES, INA219_MODE_CONT_SHUNT_BUS));
70 INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS));
71 ESP_LOGI(TAG, "Calibrating INA219 Solar"); 77 ESP_LOGI(TAG, "Calibrating INA219 Solar");
72 ESP_ERROR_CHECK(ina219_calibrate(&ina219_s_dev, (float)I_MAX_CURRENT, (float)I_SHUNT_RESISTOR_MILLI_OHM / 1000.0f)); 78 ESP_ERROR_CHECK(ina219_calibrate(&ina219_s_dev, (float)I_MAX_CURRENT, (float)I_SHUNT_RESISTOR_MILLI_OHM / 1000.0f));
73 } 79 }
74 80
75 /* event handler and event group for this task */ 81 /* event handler and event group for this task */
84 while (1) { 90 while (1) {
85 91
86 uxBits = xEventGroupWaitBits(xEventGroupINA219, TASK_INA219_REQUEST_POWER, pdFALSE, pdFALSE, portMAX_DELAY ); 92 uxBits = xEventGroupWaitBits(xEventGroupINA219, TASK_INA219_REQUEST_POWER, pdFALSE, pdFALSE, portMAX_DELAY );
87 93
88 if (uxBits & TASK_INA219_REQUEST_POWER) { 94 if (uxBits & TASK_INA219_REQUEST_POWER) {
95 /*
96 * We run the ESP32-C3 in Power Save mode, Dynamic Frequency Scaling.
97 * This means a wrong current measurement (too high) unless we let the CPU
98 * rest for a while. The INA219 runs in continuous mode so we get the
99 * results during the vTaskDelay().
100 * We also run the INA219 boards in standby/power-on mode, so first turn
101 * them on.
102 */
103 if (! ina219_state->Battery.fake)
104 ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, BUS_RANGE, GAIN_SHUNT, U_RES, I_RES, INA219_MODE_CONT_SHUNT_BUS));
105 if (! ina219_state->Solar.fake)
106 ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, BUS_RANGE, GAIN_SHUNT, U_RES, I_RES, INA219_MODE_CONT_SHUNT_BUS));
107 vTaskDelay(20 / portTICK_PERIOD_MS);
89 108
90 /* 109 /*
91 * Four scenario's: 110 * Four scenario's:
92 * 1. Both sensors present, just use them. 111 * 1. Both sensors present, just use them.
93 * 2. Only battery sensor (test environment). Use it and fake 112 * 2. Only battery sensor (test environment). Use it and fake
94 * the solar chip as if it is charging. 113 * the solar chip as if it is charging.
95 * 3. Only solar sensor. Use scenario 4, but show measured values. 114 * 3. Only solar sensor. Use scenario 4, but show measured values.
96 * 4. Fake everything. 115 * 4. Fake everything.
97 */ 116 */
98 if (! ina219_state->Battery.fake) { 117 if (! ina219_state->Battery.fake) {
99 /*
100 * We run the ESP32-C3 in Power Save mode, Dynamic Frequency Scaling.
101 * This means a wrong current measurement (too high) unless we let the CPU
102 * rest for a while. The INA219 runs in continuous mode so we get the
103 * results during the vTaskDelay().
104 */
105 ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125,
106 INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS));
107 vTaskDelay(20 / portTICK_PERIOD_MS);
108 ESP_ERROR_CHECK(ina219_get_bus_voltage(&ina219_b_dev, &bus_voltage)); 118 ESP_ERROR_CHECK(ina219_get_bus_voltage(&ina219_b_dev, &bus_voltage));
109 vTaskDelay(10 / portTICK_PERIOD_MS); 119 vTaskDelay(10 / portTICK_PERIOD_MS);
110 ESP_ERROR_CHECK(ina219_get_shunt_voltage(&ina219_b_dev, &shunt_voltage)); 120 ESP_ERROR_CHECK(ina219_get_shunt_voltage(&ina219_b_dev, &shunt_voltage));
111 /* 121 /*
112 * We don't call ina219_get_current(&ina219_b_dev, &current) because it takes 122 * We don't call ina219_get_current(&ina219_b_dev, &current) because it takes
113 * a new measurement which usual gives the same results as the shunt voltage. 123 * a new measurement which usual gives the same results as the shunt voltage.
114 * So just calculate the current. 124 * So just calculate the current.
115 */ 125 */
116 ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, 126 ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, BUS_RANGE, GAIN_SHUNT, U_RES, I_RES, INA219_MODE_POWER_DOWN));
117 INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_POWER_DOWN));
118 ESP_LOGI(TAG, "Battery VBUS: %.03f V, VSHUNT: %.02f mV, IBUS: %.01f mA", bus_voltage, shunt_voltage * 1000, shunt_voltage * 10000); 127 ESP_LOGI(TAG, "Battery VBUS: %.03f V, VSHUNT: %.02f mV, IBUS: %.01f mA", bus_voltage, shunt_voltage * 1000, shunt_voltage * 10000);
119 } 128 }
120 if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) { 129 if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) {
121 if (ina219_state->Battery.fake) { 130 if (ina219_state->Battery.fake) {
122 ina219_state->Battery.volts = 13.21; 131 ina219_state->Battery.volts = 13.21;
135 ina219_state->Battery.valid = true; 144 ina219_state->Battery.valid = true;
136 xSemaphoreGive(xSemaphoreINA219); 145 xSemaphoreGive(xSemaphoreINA219);
137 } 146 }
138 147
139 if (! ina219_state->Solar.fake) { 148 if (! ina219_state->Solar.fake) {
140 ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125,
141 INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS));
142 vTaskDelay(20 / portTICK_PERIOD_MS);
143 ESP_ERROR_CHECK(ina219_get_bus_voltage(&ina219_s_dev, &bus_voltage)); 149 ESP_ERROR_CHECK(ina219_get_bus_voltage(&ina219_s_dev, &bus_voltage));
144 vTaskDelay(10 / portTICK_PERIOD_MS); 150 vTaskDelay(10 / portTICK_PERIOD_MS);
145 ESP_ERROR_CHECK(ina219_get_shunt_voltage(&ina219_s_dev, &shunt_voltage)); 151 ESP_ERROR_CHECK(ina219_get_shunt_voltage(&ina219_s_dev, &shunt_voltage));
146 ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, 152 ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, BUS_RANGE, GAIN_SHUNT, U_RES, I_RES, INA219_MODE_POWER_DOWN));
147 INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_POWER_DOWN));
148 ESP_LOGI(TAG, " Solar VBUS: %.03f V, VSHUNT: %.02f mV, IBUS: %.01f mA", bus_voltage, shunt_voltage * 1000, shunt_voltage * 10000); 153 ESP_LOGI(TAG, " Solar VBUS: %.03f V, VSHUNT: %.02f mV, IBUS: %.01f mA", bus_voltage, shunt_voltage * 1000, shunt_voltage * 10000);
149 } 154 }
150 if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) { 155 if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) {
151 if (! ina219_state->Solar.fake && ! ina219_state->Battery.fake) { 156 if (! ina219_state->Solar.fake && ! ina219_state->Battery.fake) {
152 ina219_state->Solar.volts = bus_voltage; 157 ina219_state->Solar.volts = bus_voltage;

mercurial