main/task_ina219.c

changeset 3
e5d91caa6ab4
child 5
b1f38105ca7e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/task_ina219.c	Tue Mar 28 22:13:06 2023 +0200
@@ -0,0 +1,153 @@
+/**
+ * @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)
+{
+    int		error = 0;
+    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_16V, 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_16V, 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) {
+		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, &current));
+		ESP_ERROR_CHECK(ina219_get_power(&ina219_b_dev, &power));
+		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 (! ina219_state->Solar.fake) {
+                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, &current));
+                ESP_ERROR_CHECK(ina219_get_power(&ina219_s_dev, &power));
+                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);
+	    }
+
+	    /*
+		error = ina219_read_float(&ina219_dev, &temperature, &pressure, &humidity);
+		if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) {
+		    if (error == ESP_OK) {
+			ina219_state->error = INA219_ERR_NONE;
+			ina219_state->valid = true;
+			ina219_state->temperature = temperature;
+			ina219_state->pressure = pressure;
+			ina219_state->humidity = humidity;
+		    } else {
+			ina219_state->error = INA219_ERR_READ;
+			ina219_state->valid = false;
+			ina219_state->temperature = 0;
+			ina219_state->pressure = 0;
+			ina219_state->humidity = 0;
+		    }
+		    xSemaphoreGive(xSemaphoreINA219);
+		}
+	    } else {
+		if (xSemaphoreTake(xSemaphoreINA219, 25) == pdTRUE) {
+		    ina219_state->error = INA219_ERR_NONE;
+                    ina219_state->valid = true;
+		    ina219_state->temperature = 21.23;
+                    ina219_state->pressure = 101360;
+                    ina219_state->humidity = 0;
+		    xSemaphoreGive(xSemaphoreINA219);
+		}
+	    }
+
+	    */
+	    xEventGroupClearBits(xEventGroupINA219, TASK_INA219_REQUEST_POWER);
+	    xEventGroupSetBits(xEventGroupINA219, TASK_INA219_REQUEST_DONE);
+#if 0
+	    ESP_LOGI(TAG, "  TB: %.3f C, %.1f hPa, error: %d", ina219_state->temperature, ina219_state->pressure / 100, ina219_state->error);
+#endif
+	}
+    }
+}

mercurial