俺言語。

自分にしか理解できない言語で書かれた備忘録

【C】2byte以上のデータを1byteずつ送信する方法

例えば65535(0xFFFF)のような2byteのデータをシリアル通信で送信する場合、

1) 文字列のまま送る→ 0x54 0x53 0x53 0x51 0x53 で5byte必要
2) バイナリデータで送信 → 0xFF 0xFF で2byte

とバイナリデータで送信する方が効率がよい.

2byteデータをバイナリデータで送信する場合は上位byteと下位byteに分けて送信する必要があるため,ビットシフトなどを使って

uint8_t b[2];
b[0] = 65535 >> 8
b[1] = 65535 - (b[0]<<8) // そのまま65535を代入しても上位8bit分は自動的に削られるかも

// ビットシフトは加減算より優先順位が低いのでカッコが必要(知らんかった…)

とする必要があるが,これをCの共用体と構造体を使うともう少し簡単にできる.
たとえばCAN ID(2byte)とデータ1byteを送信する場合は,

union myuni
{
    struct{
        uint16_t id;
        uint8_t sig;
    };
    uint8_t bin[sizeof(uint8_t) * (2+1)];
};

と,共用体の中に構造体を定義して,

myuni.id = 65535;
myuni.sig = 255;
Serial.write(myuni.bin, 3);

とするとCAN IDの2byteを上位byteと下位byteに自動的に分割してくれるのでそのまま送信できる.

ポイントは,共用体は複数のメンバがメモリを共用していて,共用体のサイズは最もサイズの大きなメンバに合わせる点.
これによって,構造体の中のメンバのメモリ位置(今回の例ではidとsig)と共用体のメンバ(bin)のメモリ位置が一致するので,binにアクセスすると,idとsigに代入した値が入っている.

こちらを参考にさせて頂きました。
hawksnowlog.blogspot.com