2

私はいくつかのコードを持っています:

#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);
}

i2c 経由で MCP9800 から情報を読み取るコードです。申し訳ありませんが、それはそれと関係があるかもしれません。

この関数は、突然正しくない値を持ち始めるまで、約 12 サイクルの間うまく機能します。しかし、いくつかの奇妙な差異があります。

1. CALCULATION が以下の場合

temperature = filtered * AMB_LSB;

私はこの出力を得る:

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

働く

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 

失敗する

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 

したがって、失敗し始めると、フィルタリングされた値の出力が正しくないことがわかります。

2.計算の場合:

temperature = raw * AMB_LSB;

フィルター処理がまったく使用されないように、出力は次のようになります。

働く

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 

失敗する

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 

正しくない出力については、アスタリスク付きの数字を参照してください。何らかの理由で、フィルタリングされた値を使用しないと、他の数値も正しくなくなります! i2cチップから引き抜いたバイトにまでさかのぼります。

したがって、最初はおそらくフィルター処理が正しく機能していないことがわかります。しかし、それを削除すると、フィルタリングされていない生の値も正しくないように見えます。execFilter() が行っているのは、大きなランダムな変更を防ぐための平均化だけです。

また、i2cget を使用する CLI 経由でスクリプトを作成したところ、返される値が非常に一貫していました。クラッシュや予期しない値はありませんでした。

なぜこれが起こるのでしょうか?

4

3 に答える 3

2

ハードウェアの問題のようです。値の多くは 0x7FFFFFFF です。たとえば、SDA ラインはプルアップ抵抗によって制御されています。これは、SDA ラインのノイズが誤った I2C 停止条件を引き起こした場合に発生します。デバイスはすぐに出力をトライステートにし、残りの転送では上位ビットしか取得しません。

SCL および SDA ラインに RC ローパス フィルタを使用して、エッジを遅くし、高周波ノイズをブロックすることをお勧めします。これにより、このような通信エラーを防ぐことができます。

于 2012-11-08T22:21:56.420 に答える
0

私のアプリケーションの別のクラスからのメモリ破損でした。

ここ

于 2012-11-09T19:37:12.043 に答える