3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

M5DialによるRoller485の制御

Posted at

はじめに

本記事では、M5Dialを用いてUnit-Roller485を制御する。

目的

M5Dialをダイヤルとして使用し、I2C通信を用いてRoller485の制御を行う。

準備物

○ハードウェア系

  • PC(Windows10)
  • M5Dial
  • Unit-Roller485
  • USB Type-Cケーブル(PC-M5Stack接続用)

○ソフトウェア系

  • Arduino IDE
    →インストールについては、こちらを参照とする。

接続準備

事前準備として、

  • Roller485の通信設定をI2C通信に変更する。
  • I2C通信時のRoller485のアドレスを確認する。
    →筆者環境については、「0x40」を使用。
    ※上記2項目の確認についてはRoller485電源投入時に、背面にあるボタンを押下しながら電源を投入することで、設定画面を確認することができる。(確認画面を以下に示す。)
  • M5Stack Tab5のI2C通信用ピン(SDASCL)が何番かを確認する。
     →「SDA:13・SCL:15」をそれぞれ使用する。

実行スクリプト

Roller485 通信プロトコル(I2C通信用)を参考にコマンドを送信する。

動作としては、

  • スイッチによるモータのON/OFF切り替え
  • ダイヤルによるモータ回転速度の調整・方向変更(エンコーダ値使用)
    となる。

本記事で実際に使用したソースコードを以下に示す。
※ボードは「M5Stamp S3」を選択する。

m5tab5_motorControl.ino
// ----------------------------------------------------------------------------------------------------
// ライブラリの読込
#include "M5Dial.h"
#include <Wire.h>

// ----------------------------------------------------------------------------------------------------
// マクロの定義

// ON/OFF
#define ON  true
#define OFF false
#define CW  true
#define CCW false

// I2C通信
#define ROLLER_ADDRESS 0x40  // Unit-Roller485 I2Cアドレス
#define I2C_SDA        13    // M5Dial I2C通信ポート(SDA)
#define I2C_SCL        15    // M5Dial I2C通信ポート(SCL)

#define MAX_SPEED 1000  // 最大回転速度[rpm]

// ----------------------------------------------------------------------------------------------------
// グローバル変数・定数の定義

// スイッチ状態
bool motor_sw_state  = OFF;
bool rotate_sw_state = CCW;

// モータ回転速度
int32_t motor_speed = 100;
uint8_t motor_bytes[4] = {0, 0, 0, 0};


// ----------------------------------------------------------------------------------------------------
// 関数の定義

// int32 --> byteに変換(Roller485-Unit用)
void cvtInt2Bytes(void) {
  uint32_t remainder = motor_speed * 100;  // コマンド変換用にx100
  // char speed_str[4];  // デバッグ用

  for(int i = 0; i < 4; i++) {
    if (rotate_sw_state) {
      motor_bytes[i] = remainder % 256;  // CW
    }
    else {
      motor_bytes[i] = ~(remainder % 256);  // CCW
    }
    remainder /= 256;
  }
}

// モータON/OFF切替
void motorSW() {
  uint8_t on_command[2]  = {0x00, 0x01};  // モータONコマンド
  uint8_t off_command[2] = {0x00, 0x00};  // モータOFFコマンド

  uint8_t length = 2;  // コマンド長

  if (motor_sw_state) {
    // ON --> OFF
    motor_sw_state = OFF;
    // コマンド送信
    sendCommand(off_command, length);
  }
  else {
    // OFF --> ON
    motor_sw_state = ON;
    // コマンド送信
    sendCommand(on_command, length);
  }
}

// 速度
void controlSpeed() {
  uint8_t command[5] = {0x40, motor_bytes[0], motor_bytes[1], motor_bytes[2], motor_bytes[3]};  // 速度設定コマンド
  uint8_t length = 5;  // コマンド長

  // コマンドの送信
  sendCommand(command, length);
}

// コマンド送信
void sendCommand(uint8_t* command, uint8_t length) {
  Wire.beginTransmission(ROLLER_ADDRESS);  // ポート オープン
  for (int i = 0; i < length; i++) {
    Wire.write(command[i]);  // コマンド送信(I2C)
  }
  Wire.endTransmission(true);  // ポート クローズ
}

// ----------------------------------------------------------------------------------------------------
// メイン処理

void setup() {
  uint8_t command[5] = {0x40, 0x00, 0x00, 0x00, 0x00};
  uint8_t length = 5;

  // I2C通信 初期化
  Wire.begin(I2C_SDA, I2C_SCL);
  // M5Dial 初期化処理
  auto config = M5.config();
  M5Dial.begin(config, true, false);
  
  sendCommand(command, length);  // モータ停止
}

long bef_pos = 0;

void loop() {
  // エンコーダ位置 更新
  M5Dial.update();  // M5dial 状態更新
  long now_pos = M5Dial.Encoder.read();  // エンコーダ値 読取

  // エンコーダ位置 変化時
  if (now_pos - bef_pos != 0) {
    /*
    ダイヤルCW : モーターCW
    ダイヤルCCW: モーターCCW とする
    */

    if (now_pos*10 < -MAX_SPEED) {
      motor_speed = MAX_SPEED;
    }
    else if (now_pos*10 > MAX_SPEED){
      motor_speed = -MAX_SPEED;
    }
    else{
      motor_speed = -now_pos*10;
    }

    cvtInt2Bytes();
    controlSpeed();  // モータ回転速度を変更
    bef_pos = now_pos;
  } 

  // ボタン 押下時
  if (M5Dial.BtnA.wasPressed()) {
    motorSW();
  }
}

実行結果

実行結果の動画を以下に示す。
動画では、

  1. 起動
  2. M5Dial ボタンを押下
    →モータON(Unit-Roller485 緑色LEDが点灯→点滅に変化)
  3. M5Dial ダイヤルを時計回りに回転
    →モータ CW
  4. 一定時間回転後、M5ダイヤル ボタンを押下
    →モータOFF(停止)
  5. M5ダイヤル ボタンを押下
    →モータ CW再開
  6. M5Dial ダイヤルを時計回りに回転
    →モータ CWからCCWへ
  7. 一定時間回転後、M5ダイヤル ボタンを押下
    →モータOFF(停止)
    の順番で操作を実施している。

※フレームレートの関係で、回転状態でも止まっている用に見えるタイミング有。

上記より、M5Dialをダイヤルとして使用し、I2C通信を用いてRoller485の制御をすることができた。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?