Arduino I2C PIC DATA I/O (Wire Library)

ArduinoにI2C接続したPICとデータをやり取りするための、Arduino側のサンプルソースです。
サンプルでは4バイトのデータをPICから受けて、それをそのまま受けた順番でGVCフォーマットでシリアルから送信しています。
GVCのデーモンであるgvcdでシリアルからデータを受ける事を想定していますので、実際のデータの計算などはArduinoよりもたぶん強力な処理能力の有るgvcd側(Linux側)で行って、最終的にsyslogに出力しています。

// --------------------------------------------------
// Global Versatile Controler
// --------------------------------------------------
// --------------------------------------------------
// Memo
// --------------------------------------------------
// ------------------------------
// BASE
// ------------------------------
// New BSD License. Copyright (c) 2011-2012, Future Versatile Group
// All rights reserved.
//
// 2011.11.04 T.Kabu
// 2011.11.18 H.A.
// 2011.12.02 Arduino-IDE VerUp to 1.0
// 2011.12.13 T.Kabu このファイルはベースなので、定数を各モジュールに別途記述とした
//
// ※このソースはサンプルです。GVCプロトコルは現在も仕様策定中なのでソースが変更になる場合があります。

//---------------------------------------------------
// include
//---------------------------------------------------
#include <Wire.h>                // for I2C device

// --------------------------------------------------
// Const Define
// --------------------------------------------------
#define    SOFTNAME        "Global Versatile Controler"
#define    SOFTVER         "0.00"

#define    GVC_MSG_MAX     64           // Arduino have only 1024Bytes!!

#define    GVC_MSG_END     0x00         // Message delimiter

#define    GVC_MSG_OTHER   '!'          // START, RESET, INFO, etc

#define    GVC_DEV_00    0              // GVC DEVICE NO 0 (DO NOT USE THIS!!)
#define    GVC_DEV_01    1              // GVC DEVICE NO 1
#define    GVC_DEV_02    2              // GVC DEVICE NO 2
#define    GVC_DEV_03    3              // GVC DEVICE NO 3
#define    GVC_DEV_04    4              // GVC DEVICE NO 4
#define    GVC_DEV_05    5              // GVC DEVICE NO 5

#define    LED    13                    // LED Port

// ------------------------------
// Define PIC(12F1822) IN/OUT
// ------------------------------
#define    PIC_ADDRESS      0x20        // I2C Device ID : PIC(12F1822)

#define    GVC_MSG_PICDIO   0x20        // PIC(12F1822) DATA IN/OUT

#define    GVC_PICDIO_SIZE   8          // GVC PIC DATA ONLY MESSAGE SIZE = 8 bytes

// --------------------------------------------------
// Structure
// --------------------------------------------------
// ------------------------------
// GVC Message : BASIC
// ------------------------------
struct _GVC_MSG_BASIC
{
  char    msg_type;                    // Message Type
  char    dev_num;                     // Module No.
  char    msg_format;                  // Message Format
  char    msg_data[GVC_MSG_MAX];       // Message Data
};

// ------------------------------
// GVC Message : PIC(12F1822) IN/OUT
// ------------------------------
struct _GVC_MSG_PICDATAINOUT
{
    char    msg_type;                  // Message Type
    char    dev_num;                   // Module No.
    char    msg_format;                // Message Format
    char    msg_data[4];               // Message Data
    char    msg_end ;                  // Message End
};

// --------------------------------------------------
// Variable Param
// --------------------------------------------------
// ------------------------------
// GVC Message Length
// ------------------------------
int gvc_msg_len;

// ------------------------------
// GVC Message : FIRST
// ------------------------------
char GVC_FIRST_MSG[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0x00};

// ------------------------------
// GVC Message : BASIC
// ------------------------------
struct _GVC_MSG_BASIC    gvc_msg;

// --------------------------------------------------
// Sub Routine
// --------------------------------------------------
// ------------------------------
// Send Start Frame
// ------------------------------
void send_startframe()
{
  // GVC Message Set (First message)
  // Serial OUTPUT
  Serial.write((uint8_t *)&GVC_FIRST_MSG, 9);

  // GVC Message Set (First message)
  // Serial OUTPUT
  Serial.write((uint8_t *)&GVC_FIRST_MSG, 9);

  // GVC Message Set (First message)
  // Serial OUTPUT
  Serial.write((uint8_t *)&GVC_FIRST_MSG, 9);
}

