今年最後のお仕事で機構の設計開発と制御をやったのですが、その際DMXでステッピングモーターを回すという単純なユニットを作りました。
わりと汎用的なデバイスなので、作ったプロセスをまとめてみたら、クリエイティブコーディングが好きで動きものをこれからトライしてみたい人への導入として便利な情報になるのではないかと思いQiitaに書き留めてみました。
こういう事に興味があって手伝ってくれそうな人を探しているので、そういう方は是非コンタクトを!
##対象となりそうな人
- 動き物をやりたい
- メカ作りに興味がある
- 照明をやっている
- TouchDesignerをやってる
!!!注意!!!
動き物はその名の通り動く装置です。装置を動作させる際は、物や人がぶつからないようにする、高所ではワークが落下しないようにするなど、安全面に十分配慮してください。
この記事を参考にしたことで発生した事故等には一切責任を負えませんので、ご了承ください。
##要件
今回は、撮影で使う演出用の駆動装置を作りました。700mmのアルミフレームを取り付け、そこに演出用の小道具を取り付けて回転させます。
完成品実験中の様子。机に置いていますが、実際の向きは逆さで、4.5mの高さに吊り下げます。
撮影ではこのモーターが9台あり、本番中は自分たちが映り込まないようにしなくてはならないのでPCから装置までの距離は少なくとも10~20m必要になります。
PCから全ての装置に直接つなごうとすると、最低でも10 * 9で合計90m以上のケーブルを用意しなくてはなりません。
そこで、長距離伝送ができ一対多の通信で子機を数珠つなぎ(デイジーチェーンと言います)にできるDMXが候補に上がります。
更にDMXで通信できるようにしておけば、touchdesignerにDMX用の機能が付いているので制御用のプログラムを書く手間が省ける!という事に気づき、DMXを使う事が確定しました。
ということで今回は、**「ArduinoでDMX信号を受信して、ステッピングモーターを回す装置」**を作っていきます。
(余談ですが今回製造コストをできるだけ下げるためにPICも検討したのですが、自分の経験値が低く時間も無かったことから断念…いつかリベンジしたい。)
##メカ設計
さぁ始めるぞとなった時、まずはメカの設計をします。先にメカを設計するのは、物がないと先に回路を作っても動作確認ができないという点もありますが、部品によっては調達に1週間とかのスケールで時間がかかったりするためです。
###必要な部品を決める
まず絶対必要なのはモーターなので、そこから決めていきます。
モーターと聞くとミニ四駆に使われるようなDCモーターを想像されるかもしれませんが、今回使うのはステッピングモーターと呼ばれるモーターです。
制御が複雑になりますが、特定の角度に向けて回転させることができ、1ステップ1.8度や0.9度というステップ単位が決まっているので、動く角度を細かく指示したり、今自分がどの位置にいるかを把握することができます。近い事ができるものにPWMサーボがありますが、PWMサーボと比べた場合比較的静かに駆動でき、高トルクなものが充実していること、回転角度に制限が無いこと等が特徴です。
今回使うのは一般的なバイポーラ型のステッピングモーターです。普段は個人にも販売しているオリエンタルモーターやシナノケンシを使うのですが、今回数が多くてもうちょっと値段を抑えたかったので、ミスミからフーシンモーターの60角タイプを選びました。
ミスミは様々な工業用品を販売していてるのですが、ネット上で注文ができCADデータも商品ページから簡単に取得できる非常に便利なECサイトです。残念ながら対象は個人事業主を含む法人との取引のみなのですが…。
個人で制作等をされる場合は、モノタロウなどが良いでしょう。安いのでアリババを使ってる方も多いようですが、個人的にはリードタイムが不安だったりするのでまだ使ったことはありません。個人制作とか、納期に余裕がある案件で使ってみたい
モーターを中心に設計をします。自分の場合はrhinocerosを使っています。四隅の柱はアルミフレームという工業用の部材を使いました。好きな長さで発注することができるのでこういう構造物を作るのに便利です。自主制作にも使っています。工業系の製品は最近だとCADデータを公開している所が多いので、そういったデータをダウンロードしてCADソフト上で組み立てることができます。
###モーター軸へ部品の取り付け
最初のGIF動画にあったようにモーターへアルミフレームを取り付けなければいけませんが、モーターから出ているのは軸と呼ばれる金属棒で、何か取り付け用のネジ穴とかがあるわけではありません。そのためアルミフレームを取り付けられるようシャフトホルダをかますことにしました。上のグレーの円柱がモーター軸、黄色?のパーツがシャフトホルダです。一般的にモーターの軸はDカットと呼ばれるフラットな面があり、そこに横からイモネジを挿入してパーツを固定します。これによって、軸径が合っていれば芯がほぼ揃った状態でパーツを組み付けられるわけです。
###売ってない部品は発注する
赤と紫色の板はモーターとアルミフレーム、そして吊り下げ用クランプと落下防止ワイヤーを付けられるようにいくつか穴を空けてあります。
もちろんこんな板がピッタリ売ってるわけがないので作る必要があります。レーザーカッターで切れそうな形ですが、強度が心配なので、初めて板金屋さんに発注することにしました。上図のようにrhinocerosで寸法図を書き出していきます。色々ルールがあるらしいので、ググりながら引いていきました。
最近はネットで頼める板金屋さんも増えていて、今回は曲げ加工ドットコムというサービスをしている谷川工業さんに発注してみました。ここは、12時までに決済を済ませると当日発送してくれるという爆速の板金屋さんです。実はちょっと寸法図にミスがあったのですが、それも朝早く連絡が来て確認をしていただき、本当に当日出荷してくれました。
「レーザーだと当日出荷できないので、タレパン加工という方式で穴あけなら当日出荷できます、ただ長穴がちょっと汚くなります」という点もお伝えいただき、今回は早いほうが良かったのでタレパン加工でお願いしました。確かにちょっと長穴の側面がギザギザしています。
###試作の組み立て
とまぁこんな感じで設計と発注を繰り返します。今回はそんなに複雑な機構ではなかったのでほぼ設計→発注の1サイクルでしたが、組み立ててみてから修正することも度々なので、余裕を持ったスケジュールを組みましょう。(とはいえ今回もギリギリだったー…)
あとはアマゾンで舞台用の吊りクランプ+ワイヤーセットを購入して、上のプレートに取り付けます。
下の部品は、取り付けが楽かなと思ってカメラ用品のクランプを試しに付けてみたけどボツった品。
##回路設計
試作の組み上げが概ね完了したので量産用のパーツを発注しますが、それらが届くまでの間に回路設計を行っています。メインを煮込んでいる間にちょっとしたサラダを作る感覚で、機構部品を発注している間に制御回路の方を設計&テストしていきます。
今回は部品をできるだけ小さくまとめてみたいのと、ちょっとした理由(後述)でATMEGA32u4が載っているArduino Microを使います。
これをソフトウェア処理の頭脳とし、加えてArduino単体では出来ない「ステッピングモーターの駆動」と「DMXの受信」を実現するためのモジュールを用意します。
###L6470でモーターを駆動する
一般的にモーターの駆動は、Arduinoのようなマイコンで使うよりも高電圧・高電流が必要になりますので、直接Arduinoのデジタルピンにモーターを繋いで「はいどうぞ」とは行きません。それ相応のモータードライバが必要です。このL6470というドライバICは、電圧設定や加減速のコントロールができたりマイクロステップ駆動も可能なため、クリエイティブ表現的な用途にも向いていて、ステッピングモータードライバの中では個人的にオススメなモータードライバです。
本体はSTマイクロのチップですが、ストロベリーリナックスや秋月電子でキットが販売されています。
SPI通信という通信方法でコントロールするので、ArduinoにあるSPIライブラリからコントロールすることができます。
こちらに自分用のArduinoライブラリを上げてみました。基本的にはSPI通信とL6470ドライバのコマンドのラッパーをしているだけのものです。
配線などはそれぞれのドライバに付属の説明書か、北の国から電子工作(仮)さんの記事がとても分かりやすいので、こちらを見ていただくと良いと思います。
###ArduinoでDMXを受信だけする
ArduinoでDMXと言えばDMXシールドがありますが、なんかやたら高いです。昔は色々なところで置いていた気がしましたが、最近だとamazonかRSコンポーネンツくらいしか置いてない印象。
受信するだけだったら、**LTC485**という150円のICを一個付けてあげるだけでArduinoからDMX受信ができるようになります。
DMXの物理層規格であるRS-485はData+/Data-/GNDの三線で、普通のシリアル通信を差動通信方式でやりとりしています。
上図はLTC485のデータシートから持ってきたピン配置です。このICを
Arduino受信ピン(0/RX) ↔ (1/RO)
Arduino5V ↔ (8/Vcc)
DMXのGND ↔ (5/GND)
DMXのDATA+ ↔ (6/A)
DMXのDATA- ↔ (7/B)
という要領で接続していきます。L6470と合わせて回路にすると、このような感じ。
L6470のインターフェースは、BUSYやSTEPクロックを使わないミニマム構成なので6箇所接続します。ちなみにこれはストロベリーリナックスのキット上でのピン配置図。LTC485は必要なピンをArduinoとDMXに接続し、今回使わない出力用のピンはGNDに降ろしておきます。
ちなみにここでArduino Microを採用した理由なのですが、LeonardoやMicroで使われているATMega32u4はUSBの通信機能を自分で持っているので、ハードウェアシリアルのD0,1ピンが他の機器で塞がっていてもArduinoIDEからプログラムを書き込むことができます。ATMEGA328系のArduinoだと書き込む時にこのピンをジャンパーとかで付け外ししなければならないので、実は地味に便利なのです。
DMXケーブルは規格上5ピンか3ピンのXLRなのですが、地味にデカいし、コネクタを用意しようとするとユニバーサル基板ではやりづらいので、安いXLRを一本片方だけ切ってXHコネクタを圧着、そこから先のデイジーチェーンもXHコネクタにしてしまいました。
ENTTECのOpenDMX EthernetからArt-netで飛ばします。
シリアル通信の読み取りはDMXSerialという素晴らしいArduinoライブラリがあったので、こちらを活用しました。250kbpsと速度も早いし、ブレイク信号の仕様が若干変なので、こういうライブラリを使うのが吉です。(最初PICでやろうとしたけどこの辺のパースができずに断念、Arduinoでライブラリ検索したら秒で出てきた…)
#include <EEPROM.h>
#include "l6470duino.h"
#include "DMXSerial.h"
using namespace l6470duino;
driver Driver;
int startCh = 0;//DMXのスタートアドレス
void setup()
{
DMXSerial.init(DMXReceiver);
/* 中略 */
}
void loop()
{
unsigned long lastPacket = DMXSerial.noDataSince();
if (lastPacket < 5000) {
byte dmx[4];
for (int i = 0;i < 4;i++)
dmx[i] = DMXSerial.read(startCh + i);
/* 中略(モーターの制御) */
}
}
このような形で、DMXから送られてくるバイト列を取得することができました。
byte型のdmxという配列に入ってきた情報から、モーターの挙動を制御します。
startChというのはユニット機器の先頭チャンネルです。DMXは512チャンネルのバイト列なので、自分が何番目から何チャンネル分のデータを使うかをここで設定する必要があります。
DIPスイッチ等でハード的に設定できても良いのですが、今回はプログラムで直接指定してしまいました。
スケッチに書いておくと、プログラムを修正する際にうっかり同じチャンネルにしがちなので、setup関数内に以下のような形でEEPROMに書き込んでおくと便利です。
bool writeNewChan = false;//書き込む時true
if (writeNewChan)
{
//ユニット番号(今回は9台なので1~9)
number = 0;
//EEPROMに自分のユニット番号を書き込む
EEPROM.put(0, number);
}
else
{
//EEPROMから自分のユニット番号を読み出す
number = EEPROM.read(0);
}
//オフセット+1ユニット4ch消費するので、ユニット番号からDMXのスタートアドレスを計算
startCh = 2 + number * 4;
##組み立て
回路設計が出来たくらいで量産用のパーツも届き始めたので、ゴリゴリ組み立てていきます。
自分は手先が致命的に不器用なため、基本的に追加工なしでボルト締めだけで組み上がるように設計しました。
アルミフレームだけはプレートに垂直に固定する必要があるので、タップを切りました。これも発注できはするんですが料金倍になるので…
タップを切るというのはネジ穴を作る事で、ドリルで穴を開けるのに近い要領で、アルミのような金属に雌ねじを作ることができます。
右が出荷された時点、左がネジ穴を開けた状態です。写真は手開けなのでちょっと汚い…けど普通にM5ネジがするすると入ります。
1ユニットにつき4本 x 10台 x 上下2穴なので80本ノックです。タップは大体3/4回して1/2戻す…みたいな感じで開けていくので手でやると死にますが、スパイラルタップを使うと切子が外に出てくるので電動ドリルで一気に開けられて便利です。
ボルトも1ユニットで20本くらい使います。
今回吊るす高さは4.5m程度。真下ではありませんがかなり近い場所に人が近づくので、ネジが緩んで部品が落ちてきたりしたら即、事故につながります。
落下防止のワイヤー等も付けていますが、ボルトは振動に弱く、かなりキツく締めても簡単に緩んでしまいますので、そういう時はロックタイトのような接着剤を付けておきましょう。
これはネジ止め用の接着剤で、振動のような短い時間力が加わってもネジがゆるみにくくなり、外したい時は力を加えれば接着剤が取れて再び外すことができるという便利な接着剤です。
ロックタイトを付け、照明用クランプと落下防止用のワイヤーも取り付けたので、これで安心して吊るすことができました。デイジーチェーンケーブルが作るカテナリー曲線がキレイですね。
##TouchDesignerでコントロール
やっとQiitaらしい見出しが出てきました。
ArduinoでDMXを受信できるようになったので、Touchdesignerで制御することができます。
###DMXout CHOP
TDだと、ENTTECのDMX機器はDMXout CHOPから簡単に制御できるようになってます。
DMX,ちゃんと書くとDMX-512の規格では、512チャンネル分の、0から255までの数字を送ることができます。
DMXout CHOPでは、シンプルにチャンネルの並びがそのままDMXの信号として変換されて送られていきます。つまりここに値を突っ込めばそれをDMXプロトコルとして送ってくれます…超便利。
今回のモーターユニットでは、角度の指定に2チャンネル、電圧や加減速の設定コマンド用に2チャンネル使用しているので、[角度H, 角度L, コマンド番号, コマンド引数] [角度H, 角度L, コマンド番号, コマンド引数] [角度H ...と続けてあげることで複数分の制御信号を送ることが出来ます。
###角度の指定を2バイトに分けて送る(ビット演算)
シンプルにモーターに角度を送るだけなら1チャンネルを角度情報とすれば良いのですが、255段階はちょっと少ない気がします。せっかく無限回転が可能なステッピングモーターなのに、マイクロステップ制御では1周25600ステップなので3.6度しか回せません。Arduino側で回転量を何倍かしてあげることもできますが、そうすると単位辺りの角度が大きくなるので、微調整が効きません。
演出上の余裕として2〜3回転はして欲しいので、2ch=2バイトで角度を指定できるように、scriptCHOPでビット演算を行います。このような手法は、同じようにDMXで制御する市販のムービングライトでも用いられています。
def onCook(scriptOp):
scriptOp.clear()
val = scriptOp.inputs[0][0][0]
val = int(val * 200 * 128)
h = scriptOp.appendChan("ang_H")
l = scriptOp.appendChan("ang_L")
h[0] = val >> 8 & 255
l[0] = val & 255
return
valを1周1.0の角度として、モーターのステップ数200とマイクロステップ量128をかけています。
そして追加したチャンネルのang_Hに上位8ビット、ang_Lに下位8ビットを入れてあげることで、65536段階の角度指定ができるようになります。
もちろんArduino側でもこれをパースしてあげる必要はあり、以下のように記述します。
int16_t pos = dmx[0] << 8; //ang_Hの値を8ビットシフトして格納
pos += dmx[1]; //ang_Lの値を、ang_Hの下8ビットに加える
Driver.Goto(pos); //16bit65535段階の位置情報としてモーターに送る
撮影当日までに動きのパターンを作らねばなりませんが、見え方が分からないのでシミュレーションもTDの中でやってしまいます。
角度の変換をしながら、シミュレーション用のSOPも同時に回転させて、それを見ながら演出を決めていきます。
DMX用のCHOPと、シミュレーション用のSOPを吐き出すContainerを作りました。今回は9台使うのですが、それを1個のコンテナで修正したりするとごちゃごちゃしてきそうだったので、1台分の制御ユニットを作って、Replicator COMPで制御する台数分のContainerを複製しています。この方が修正や機能の追加も一括で行えるので、非常に便利でした。
DMX制御する時TouchDesignerめちゃ便利じゃん…と実感したのがこれなのですが、Animation COMPを使うと、時間軸で変化するCHOPのキーフレームを打つ事ができます。デフォルトは下のタイムラインと連携しているのですが、Playmode をUse input indexにするとフレーム番号を指定してコントロールすることができるので、TimerCHOPと組み合わせれば複数の時間軸を自由に再生することができます。
これのおかげで結構ギリギリまでメカ制作の方に時間を割けましたし、当日状況を見ながらの微調整も比較的スムーズに行う事ができました。
若干UIとか、配色が見づらいきらいはあるのですが…モーターのコントロールくらいで考えると、相当便利な機能だと思います。このくらいのシンプルな連携
であれば、サクサクバリエーションを組んでいけました。
##完成!
これで、機構の設計をしてからTouchdesignerで制御するまでの流れをおおまかざっくりとではありますが、追うことができました。
これを熟読してそのまま真似れば同じ事ができる、というところまで丁寧に書ききれなかったのが恐縮ですが、検索すると詳細が分かるようなワードをできるだけ散りばめてググラビリティ高めな状態にしてみたつもりです。
機械はコピペできないのでどうしても自分の手を動かして知見を溜めていく必要があるようです。この記事がきっかけになって動き者にトライしてくれる人が周りに増えたら良いな〜と思っております。もしこういうことに興味がある学生さんなどいましたらお声がけください!フリーランスでのメカ開発は必要な手数にとてもムラがあるので、初台方面は色んなタイミングで人手を必要としています。。
いつかこういうフリーのメカ使いが増えていって「構造作家100人」ていうムック本が出て欲しい。