Arduinoで6CHモーターコントローラの解析

ArduinoでI2Cスレーブ側のプログラムを練習すべく、6CHモーターコントローラが受けるI2C通信を解析してみる。

まず、C-Styleで6CHモーターコントローラを操作するサンプルプログラムを準備し、TJ3Bで実行しておく。モーターの停止、正転、ブレーキ、逆転を繰り返す。

Arduino側プログラムは、こんな感じ。I2Cの受信のみで応答しないのでシンプルにできた。

#include <Wire.h>

#define MCB_ADRS	0x14
#define I2C_BUFSIZE	48
#define MAX_PWM		6

//I2C受信バッファ(byte 0〜255)
byte i2c_recv_buf[I2C_BUFSIZE];

void setup()
{
  int adrs = MCB_ADRS >> 1;  //Slave addressスレーブアドレス変換

  //I2C開始
  Wire.begin(adrs);
  //マスターからの書き込み要求(R/W=0)を受けた時の割込み関数を登録
  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
}

void loop()
{
  delay(10);
}

/**
 * マスターからの書き込み要求(R/W=0)を受けた時の割込み関数
 * @param int bytesReceived データ長(byte)
 */
void receiveEvent(int bytesReceived)
{
  int i, a, b;

  for (i = 0; i < I2C_BUFSIZE; i++) {
    if (i < bytesReceived) {
      //I2C受信
      i2c_recv_buf[i] = Wire.read();
    }
    else {
      Wire.read();
    }
  }

  for (i = 0; i < MAX_PWM; i++) {
    if (i > 0) Serial.print(" ");
    Serial.print("[");
    Serial.print(i);
    Serial.print("]");
    if (i2c_recv_buf[i] == 0) {
      Serial.print("stop");
    }
    else if (i2c_recv_buf[i] == 128) {
      Serial.print("brake");
    }
    else if (i2c_recv_buf[i] < 128) {
      //cw
      Serial.print("cw:");
      a = map(i2c_recv_buf[i], 0, 100, 0, 255);
      Serial.print(a);
    }
    else {
      //ccw
      Serial.print("ccw:");
      b = map(i2c_recv_buf[i] - 128, 0, 100, 0, 255);
      Serial.print(b);
    }
  }
  if (i > 0) Serial.println("");
}

ArduinoとTJ3BをI2Cで繋ぎ、Arduino IDEのシリアルモニタで結果を確認する。各chの0〜100%の値をanalogWrite()などで処理しやすいよう0〜255の値に変換している。C-Style上の1〜100%が右回転(CW:Clockwise)、-100〜-1が左回転(CCW:Counter-clockwise)、0:停止、128:ブレーキとした。