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:ブレーキとした。