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);
}