コンテンツにスキップ
高トルクモーターDDT-M15の使い方 #DirectDriveTech

高トルクモーターDDT-M15の使い方 #DirectDriveTech

高トルクDDTモーター https://www.switch-science.com/catalog/8248/ のコントロール方法をまとめてみます。

必要なもの

- 任意のSPI機能が使えるマイコン(今回はRaspberryPi Pico https://www.switch-science.com/products/6900 )
- CANトランシーバー
- 24V10~20A電源

電源は22V以上必要でしたトルクが減ってもいいからと18Vで動かすといったことはできません。また、電流容量の少ない電源での運用はよほど負荷が少なく安定していないと安定動作が難しいので、しっかりと容量を確保するのがおすすめです(移動体として動作させたとき、段差にぶつかるだけでも瞬間的に大電流を要求されます)。

ケーブルについて

付属のケーブル長は約0.5m。

 番号 役割
1 VCC(24V)
2 GND
3 CAN High
4 CAN Low

 

CANアダプタについて

[Amazonの例](https://amzn.asia/d/b9DWvV3)


MCP2515は任意のVCC(2V~5V)で動くSPI接続のCANアダプタです。

Picoとの接続

 Pico名称 ピン番 MCP側名称
unuse - INT
SCK GP2 SCK
SDO GP3 MOSI
SDI GP4 MISO
GP28 CS
GND - GND
3.3V - VCC

 

M15の資料

https://doc.switch-science.com/media/files/bb32803a-dbdb-45a6-8cc5-0558f81eb66b.pdf

主に使う指令コマンド

0x106: ステータスレポート頻度の指定コマンド

モーターから自発的に出力するのを止めるために0x80を指定。

0x105: モーター制御モードの指定コマンド

0x00: Open Loopモード(0x00)を指定。
0x01: 電流制御モード
0x02: 速度制御モード
0x03: 角度制御モード
0x09: モーター無効化
0x0a: モーター有効化(電源ON時、有効)

0x107: ステータスレポートの発行要求コマンド

ループ処理中にこれを送信してレポートを吐かせる。
出力させる項目をいくらか指定できる。

0x32: 制御目標値の設定

TinyGoで制御サンプル

あらかじめ必要

  • goのインストール
  • tinygoのインストール

準備

go mod init sample
go get tinygo.org/x/drivers

 

サンプルコード

package main

import (
  "fmt"
  "machine"
  "runtime"
  "time"

  "tinygo.org/x/drivers/mcp2515"
)

var (
  spi   = machine.SPI0
  csPin = machine.GP28
)

func ReadFrame(can *mcp2515.Device) (*mcp2515.CANMsg, error) {
  for !can.Received() {
    runtime.Gosched()
  }
  return can.Rx()
}

func main() {
  for !machine.Serial.DTR() {
    time.Sleep(100 * time.Millisecond)
  }
  led := machine.LED
  led.Configure(machine.PinConfig{
    Mode: machine.PinOutput,
  })
  if err := spi.Configure(
    machine.SPIConfig{
      Frequency: 500000,
      SCK:       machine.GP2,
      SDO:       machine.GP3,
      SDI:       machine.GP4,
      Mode:      0,
    },
  ); err != nil {
    println(err.Error())
  }

  can := mcp2515.New(spi, csPin)
  can.Configure()
  if err := can.Begin(mcp2515.CAN500kBps, mcp2515.Clock8MHz); err != nil {
    println(err.Error())
  }
  if err := can.Tx(0x109, 8, []byte{0, 0, 0, 0, 0, 0, 0, 0}); err != nil {
    println(err.Error())
  }
  msg, err := ReadFrame(can)
  if err != nil {
    println(err.Error())
  }
  fmt.Printf("%#v\n", msg)
  if err := can.Tx(0x106, 8, []byte{0x80, 0, 0, 0, 0, 0, 0, 0}); err != nil {
    println(err.Error())
  }
  msg, err = ReadFrame(can)
  if err != nil {
    println(err.Error())
  }
  fmt.Printf("%#v\n", msg)
  if err := can.Tx(0x105, 8, []byte{0x00, 0, 0, 0, 0, 0, 0, 0}); err != nil {
    println(err.Error())
  }
  msg, err = ReadFrame(can)
  if err != nil {
    println(err.Error())
  }
  fmt.Printf("%#v\n", msg)

  for {
    if err := can.Tx(0x107, 8, []byte{0x01, 0x01, 0x02, 0x04, 0x55, 0, 0, 0}); err != nil {
      println(err.Error())
    }
    msg, err = ReadFrame(can)
    if err != nil {
      println(err.Error())
      continue
    }
    fmt.Printf("%#v\n", msg)
    if err := can.Tx(0x32, 8, []byte{0x00, 0x00, 0, 0, 0, 0, 0, 0}); err != nil {
      println(err.Error())
    }
    led.Low()
    time.Sleep(5 * time.Millisecond)
    led.High()
    time.Sleep(5 * time.Millisecond)
  }
}

 

ビルドと書き込み

ビルドのみ

tinygo build -target pico -o sample.elf .

ビルド&書き込み

tinygo flash -target pico .

まとめ

  • DDTのCANインターフェース利用にMCP2515が便利
  • TinyGoにはドライバーが提供されているので利用も簡単
前の記事 Forget WiFi Woes, Go LTE All-American