Added begin of INA219 measurements. Added raw main state table.

Tue, 28 Mar 2023 22:13:06 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 28 Mar 2023 22:13:06 +0200
changeset 3
e5d91caa6ab4
parent 2
3462a53e548f
child 4
d0155c16e992

Added begin of INA219 measurements. Added raw main state table.

main/CMakeLists.txt file | annotate | diff | comparison | revisions
main/config.c file | annotate | diff | comparison | revisions
main/config.h file | annotate | diff | comparison | revisions
main/iotbalkon.c file | annotate | diff | comparison | revisions
main/task_ina219.c file | annotate | diff | comparison | revisions
main/task_ina219.h file | annotate | diff | comparison | revisions
--- a/main/CMakeLists.txt	Tue Mar 28 11:25:46 2023 +0200
+++ b/main/CMakeLists.txt	Tue Mar 28 22:13:06 2023 +0200
@@ -1,2 +1,2 @@
-idf_component_register(SRCS config.c iotbalkon.c task_bmp280.c
+idf_component_register(SRCS config.c iotbalkon.c task_bmp280.c task_ina219.c
                     INCLUDE_DIRS ".")
--- a/main/config.c	Tue Mar 28 11:25:46 2023 +0200
+++ b/main/config.c	Tue Mar 28 22:13:06 2023 +0200
@@ -7,4 +7,6 @@
 bmp280_params_t         bmp280_params;
 bmp280_t                bmp280_dev;
 
+ina219_t		ina219_b_dev;
+ina219_t		ina219_s_dev;
 
--- a/main/config.h	Tue Mar 28 11:25:46 2023 +0200
+++ b/main/config.h	Tue Mar 28 22:13:06 2023 +0200
@@ -48,11 +48,13 @@
  */
 #include <i2cdev.h>
 #include <bmp280.h>
+#include <ina219.h>
 
 /*
  * Application sources
  */
 #include "task_bmp280.h"
+#include "task_ina219.h"
 //#include "task_wifi.h"
 //#include "task_mqtt.h"
 //#include "task_user.h"
--- a/main/iotbalkon.c	Tue Mar 28 11:25:46 2023 +0200
+++ b/main/iotbalkon.c	Tue Mar 28 22:13:06 2023 +0200
@@ -7,13 +7,27 @@
 
 static const char *TAG = "iotbalkon";
 
+#define State_Init       0
+#define State_Connect    1
+#define State_Working    2
+#define State_WorkDone   3
+#define State_Stop       4
+#define State_Wait       5
+#define State_Measure    6
+#define State_GoSleep    7
+
 
 static TaskHandle_t			xTaskBMP280 = NULL;
+static TaskHandle_t			xTaskINA219 = NULL;
+
 
 extern BMP280_State			*bmp280_state;			///< I2C state
 extern SemaphoreHandle_t		xSemaphoreBMP280;		///< I2C lock semaphore
 extern bmp280_params_t			bmp280_params;
 extern bmp280_t				bmp280_dev;
+extern SemaphoreHandle_t		xSemaphoreINA219;
+extern ina219_t				ina219_b_dev;
+extern ina219_t				ina219_s_dev;
 
 
 void app_main(void)
@@ -29,6 +43,8 @@
 
     bmp280_init_default_params(&bmp280_params);
     memset(&bmp280_dev, 0, sizeof(bmp280_t));
+    memset(&ina219_b_dev, 0, sizeof(ina219_t));
+    memset(&ina219_s_dev, 0, sizeof(ina219_t));
 
     i2c_dev_t dev = { 0 };
     dev.cfg.sda_io_num = CONFIG_I2C_MASTER_SDA;
@@ -41,10 +57,14 @@
     }
     dev.addr = 0x40;
     if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
