したがって、これを2日間試みた後、頭を動かすことができません。
それで私はCANバスを使って加速度計データと時間データを転送しています(71分未満の場合はmicros()関数はunsigned longになる可能性のあるデータを出力します)が、データをバイトとして送信する必要があります。 16ビットintを2バイトにビットシフトすることができましたが、そのメソッドをlongの使用に外挿するのに問題があります(後で追加します)。独自の関数を作成するのが初めてなので、unionメソッドを理解するのに問題があります。皆さんはこれを達成しますか?できるだけ簡単にしてください:)
コメント
- 合計から最大バイト3を差し引くと、最大バイト2を差し引くと、バイト3が得られます。バイト4は、最大バイト4から数値を引いたものから最大バイト3 + 1を引いたものです。
回答
ビットシフトおよびビット単位および演算子。
これは抽出できる例です。 long
変数の個々のバイト。異なる長さの変数に拡張するのは簡単なことだと思います。
void loop() { long a=0x12345678, c=0; byte b[4]; Serial.println("Original:"); Serial.println(a,HEX); delay(1000); Serial.println("Individual bytes:"); for (int i=0; i<4; i++) { b[i]=((a>>(i*8)) & 0xff); //extract the right-most byte of the shifted variable Serial.println(b[i],HEX); delay(1000); } for (int i=0; i<4; i++) { c+=b[i]<<(i*8); } Serial.println("Reconstructed:"); Serial.println(c,HEX); delay(1000); }
予想されるバイト順序(ビッグエンディアンまたはリトルエンディアン)に応じて、次のようになります。送信前または受信後にバイトを並べ替える必要があります。
コメント
- 非常にわかりやすく、原則を理解しやすいので、ありがとうございます。ただし、"再構築" 5678しか出力しませんか?
- 私の回答からコードスニペットをコピーしましたか? nodemcuでコードを実行すると、正しい答えが得られるためです。
- はい、コードをコピーして貼り付け、void setup();を追加しました。およびSerial.begin(9600);コードを私のarduinonanoで実行するには
- デフォルトで8ビットAVRで、equalsの右側はデフォルトで16ビットで署名されたint演算になります。だから私は配列をループ内のuint32_tにキャストしました。それが最も効率的な方法かどうかはわかりませんが、機能します。助けてくれてありがとう
- そうです。 nodemcuを試してみたとき、' arduinoコントローラーについては考えていませんでした。
回答
union
タイプはstruct
に似ていますが、要素の各メンバーが同じメモリ。 struct
を定義して2つのメンバー(1つは4バイト型、もう1つは1バイト型の4要素配列)を持つようにすると、同じデータを簡単に参照できます。全体として4バイトの要素として、または必要に応じてバイト単位で。
union packed_long { long l; byte b[4]; };
これは型であるため、変数を次のように宣言する必要があります。そのタイプ:
packed_long mydata;
これで、mydata
の2つのサブ要素があります:l
およびb[]
。
long
の値を保存するには、
部分:
mydata.l = myaccel.getY();
4バイトのそれぞれにアクセスするには:
byte1 = mydata.b[0]; byte2 = mydata.b[1]; byte3 = mydata.b[2]; byte4 = mydata.b[3];
受信側では、次の4バイトをそれぞれ取得します。
mydata.b[0] = canbus.read(); mydata.b[1] = canbus.read(); mydata.b[2] = canbus.read(); mydata.b[4] = canbus.read();
同じ順序でバイトを受信する限りそれらを送信した場所で、mydata.l
のlong
値にアクセスできるようになりました。
異なるサイズタイプはコンパイラとアーキテクチャに依存するため、値を一定サイズの変数として定義して、常に32ビットで作業できるようにすることもできます。int32_t
(符号付き32ビット整数)またはuint32_t
(符号なし32ビット整数)。