2016-07-13 5 views
0

Modbus RTUプロトコルを使用してシリアルポート経由でデバイスと通信しています。データは8ビットのバイトとして取り込まれます。解析の後、私は1つの32ビットフィールドに「結合」したい4バイトで終わります。 次のように私はこれをやっている:シリアルポート経由でデータを入力します。ビットをintやfloatなどの型に解析します。


unsigned char bytes[4]; 
int field; 
field = (0x000000FF & bytes[0]); 
field = (field << 8); 
field = (field & 0x0000FF00); 
field = (field | bytes[1]); 
field = (field << 8); 
field = (field & 0x00FFFF00); 
field = (field | bytes[2]); 
field = (field << 8); 
field = (field & 0xFFFFFF00); 
field = (field | bytes[3]); 

しかし、同僚は、この方法は、異なるシステム上で予期しない結果を有していてもよく、それは、さらに、それがフロートまたはlong型では動作しない可能性があることを私に言いました。 誰かが私にこの理由を説明することはできますか?可能であれば、可能な限り、異なるシステム間で一貫した結果をもたらす方法で上記の作業をどのように達成するかを教えてください。ありがとう!

+0

まず(と成長するリスト)intが(あなたがバイト順(ここでは、ネットワークバイトオーダーを想定かもしれないがわからない場合 –

+0

第二には、あなたが完全に失われます(それは何もすることができます)ではない32ビットであり、ビッグエンディアン)) –

+0

第3に、浮動小数点値は、期待する浮動小数点値ではない可能性があります。異なるサイズに加えて、異なる表現が可能である。 –

答えて

0

まず、データが実際に符号付きの数値でない限り、intの代わりにunsignedを使用する必要があります。 fixed-width integer types of <cstdint>を使用している場合は、8ビットまたは32ビットの符号なし整数型を使用していると明示することをお勧めします。あなたの問題については

は、それはあなたがそれだと思うよりも、実際にはるかに簡単です:バイト順序がある

uint32_t field = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0]; 

場合は反対に、あなたがbytesに使用する順序を逆にします。同じ技術を使用してfloat変数を再構成する


、上記のように行い、その後、例えば行います

float value = *reinterpret_cast<float*>(&field); 
+0

これはfloat型でも動作しますか?そしてはい、実際には – Numi

+0

@Numiが署名されます。送信される浮動小数点値がバイト単位で送信された単精度32ビット型で正しいバイトオーダーであれば、それも可能です。コンパイラに、ビット単位の演算の結果が実際には整数ではなく、例えば、整数ではないことを伝えるためには、いくつかのキャストとポインタ演算を行う必要があります。 「フロート」。 –

+0

ありがとうございます!それは私の心を安らかにする – Numi

関連する問題