Zephyr INA219 driver not transmitting any I2C

Hi,

I am going through various sensors on my custom board and integrating them one by one. I've got "i2c0" peripheral setup and can talk with BME680, LIS2DS12 no problem. I am having some issues with LIS2DS12 but I am not troubleshooting it yet.

What is strange, is that the thread that is requesting data from the INA219 run, but I see no I2C traces using my logic analyser. I can see I2C traffic for the BME680 and LIS2DS12, so I should see the INA219 since they are all on the same bus.

I have ruled out these issues:

- Physical connection. Yes it exists, I've "beeped it out", but not really relevant since I don't see trace on LA.

- Device address - not relevant since I cannot even see the I2C traces on the logic analyser.

- Thread starvation - the thread never runs. It does, I've used Debugger to confirm that it is executing.

- Error from Zephyr - could be, but I am logging the response from "sensor_channel_get" and it always returns 0. 

- Device is not ready - it is, I see no error log that it is not ready.

- DTS config is incorrect - I took DTS config directly from the zephyr/samples/sensors/ina219 project in v2.2.0 Nordic SDK

Here is my .overlay which works for the BME680 and LIS2DS12, but not INA219

&i2c0 {
    compatible = "nordic,nrf-twim";
    status = "okay";
    pinctrl-0 = <&i2c0_default>;
    pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
    
    ina219: ina219@40 {
        status = "okay";
		compatible = "ti,ina219";
		reg = <0x40>;
		brng = <0>;
		pg = <0>;
		sadc = <13>;
		badc = <13>;
		shunt-milliohm = <100>;
		lsb-microamp = <10>;
	};

    kt2027ewe: kt2027ewe@30{
        compatible = "i2c-device";
        reg = <0x30>;
    };

    kt2027bewe: kt2027bewe@31{
        compatible = "i2c-device";
        reg = <0x31>;
    };

    bme680: bme680@76 {
        compatible = "bosch,bme680";
        reg = <0x76>;
    };

    lis2ds12: lis2ds12@1e {
        compatible = "st,lis2ds12";
        reg = <0x1E>;
        irq-gpios = < &gpio0 7 GPIO_ACTIVE_HIGH>,<&gpio0 31 GPIO_ACTIVE_HIGH>;
    };
};

Here is the code that is supposed to fetch data from INA219. You will see that it is almost the same as sample code + use of thread in Zephyr.

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/printk.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/sensor.h>

#include "hw_pwr_monitor.h"

LOG_MODULE_REGISTER(pwr_monitor, LOG_LEVEL_DBG);

const struct device *pwr_mon_i2c = DEVICE_DT_GET_ONE(ti_ina219);
struct sensor_value v_bus, power, current;

static void fetch_and_display(const struct device *sensor)
{
	int ret = sensor_channel_get(pwr_mon_i2c, SENSOR_CHAN_VOLTAGE, &v_bus);

    if(ret > 0)
    {
        LOG_ERR("Failed to retrieve Voltage from %s",pwr_mon_i2c->name);
    }

    ret = sensor_channel_get(pwr_mon_i2c, SENSOR_CHAN_POWER, &power);
    if(ret > 0)
    {
        LOG_ERR("Failed to retrieve Power from %s",pwr_mon_i2c->name);
    }

    ret = sensor_channel_get(pwr_mon_i2c, SENSOR_CHAN_CURRENT, &current);
    if(ret > 0)
    {
        LOG_ERR("Failed to retrieve Current from %s",pwr_mon_i2c->name);
    }

    LOG_INF("Bus: %f [V] -- "
        "Power: %f [W] -- "
        "Current: %f [A]",
            sensor_value_to_double(&v_bus),
            sensor_value_to_double(&power),
            sensor_value_to_double(&current));
}

void hw_pwr_mon_thread(void)
{
    if (pwr_mon_i2c == NULL) {
		LOG_ERR("No device found");
		return;
	}
	if (!device_is_ready(pwr_mon_i2c)) {
		LOG_ERR("Device %s is not ready", pwr_mon_i2c->name);
		return;
	}

    LOG_INF("Device %p name is %s", pwr_mon_i2c, pwr_mon_i2c->name);
    while (1) {
		fetch_and_display(pwr_mon_i2c);
        k_sleep(K_MSEC(3000));
    }
}

K_THREAD_DEFINE(hw_pwr_mon_thread_id, CONFIG_PWR_MONITOR_THREAD_STACK_SIZE, hw_pwr_mon_thread, NULL, NULL, NULL, CONFIG_PWR_MONITOR_THREAD_PRIORITY, 0, 0);

Here is the LA trace.

This is the output I am seeing.

00> *** Booting Zephyr OS build v3.2.99-ncs1 ***
00> [00:00:01.302,368] <inf> buttons: Set up button at gpio@50000000 pin 11, mask 2048
00> [00:00:01.302,429] <inf> buttons: Set up button at gpio@50000000 pin 24, mask 16777216
00> [00:00:01.302,490] <inf> buttons: Set up button at gpio@50000000 pin 25, mask 33554432
00> [00:00:01.302,551] <inf> buttons: Set up button at gpio@50000000 pin 12, mask 4096
00> [00:00:01.302,581] <inf> buttons: Set up LED at gpio@50000000 pin 13
00> [00:00:01.302,581] <inf> buttons: Starting timer
00> [00:00:01.302,673] <inf> pwr_monitor: Device 0xb4d4 name is ina219@40
00> [00:00:01.302,734] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:04.302,825] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:07.302,947] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:10.303,070] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:13.303,192] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:16.303,314] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:19.303,436] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:22.303,558] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:25.303,680] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:28.303,802] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:31.303,924] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:34.304,046] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:37.304,168] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:40.304,290] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:43.304,412] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:48.811,859] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]
00> [00:00:53.172,821] <inf> pwr_monitor: Bus: 0.000000 [V] -- Power: 0.000000 [W] -- Current: 0.000000 [A]

  • Looks like you haven't fetched the data first.

    void initINA219(void){
    
    	const struct device *const ina = DEVICE_DT_GET_ONE(ti_ina219);
    	struct sensor_value v_bus, power, current;
    	int rc;
    
    	if (!device_is_ready(ina)) {
    		LOG_ERR("INA219  %s is not ready.", ina->name);
    		return;
    	}
    
    //	while (true) {
    		rc = sensor_sample_fetch(ina);      <---------------- HERE 
    		if (rc) {
    			LOG_ERR("INA219 Could not fetch sensor data.");
    			return;
    		}
    
    		sensor_channel_get(ina, SENSOR_CHAN_VOLTAGE, &v_bus);
    		sensor_channel_get(ina, SENSOR_CHAN_POWER, &power);
    		sensor_channel_get(ina, SENSOR_CHAN_CURRENT, &current);
    
    		LOG_INF("INA219 Bus: %f [V] -- "
    			"Power: %f [W] -- "
    			"Current: %f [A]",
    		       sensor_value_to_double(&v_bus),
    		       sensor_value_to_double(&power),
    		       sensor_value_to_double(&current));
    //		k_sleep(K_MSEC(2000));
    //	}
    }

    Regards

    Mashall

  • Marshall,

    Oh what a blunder, not sure how I've missed that. Thank you for the highlight. 

Related