C i2c chip reading MCP9800 suddenly starts failing

只愿长相守 提交于 2019-12-24 05:34:15

问题


I have some code:

#define AMB_LSB 0.0625

void Ambient::read()
{
    uint32_t raw; 
    float filtered;

    uint8_t bytes = 2;
    uint8_t buf[bytes];

    if(i2c_smbus_read_i2c_block_data(i2c_bus_address, A_TEMP_REG, bytes, buf) < 0)
        printf("AMB Block Read Failed\n");

    uint32_t va = buf[0];
    uint32_t vb = buf[1];

    uint32_t result = ((va<<8)+vb);

    // 12-bit code
    raw = result >> 4; 

    filtered = filter.execfilter( raw );
    temperature = filtered * AMB_LSB;  << CALCULATION 

    printf("AMB buffers %d %d -> result %d -> raw %d -> filtered %d -> amb C %f\n",va, vb, result, raw, filtered, temperature);
}

It is code to read information from a MCP9800 via i2c. Sorry for including it but maybe it has something to do with it.

The function works well for about a dozen cycles until all of a sudden it starts having incorrect values. But with some strange variances.

1. If CALCULATION is the following

temperature = filtered * AMB_LSB;

I get this output:

temperature = ((float) filtered * (float) AMB_LSB);

WORKING

AMB buffers 28 240 -> result 7408 -> raw 463 -> filtered 463 -> amb C 28.937500 
AMB buffers 28 240 -> result 7408 -> raw 463 -> filtered 463 -> amb C 28.937500 
AMB buffers 28 240 -> result 7408 -> raw 463 -> filtered 1024 -> amb C 64.000000 

FAILING

AMB buffers 29 0 -> result 7424 -> raw 464 -> filtered -**2147483648** -> amb C -134217728.000000 
AMB buffers 29 0 -> result 7424 -> raw 464 -> filtered **2147483647** -> amb C 134217728.000000
AMB buffers 29 0 -> result 7424 -> raw 464 -> filtered -**2147483648** -> amb C -134217728.000000 

So once it starts failing, I can see the output of the filtered value is incorrect.

2. If CALCULATION is:

temperature = raw * AMB_LSB;

So that filtered is not used at all, the output is this:

WORKING

AMB buffers 29 48 -> result 7472 -> raw 467 -> filtered 0 -> amb C 29.187500 
AMB buffers 29 48 -> result 7472 -> raw 467 -> filtered 2147483647 -> amb C 29.187500
AMB buffers 29 64 -> result 7488 -> raw 468 -> filtered 468 -> amb C 29.250000 

FAILING

AMB buffers **255 130** -> result **65410** -> raw **4088** -> filtered 2147483647 -> amb C 255.500000 
AMB buffers **255 130** -> result **65410** -> raw **4088** -> filtered -2147483648 -> amb C 255.500000 
AMB buffers **255 130** -> result **65410** -> raw **4088** -> filtered 2147483647 -> amb C 255.500000 

See the asterixed numbers for output that is incorrect. For some reason when you don't use the filtered values the other numbers just start being incorrect too! All the way back to the bytes I pulled off the i2c chip.

So at first I see that maybe filtered is not working correctly. But to remove it also appears to make the raw unfiltered value incorrect as well. All execFilter() is doing is some averaging to prevent large random changes.

Also, I also made up a script via the CLI that used i2cget and it was very consistant in its returned values. There was no crashing or unexpected values.

Why would this be happening?


回答1:


Sounds like a hardware problem. Many of your values are 0x7FFFFFFF, e.g. the SDA line is being controlled by the pullup resistor. This would happen if noise on the SDA line caused a spurious I2C stop condition -- the device would immediately tristate its output, and you would get nothing but high bits for the rest of the transfer.

RC lowpass filters are suggested on the SCL and SDA lines to slow down edges and block high frequency noise, helping to prevent such communication errors.




回答2:


Check the return value from i2c_smbus_read_i2c_block_data() call, not just whether it is negative or not.

I bet it returns 0 or 1 when you get the failed transfers. Remember that the actual function depends on the adapter; I would never just assume it succeeds completely if it does not return an error, since it is documented to return the number of bytes instead.




回答3:


It ended up being memory corruption from another class in my application.

HERE



来源:https://stackoverflow.com/questions/13298793/c-i2c-chip-reading-mcp9800-suddenly-starts-failing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!