私はいくつかのコードを持っています:
#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 経由でスクリプトを作成したところ、返される値が非常に一貫していました。クラッシュや予期しない値はありませんでした。
なぜこれが起こるのでしょうか?