Mon, 03 Apr 2023 20:11:29 +0200
Changed voltage range to 32 volt. Tried INA219 powersave mode, doesn't work.
/** * @file task_ina219.c * @brief The FreeRTOS task to query the INA219 sensors. */ #include "config.h" static const char *TAG = "task_ina219"; SemaphoreHandle_t xSemaphoreINA219 = NULL; ///< Semaphore INA219 task EventGroupHandle_t xEventGroupINA219; ///< Events INA219 task INA219_State *ina219_state; ///< Public state for other tasks extern ina219_t ina219_b_dev; extern ina219_t ina219_s_dev; const int TASK_INA219_REQUEST_DONE = BIT0; ///< All requests are done. const int TASK_INA219_REQUEST_POWER = BIT1; ///< Request power readings void request_ina219(void) { xEventGroupClearBits(xEventGroupINA219, TASK_INA219_REQUEST_DONE); xEventGroupSetBits(xEventGroupINA219, TASK_INA219_REQUEST_POWER); } bool ready_ina219(void) { if (xEventGroupGetBits(xEventGroupINA219) & TASK_INA219_REQUEST_DONE) return true; return false; } /* * Task to read INA219 sensors on request. */ void task_ina219(void *pvParameter) { float bus_voltage, shunt_voltage, current, power; ESP_LOGI(TAG, "Starting task INA219 sda=%d scl=%d", CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL); ina219_state = malloc(sizeof(INA219_State)); ina219_state->Battery.valid = false; ina219_state->Battery.fake = (ina219_b_dev.i2c_dev.addr == 0) ? true:false; ina219_state->Battery.address = ina219_b_dev.i2c_dev.addr; ina219_state->Battery.error = INA219_ERR_NONE; if (ina219_b_dev.i2c_dev.addr) { ESP_LOGI(TAG, "Configuring INA219 Battery"); ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS)); ESP_LOGI(TAG, "Calibrating INA219 Battery"); ESP_ERROR_CHECK(ina219_calibrate(&ina219_b_dev, (float)I_MAX_CURRENT, (float)I_SHUNT_RESISTOR_MILLI_OHM / 1000.0f)); } ina219_state->Solar.valid = false; ina219_state->Solar.fake = (ina219_s_dev.i2c_dev.addr == 0) ? true:false; ina219_state->Solar.address = ina219_s_dev.i2c_dev.addr; ina219_state->Solar.error = INA219_ERR_NONE; if (ina219_s_dev.i2c_dev.addr) { ESP_LOGI(TAG, "Configuring INA219 Solar"); ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS)); ESP_LOGI(TAG, "Calibrating INA219 Solar"); ESP_ERROR_CHECK(ina219_calibrate(&ina219_s_dev, (float)I_MAX_CURRENT, (float)I_SHUNT_RESISTOR_MILLI_OHM / 1000.0f)); } /* event handler and event group for this task */ xEventGroupINA219 = xEventGroupCreate(); EventBits_t uxBits; /* * Task loop forever. */ ESP_LOGI(TAG, "Starting loop INA219 sensors 0x%02x %d, 0x%02x %d", ina219_state->Battery.address, ina219_state->Battery.fake, ina219_state->Solar.address, ina219_state->Solar.fake); while (1) { uxBits = xEventGroupWaitBits(xEventGroupINA219, TASK_INA219_REQUEST_POWER, pdFALSE, pdFALSE, portMAX_DELAY ); if (uxBits & TASK_INA219_REQUEST_POWER) { /* * Four scenario's: * 1. Both sensors present, just use them. * 2. Only battery sensor (test environment). Use it and fake * the solar chip as if it is charging. * 3. Only solar sensor. Use scenario 4, but show measured values. * 4. Fake everything. */ if (! ina219_state->Battery.fake) { /* * Note, on Arduino power down and resume works, but not on esp-idf. * This could save only 0.5 mA per device. */ // ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, // INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS)); ESP_ERROR_CHECK(ina219_get_bus_voltage(&ina219_b_dev, &bus_voltage)); ESP_ERROR_CHECK(ina219_get_shunt_voltage(&ina219_b_dev, &shunt_voltage)); ESP_ERROR_CHECK(ina219_get_current(&ina219_b_dev, ¤t)); ESP_ERROR_CHECK(ina219_get_power(&ina219_b_dev, &power)); // ESP_ERROR_CHECK(ina219_configure(&ina219_b_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, // INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_POWER_DOWN)); ESP_LOGI(TAG, "Battery VBUS: %.04f V, VSHUNT: %.04f mV, IBUS: %.04f mA, PBUS: %.04f mW", bus_voltage, shunt_voltage * 1000, current * 1000, power * 1000); } if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) { if (ina219_state->Battery.fake) { ina219_state->Battery.volts = 13.21; if (ready_WiFi()) { ina219_state->Battery.shunt = 0.00785; ina219_state->Battery.current = 78.5; } else { ina219_state->Battery.shunt = 0.00182; ina219_state->Battery.current = 18.2; } } else { ina219_state->Battery.volts = bus_voltage; ina219_state->Battery.shunt = shunt_voltage; ina219_state->Battery.current = current; } ina219_state->Battery.valid = true; xSemaphoreGive(xSemaphoreINA219); } if (! ina219_state->Solar.fake) { // ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, // INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_CONT_SHUNT_BUS)); ESP_ERROR_CHECK(ina219_get_bus_voltage(&ina219_s_dev, &bus_voltage)); ESP_ERROR_CHECK(ina219_get_shunt_voltage(&ina219_s_dev, &shunt_voltage)); ESP_ERROR_CHECK(ina219_get_current(&ina219_s_dev, ¤t)); ESP_ERROR_CHECK(ina219_get_power(&ina219_s_dev, &power)); // ESP_ERROR_CHECK(ina219_configure(&ina219_s_dev, INA219_BUS_RANGE_32V, INA219_GAIN_0_125, // INA219_RES_12BIT_1S, INA219_RES_12BIT_1S, INA219_MODE_POWER_DOWN)); ESP_LOGI(TAG, " Solar VBUS: %.04f V, VSHUNT: %.04f mV, IBUS: %.04f mA, PBUS: %.04f mW", bus_voltage, shunt_voltage * 1000, current * 1000, power * 1000); } if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) { if (! ina219_state->Solar.fake && ! ina219_state->Battery.fake) { ina219_state->Solar.volts = bus_voltage; ina219_state->Solar.shunt = shunt_voltage; ina219_state->Solar.current = current; } else if (ina219_state->Solar.fake && ! ina219_state->Battery.fake) { ina219_state->Solar.volts = ina219_state->Battery.volts + 0.78; ina219_state->Solar.shunt = 0.02341; ina219_state->Solar.current = 234.1; } else { ina219_state->Solar.volts = 13.98; ina219_state->Solar.shunt = 0.02341; ina219_state->Solar.current = 234.1; } ina219_state->Solar.valid = true; /* * Now update the outer state */ ina219_state->valid = (ina219_state->Battery.valid && ina219_state->Solar.valid); ina219_state->fake = (ina219_state->Battery.fake || ina219_state->Solar.fake); ina219_state->error = ina219_state->Battery.error; if (ina219_state->error == 0) ina219_state->error = ina219_state->Solar.error; xSemaphoreGive(xSemaphoreINA219); } xEventGroupClearBits(xEventGroupINA219, TASK_INA219_REQUEST_POWER); xEventGroupSetBits(xEventGroupINA219, TASK_INA219_REQUEST_DONE); } } }