シンプルモータコントローラG2のTTLシリアル通信を使い、Arduinoでモータ制御をしていきます。
Arduinoシリーズや、A-Starなどの互換機から、TTLシリアル通信で制御する基本的なサンプルコードと、エラー処理も行う詳細なサンプルコードです。
シリアル動作モード

Arduinoとシンプルモータコントローラを、シリアルとGNDを接続します。
Arduinoシリアル通信に、SoftwareSerialを使用しているので、Arduino Txのピンは、D4ピン以外にも設定できます。
18v15/24v12と18v25/24v19で配置がすこし違いますが、ボードの左にあるRX/SDAとGNDへ接続します。


Simple Motor Control Center G2から設定します。 インストールがまだの時は、導入編をご覧ください。
Input settingsタブを開き設定していきます。
サンプルコード中で、baud rateを指定しているため、19200にしてください。標準のAuto-detect baud rateでも動作しますが、SoftwareSerialライブラリのボーレートの正確さを考えると推奨できません。

基本的な、正転と逆転を行うサンプルコードです。
正転全速回転 1秒し、逆転全速回転 1秒 を繰り返すコードです。
#include <SoftwareSerial.h>
#define rxPin 3 // pin 3 connects to smcSerial TX (このサンプルでは使用しません)
#define txPin 4 // pin 4 connects to smcSerial RX
SoftwareSerial smcSerial = SoftwareSerial(rxPin, txPin);
// コントローラの再起動やエラー後に
// モータの動作を有効にするため必要
void exitSafeStart()
{
smcSerial.write(0x83);
}
// 速度を数値で -3200 ~ 3200 まで
void setMotorSpeed(int speed)
{
if (speed < 0)
{
smcSerial.write(0x86); // モータ逆転コマンド
speed = -speed; // モータ速度を正の値へ
}
else
{
smcSerial.write(0x85); // モータ正転コマンド
}
smcSerial.write(speed & 0x1F);
smcSerial.write(speed >> 5 & 0x7F);
}
void setup()
{
// 初期化: ソフトウェアシリアル ボーレート 19.2 kbps
smcSerial.begin(19200);
// シンプルモータコントローラは、
// シリアルデータを送る前に 1ms あける必要があります。
// ここでは、5ms 遅延処理を行います。
delay(5);
// シンプルモータコントローラで自動ボーレート検出を有効にしている場合、
// ボーレートを学習できるように、最初に 0xAA (10進数170)を送信します。
smcSerial.write(0xAA);
// 次に、セーフスタート終了コマンドを送信
// セーフスタートエラーをクリアし、モータを動作開始状態にします。
exitSafeStart();
}
void loop()
{
setMotorSpeed(3200); // 正転 全速
delay(1000);
setMotorSpeed(-3200); // 逆転 全速
delay(1000);
}

Arduinoとシンプルモータコントローラを接続します。基本的なサンプルコードより接続が増えていますので注意してください。
Arduinoシリアル通信に、SoftwareSerialを使用しているので、シリアルはD3,D4ピン以外にも設定できます。/RSTとERRも、任意のデジタルピンへ変更できます。
18v15/24v12と18v25/24v19で配置がすこし違いますが、ボードの左にあるRX/SDA、TX、/RST、ERRとGNDへ接続します。


上で設定した、基本的なサンプルコードの設定と同じです。
シンプルモータコントローラG2との、シリアル通信の方法、モータ速度の設定、変数の読取り、モータの制限を変更するためのコマンドの送信サンプルです。
#include <SoftwareSerial.h>
#define rxPin 3 // pin 3 connects to SMC TX
#define txPin 4 // pin 4 connects to SMC RX
#define resetPin 5 // pin 5 connects to SMC nRST
#define errPin 6 // pin 6 connects to SMC ERR
SoftwareSerial smcSerial = SoftwareSerial(rxPin, txPin);
// some variable IDs
#define ERROR_STATUS 0
#define LIMIT_STATUS 3
#define TARGET_SPEED 20
#define INPUT_VOLTAGE 23
#define TEMPERATURE 24
// some motor limit IDs
#define FORWARD_ACCELERATION 5
#define REVERSE_ACCELERATION 9
#define DECELERATION 2
// シリアル 1バイト読込み (タイムアウトしデータがない時は -1 を返す)
int readByte()
{
char c;
if(smcSerial.readBytes(&c, 1) == 0){ return -1; }
return (byte)c;
}
// コントローラの再起動やエラー後に
// モータの動作を有効にするため必要
void exitSafeStart()
{
smcSerial.write(0x83);
}
// 速度を数値で -3200 ~ 3200 まで
void setMotorSpeed(int speed)
{
if (speed < 0)
{
smcSerial.write(0x86); // モータ逆転コマンド
speed = -speed; // モータ速度を正の値へ
}
else
{
smcSerial.write(0x85); // モータ正転コマンド
}
smcSerial.write(speed & 0x1F);
smcSerial.write(speed >> 5 & 0x7F);
}
unsigned char setMotorLimit(unsigned char limitID, unsigned int limitValue)
{
smcSerial.write(0xA2);
smcSerial.write(limitID);
smcSerial.write(limitValue & 0x7F);
smcSerial.write(limitValue >> 7);
return readByte();
}
// 指定した変数IDの値を unsinged int で返す
// もし指定した変数IDの値が、符号付き整数(singed int)の場合は、
// この関数の返値をintとして型をキャストしてください。
// 具体的には (int)getVariable(TARGET_SPEED)
unsigned int getVariable(unsigned char variableID)
{
smcSerial.write(0xA1);
smcSerial.write(variableID);
return readByte() + 256 * readByte();
}
void setup()
{
Serial.begin(115200); // デバッグ用 (optional)
smcSerial.begin(19200);
// Arduino起動時にSMCを一時的にリセット (optional)
pinMode(resetPin, OUTPUT);
digitalWrite(resetPin, LOW); // reset SMC
delay(1); // wait 1 ms
pinMode(resetPin, INPUT); // let SMC run again
// リセット後に送信するとき、1ms以上待機する必要があります。
delay(5);
// SMC ERRピンの状態を読出し (optional)
pinMode(errPin, INPUT);
smcSerial.write(0xAA); // ボーレート自動検出用バイト送信
setMotorLimit(FORWARD_ACCELERATION, 4);
setMotorLimit(REVERSE_ACCELERATION, 10);
setMotorLimit(DECELERATION, 20);
// セーフスタートエラーをクリアし、モータを動作開始状態にする
exitSafeStart();
}
void loop()
{
setMotorSpeed(3200); // 正回転 全速
// 符号付きの変数はintへキャストします:
Serial.println((int)getVariable(TARGET_SPEED));
delay(1000);
setMotorSpeed(-3200); // 正回転 全速
Serial.println((int)getVariable(TARGET_SPEED));
delay(1000);
// シリアルモニタに入力電圧(mV)を送信
Serial.print("VIN = ");
Serial.print(getVariable(INPUT_VOLTAGE));
Serial.println(" mV");
// エラーによりモータが停止している時は、
// エラーステータス変数を読込み、モータの再始動をトライする。
if (digitalRead(errPin) == HIGH)
{
Serial.print("Error Status: 0x");
Serial.println(getVariable(ERROR_STATUS), HEX);
// 全てのエラーが解除されると、モータが再び動作します。
exitSafeStart();
}
}
Pololuユーザガイドにある、ArduinoのTTLシリアル通信からシンプルモータコントローラG2を制御するのサンプルコードです。バイナリコマンド方式の詳細は、ユーザガイド 6.2.1(英語版)をご覧ください。