+	ESP_ERROR_CHECK(ina219_init_desc(&ina219_b_dev, 0x40, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
+	ESP_ERROR_CHECK(ina219_init(&ina219_b_dev));
 	ESP_LOGI(TAG, "Found INA219 Battery");
     }
     dev.addr = 0x41;
     if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
+	ESP_ERROR_CHECK(ina219_init_desc(&ina219_s_dev, 0x41, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
+	ESP_ERROR_CHECK(ina219_init(&ina219_s_dev));
         ESP_LOGI(TAG, "Found INA219 Solar");
     }
     dev.addr = 0x76;
@@ -52,10 +72,13 @@
 	ESP_ERROR_CHECK(bmp280_init_desc(&bmp280_dev, BMP280_I2C_ADDRESS_0, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
 	ESP_ERROR_CHECK(bmp280_init(&bmp280_dev, &bmp280_params));
 	ESP_LOGI(TAG, "Found BMP280 @ 0x76 id: 0x%02x", bmp280_dev.id);
-    }
-    dev.addr = 0x77;
-    if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
-        ESP_LOGI(TAG, "Found BMP280 @ 0x77");
+    } else {
+    	dev.addr = 0x77;
+    	if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
+	    ESP_ERROR_CHECK(bmp280_init_desc(&bmp280_dev, BMP280_I2C_ADDRESS_1, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
+	    ESP_ERROR_CHECK(bmp280_init(&bmp280_dev, &bmp280_params));
+            ESP_LOGI(TAG, "Found BMP280 @ 0x77 id: 0x%02x", bmp280_dev.id);
+    	}
     }
 
     /*
@@ -64,13 +87,238 @@
     xSemaphoreBMP280 = xSemaphoreCreateMutex();
 
     xTaskCreate(&task_bmp280,     "task_bmp280",      2560, NULL, 8, &xTaskBMP280);
+    xTaskCreate(&task_ina219,     "task_ina219",      2560, NULL, 8, &xTaskINA219);
 
     /*
      * Main application loop.
      */
+    int State = State_Init;
+    int OldState = State_Init + 1;
+
     while (1) {
-	request_bmp280();
-        vTaskDelay(2000 / portTICK_PERIOD_MS);
+	if (OldState != State) {
+	    ESP_LOGI(TAG, "Switch to state %d", State);
+	    OldState = State;
+	}
+	switch (State) {
+	    case State_Init:		request_bmp280();
+        				request_ina219();
+		    			// getTempBaro();
+					// getLightValues();
+					// getVoltsCurrent();
+					State = State_Connect;
+		    			break;
+
+	    case State_Connect:		// Wake WiFi ??
+					// if (NetworkConnect()) {
+					//   State = State_Working;
+					//   Alarm &= ~AL_NOWIFI;
+					//   DisCounter = 0;
+					// } else {
+					//   DisCounter++;
+					//   if (DisCounter > 30) {
+					//     Alarm |= AL_NOWIFI;
+					//   }
+					//   delay(2000);
+					// }
+					break;
+
+	    case State_Working:		// WorkAgain = false;
+      					// client.loop();
+
+      					// // Measure
+      					// getVoltsCurrent();
+      					// solarVolts = solarCurrent = batteryVolts = batteryCurrent = 0;
+      					// loops = 0;
+      					// totalTime = 0;
+      					// for (int i = 0; i < loopno; i++) {
+	      				    /*
+    					     * If there are only 2 loops, and the flag that we came from deep-sleep is set
+    					     * then assume the following:
+   					     *   1. No current (or very low for the dc converter) during DS_TIME seconds.
+    					     *   2. Low power during 0.5 second (no WiFi yet).
+    					     *   3. 5 seconds power usage for the last measurement.
+    					     * Calculate the average battery current from this.
+    					     *
+    					     * If there are more loops and we came from continues running do the following:
+    					     *   1. Take the current use from all exept the last one, weight loops * 10 seconds.
+    					     *   2. Take the last one, and weight for 5 seconds.
+    					     * Calculate the average battery current from this.
+    					     */
+					//      if (m_Valid[i]) {
+          				//	solarVolts += s_Volts[i];
+          				//	solarCurrent += s_Current[i];
+          				//	batteryVolts += b_Volts[i];
+          				//	if (i == (loopno - 1)) {
+          				//	  // Add the extra time
+          				//	  m_Time[i] += SUB_TIME;
+          				//	}
+          				//	batteryCurrent += b_Current[i] * m_Time[i];
+          				//	totalTime += m_Time[i];
+          				//	loops++;
+        				//  	}
+      					//  }
+
+      					// if (EEPROM.read(EM_DS_Active)) {
+        				//    totalTime += EEPROM.read(EM_DS_Time) * 1000;
+        				//    batteryCurrent += DS_CURRENT * EEPROM.read(EM_DS_Time) * 1000;
+					//    //        Serial.printf("Added %d totalTime %d\n", EEPROM.read(EM_DS_Time) * 1000, totalTime);
+      					// }
+
+      					// If valid measurements
+      					// if (loops) {
+        				//    solarVolts = solarVolts / loops;
+        				//    solarCurrent = solarCurrent / loops;
+        				//    solarPower = solarVolts * solarCurrent;
+       					//    batteryVolts = batteryVolts / loops;
+        				//    batteryCurrent = batteryCurrent / totalTime;
+        				//    batteryPower = batteryVolts * batteryCurrent;
+        				//    BatteryState(batteryVolts, (0 - batteryCurrent) + solarCurrent);
+
+        				//    //#if Debug == true
+        				//    Serial.print(F("  Solar Volts: "));
+        				//    Serial.print(solarVolts, 4);
+        				//    Serial.print(F("V  Current: "));
+        				//    Serial.print(solarCurrent, 4);
+        				//    Serial.print(F("mA  Power: "));
+        				//    Serial.print(solarPower, 4);
+        				//    Serial.println(F("mW"));
+
+					//    Serial.print(F("Battery Volts: "));
+        				//    Serial.print(batteryVolts, 4);
+        				//    Serial.print(F("V  Current: "));
+        				//    Serial.print(batteryCurrent, 4);
+        				//    Serial.print(F("mA  Power: "));
+        				//    Serial.print(batteryPower, 4);
+        				//    Serial.print(F("mW  Capacity "));
+        				//    Serial.print(batteryState);
+        				//    Serial.println(F("%"));
+        				//    //#endif
+
+        				/*   Check alarm conditions */
+        				//   if (batteryState <= 10) {
+        				//     Alarm |= AL_ACCULOW;
+        				//   } else {
+        				//     Alarm &= ~AL_ACCULOW;
+        				//   }
+      					// }
+      					// getTempHumi();
+      					// Publish();
+      					// Subscribe
+					// #if Production == true
+      					// client.subscribe("balkon/output/set/#");
+					// #else
+      					// client.subscribe("wemos/output/set/#");
+					// #endif
+      					// client.loop();
+      					// State = State_WorkDone;
+      					// gTimeNext = millis() + SUB_TIME;
+					break;
+
+	    case State_WorkDone:	// Hang around for a while to process the subscriptions.
+					// client.loop();
+      					// delay(1);
+      					// if (WorkAgain) {
+        				//    // Some command was executed.
+        				//    State = State_Working;
+      					// }
+      					// if (gTimeInMillis > gTimeNext) {
+        				//    State = State_Stop;
+      					// }
+					break;
+
+	    case State_Stop:		// #if Production == true
+      					// client.unsubscribe("balkon/output/set/#");
+					// #else
+      					// client.unsubscribe("wemos/output/set/#");
+					// #endif
+      					// delay(1);
+      					// client.loop();
+      					// client.disconnect();
+      					// delay(1);
+      					// WiFi.mode( WIFI_OFF );
+      					// // Reset values for average current measurement.
+      					// HaveIP = false;
+      					// loopno = 0;
+      					// gLastTime = millis();
+      					// delay(10);
+					// #if defined(ARDUINO_ESP8266_WEMOS_D1MINI)
+      					// WiFi.forceSleepBegin(0);  // 0 == forever
+					// #endif
+
+					/*
+      					 *  If any output is on, use 6 10 seconds loops.
+      					 *  If nothing on, do a deep sleep.
+      					 */
+					// if (EEPROM.read(EM_Relay1) || EEPROM.read(EM_Relay2) || EEPROM.read(EM_Dimmer3) || EEPROM.read(EM_Dimmer4)) {
+        				//    if (EEPROM.read(EM_DS_Active)) {
+          				//	EEPROM.write(EM_DS_Active, 0);
+          				//	EEPROM.commit();
+        				//    }
+
+        				//    // Active mode, 60 seconds loop
+        				//    ST_LOOPS = 6;
+        				//    gTimeNext = millis() + ST_INTERVAL;
+					//    #if Debug == true
+        				//    Serial.println(F("Start sleeploops"));
+					//    #endif
+        				//    State = State_Wait;
+      					// } else {
+					//    ds_time = DS_TIME;
+        				//    if (solarVolts < 6) {
+          				//      // At night, increase the deep-sleep time.
+          				//	ds_time *= 4;
+        				//    }
+        				//    if ((! EEPROM.read(EM_DS_Active)) || (EEPROM.read(EM_DS_Time) != ds_time)) {
+          				//      EEPROM.write(EM_DS_Active, 1);
+          				//      EEPROM.write(EM_DS_Time, ds_time);
+          				//      EEPROM.commit();
+          				//      Serial.println("wrote new deep-sleep settings");
+        				//    }
+        				//    State = State_GoSleep;
+      					// }
+      					/*
+      					 * Update CRC and write rtcData.
+      					 */
+      					// rtcData.crc32 = calculateCRC32((uint8_t*) &rtcData.data, sizeof(rtcData)-4);
+					// #if defined(ARDUINO_ESP8266_WEMOS_D1MINI)
+      					// if (ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData))) {
+					// #if Debug == true
+        				//    Serial.print("Write: ");
+        				//    printMemory();
+					// #endif
+      					// } else {
+        				//    Serial.println("Write error rtcData");
+      					// }
+					// #endif
+					break;
+
+	    case State_Wait:		// if (gTimeInMillis > gTimeNext) {
+      					//   State = State_Measure;
+      					// }
+					break;
+
+	    case State_Measure:		// getVoltsCurrent();
+					// if (isnan(Temperature)) {
+      					//   getTempHumi();
+      					// }
+      					// gTimeNext = millis() + ST_INTERVAL;
+      					// if (loopno >= ST_LOOPS) {
+        				//    getLightValues();
+        				//    State = State_Connect;
+      					// } else {
+        				//    State = State_Wait;
+      					// }
+					break;
+
+	    case State_GoSleep:		// ds_time = EEPROM.read(EM_DS_Time);
+					// #if Debug == true
+      					// Serial.printf("Going to deep-sleep for %d seconds\n", ds_time);
+					// #endif
+      					// ESP.deepSleep(ds_time * 1e6);
+					break;
+	}
+        vTaskDelay(20 / portTICK_PERIOD_MS);
     }
     // Not reached.
 }
--- /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
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/task_ina219.h	Tue Mar 28 22:13:06 2023 +0200
@@ -0,0 +1,77 @@
+/**
+ * @file task_ina219.h
+ * @brief The FreeRTOS task to query the INA219 sensors connected to
+ *        the I2C bus.
+ *        The task will update the sensor state structures.
+ */
+
+#ifndef	_TASK_INA219_H
+#define	_TASK_INA219_H
+
+/*
+ * Error codes in this task
+ */
+#define	INA219_ERR_NONE			0	///< No errors
+#define INA219_ERR_READ			1
+
+#define	I_MAX_LOOPS			32
+#define	I_MAX_CURRENT			5	///< Max 5 Ampere
+#define	I_SHUNT_RESISTOR_MILLI_OHM	100	///< Shunt value
+
+
+typedef struct {
+    bool		valid;			///< Valid measurement
+    bool		fake;			///< Fake measurement
+    uint8_t		address;		///< Device i2c address
+    float		shunt;			///< Shunt voltage
+    float		volts;			///< Bus voltage
+    float		current;		///< Current mA
+    int			error;			///< Error result
+} INA219_tt;
+
+
+/**
+ * @brief Structure containing the variables for the INA219 task.
+ */
+typedef struct {
+    bool		valid;			///< Valid measurement
+    bool		fake;			///< Fake measurement
+    INA219_tt		Battery;		///< Battery measurement
+    INA219_tt		Solar;			///< Solar measurement
+    float		s_Volts[I_MAX_LOOPS];
+    float		s_Current[I_MAX_LOOPS];
+    float		b_Volts[I_MAX_LOOPS];
+    float		b_Current[I_MAX_LOOPS];
+    bool		m_Valid[I_MAX_LOOPS];
+    time_t		m_Time[I_MAX_LOOPS];
+    time_t		gLastTime;
+    uint8_t		loopno;
+    uint8_t		loops;
+    uint8_t		tries;
+    int			error;			///< Error result
+} INA219_State;
+
+
+
+/**
+ * @brief Request a new measurement from selected sensors.
+ */
+void request_ina219(void);
+
+
+/**
+ * @brief Check if results are ready
+ * @return true of results are ready, else false.
+ */
+bool ready_ina219(void);
+
+
+/**
+ * @brief The FreeRTOS task to update the INA219 on request.
+ * @param pvParameters Parameters for the task.
+ */
+void task_ina219(void *pvParameters);
+
+
+#endif
+

mercurial