// --------------------------------------------------
// Setup
// --------------------------------------------------
void setup()
{
    // Start Serial Port
    Serial.begin(9600);

    // Send Start Frame
    send_startframe();

    // GVC Message Set (Init message)
    gvc_msg.msg_type = GVC_MSG_OTHER;  // '!'
    gvc_msg.dev_num = GVC_DEV_01; // DEVICE NUM (1..254)
    gvc_msg.msg_format = 0x00;    // 0x00 = INITIAL Message
    sprintf(gvc_msg.msg_data, "%s %s", SOFTNAME, SOFTVER);
    // GVC Message Length Set (Dont forget NULL!!)
    gvc_msg_len = 3 + strlen(gvc_msg.msg_data) + 1;
    // Serial OUTPUT
    Serial.write((uint8_t *)&gvc_msg, gvc_msg_len);

    // GVC Message Set (Start message)
    gvc_msg.msg_type = GVC_MSG_OTHER;  // '!'
    gvc_msg.dev_num = GVC_DEV_01; // DEVICE NUM (1..254)
    gvc_msg.msg_format = 0x10;    // 0x10 = NORMAL Message
    sprintf(gvc_msg.msg_data, "GVC START");
    // GVC Message Length Set (Dont forget NULL!!)
    gvc_msg_len = 3 + strlen(gvc_msg.msg_data) + 1;
    // Serial OUTPUT
    Serial.write((uint8_t *)&gvc_msg, gvc_msg_len);

    // Setup LED
    pinMode(LED,OUTPUT);

    // Open I2C device
    Wire.begin();
}

// ------------------------------
// Get DATA from PIC(12F1822)
// ------------------------------
void get_picdataio(void * msg_ptr)
{
    struct _GVC_MSG_PICDATAINOUT    *gvc_pic;    // GVCメッセージ(PIC DATA I/O)
    byte    i2c_cmd[] = {0x01, 0x11, 0x00};      // I2C用コマンド、ArduinoのbyteとLinuxのbyte型は違うかもしれないので注意
    char    data[4];                             // PICからのデータ

    // GVC Message Set (Temparature message)
    gvc_pic = (struct _GVC_MSG_PICDATAINOUT *)msg_ptr;

    // PIC(12F1822)に対してデータ要求
    Wire.beginTransmission(PIC_ADDRESS);         // PIC(12F1822)のデバイスIDに対して
    Wire.write(i2c_cmd, 3);                      // I2Cコマンドを送信
    Wire.endTransmission();                      // 送信終了
    Wire.requestFrom(PIC_ADDRESS, 4);            // PIC(12F1822)からデータを4バイトを受信する

    // データが来るまでループして待つ
    while (Wire.available() < 1)
    {
        // 必要ならタイマー割り込みを用意して、タイムアウト→エラー処理とすること
    }

    // データを受信
    gvc_pic->msg_data[0] = Wire.read();                // 1バイト受信
    gvc_pic->msg_data[1] = Wire.read();                // 1バイト受信
    gvc_pic->msg_data[2] = Wire.read();                // 1バイト受信
    gvc_pic->msg_data[3] = Wire.read();                // 1バイト受信
    Wire.endTransmission();               // 送信終了

    gvc_pic->msg_type = GVC_MSG_PICDIO;    // PIC(12F1822) DATA IN/OUT
    gvc_pic->dev_num = GVC_DEV_04;         // デバイス番号(GVCに接続されているデバイスとしての番号...4というのは適当です)
    gvc_pic->msg_format = 0x01;            // FORMAT No.1 (TBD)
//    memcpy(gvc_pic->msg_data, data, 4);    // ... 上で直接入れているので二度手間はしない
    gvc_pic->msg_end = GVC_MSG_END;        // NULL
    // GVC Message Length Set (Dont forget NULL!!)
}

// --------------------------------------------------
// Main loop
// --------------------------------------------------
void loop()
{
    // 1サイクル開始時にArduinoのLED点灯(ボードの動作確認)
    digitalWrite(13, HIGH);

    // Send Start Frame
    send_startframe();

    // PIC(12F1822)からデータを取得
    get_picdataio(&gvc_msg);

    // 取得データをgvcdに送信
    Serial.write((uint8_t *)&gvc_msg,   GVC_PICDIO_SIZE);

    // 1サイクル終了時にArduinoのLED消灯
    digitalWrite(13, LOW);

    // 1秒待つ
    delay(1000);
}