2019/09/11

MIDI 機器(リズムマシン R-8MK II)をコントロールしてみた

ギターの練習のお供にリズムマシンを使う時に、例えば8ビート1小節のパターンを延々と流しながら、というのは良くあるんではないかと思います。ただ、曲によってはAメロとBメロではパターンが違ったりするのに同じパターンで続けてしまったりするのですけど。

もちろんリズムマシンでパターンをいろいろ用意して、それを繋げて1つの曲に仕立ててカラオケがわりにそのパターンを流せば気持ちよく練習ができるとは思うんですが、まず曲を準備するのが面倒臭い。

とりあえず Aメロの基本パターン1小節、Bメロの基本パターン1小節がスイッチ1つで切り替えられるなら、まぁいいんじゃない?ということで、あまりお金をかけずにこれを実現する MIDI OUT 機器を作ってみます。

1. 簡単仕様


  • リズムマシンのターゲット Roland R-8MK II (手持ちがこれなので)
  • MIDI OUT コントローラのマイコンは micro:bit (手持ちのパーツを流用)
  • リズムマシンには A, B の2つのパターンを準備
  • リズムマシンはパターンプレイモードでパターンをあらかじめ実行
  • ボタンを押すと A, B のパターンを切り替える
もう少し機能をつけたいのですが、とりあえず最低限のやりたいことを実現します。
最初は Arduino で作ってたのですが、モーター回すのに micro:bit 使っていて、ボタンも備えられていることから micro:bit で実装してみました。

2. 実装イメージ

3.3V 電源の構成。本当に簡単簡単。4番ピンを 33ohm を通して 3.3V にプルアップ。5番ピンは 10ohm を通して UART の TX に。ここでは micro:bit の P2 を割り当てています。丁寧にやるなら 2番ピンとシールドの外側は GND に。ただし、それをやっていいのは MIDI OUT のみ。

ちなみに5V 系のマイコン例えば Arduino だったら 220ohm の抵抗を両方に使えばいいですね。


3. プログラム

シリアルの端子の送信を P2 に割り当てます。P1 はおまけ。

ボタンを押したらプログラムチェンジを送ります。プログラムチェンジは 2byte 構成。

最初の1バイトでプログラムチェンジのコード 0xC0 に CH 番号 - 1 を加えたもの。続いて、プログラム番号は 1バイトを送ります。

ブロックエディタだとバイナリーのデータを送るブロックがないので、この部分のみブロックエディタから JavaScript エディターに切り替えて入力します。ついでに関数にしてしまいます。

pins.createBuffer(2) で 2バイトの配列を準備。setNumber(変数, インデックス, 値) で配列の要素に値を設定。serial.writeBuffer() で準備した配列を送信します。


4. 実行
4.1 R-8MK II の設定

必要な設定は

MIDI -> TX CH -> 10CH

MIDI -> FUNCTION -> PGM CHANGE = ON
のみ。
パターンを二つ用意して、パターンプレイモードで START しておきます。


4.2 Play

A/B ボタンを押せばそれぞれにアサインされたパターンに切り替わります。

本当はフットスイッチを付けたいところ。デモなんで、お手軽に micro:bit のスイッチを使ってます。

CASIOPEA の Street Performer より


5. 次のステップ


  • フィルイン機能1
    A または B メロパターンを実行中にフィルインボタンを押すと、AまたはB用のフィルインパターンを1小節実行して、また元のパターンに戻る
  • フィルイン機能2
    A/B 切り替えボタンを押した時に、A->B 切り替え時フィルインまたは B->A フィルインパターンを自動的に1小節挟む
  • スタート、ストップトグルボタンの追加
  • テンポの自動取得
    フィルイン機能を入れるのにはテンポがわからないと適切なタイミングで次のパターンが入れられないと予想されます
  • 筐体とボタンの強度を上げる
    今のでは足で踏むとすぐ壊れます

というのをボチボチ実装していければいーなと思います。が、やるんだろうか。

6. 解説
ハマったところをメモがわりに解説しておきます。

6.1 MIDI 端子のピン配置

まずMIDI 規格書はこちら。CA-033 が電気的規格を理解するのに丁度いいです。
これがすごくハマりました。使う端子はたったの2つ。4番と5番。これがどちらかわからない!制作記事をみても多くが MIDI IN の回路だったりして。テスターのダイオードチェック機能を使えば MIDI IN 回路のフォトカプラの入力の極性から4番、5番端子が特定できそうなものだけれど、サージなどからの保護用のダイオードがパラレルに逆極性で入っているので、どちらもダイオードのアノード、カソードに見えてしまう。あと、MIDI IN - MIDI OUT はストレートケーブルで繋がるので、MIDI IN の 4 は MIDI OUT の 4 というように同じ番号同士がケーブルで接続されます。

結局こちらのブログの記事が助かりました。

CA-033 の規格書はどっちから見たんだ?オスコネクタ目線?? ちなみに IN 側も OUT 側も端子配置は同じ。正しくは OUT 側は 4番、5番の間に挟まれた 2番とシールドの外側は GND に落としますが、ここではサボっています。写真だと手前の空いている二つのピンがシールドで、奥の半田付けされたジャンパーピンの間のピンが2番です。ノイジーなステージでの使用を考えるならちゃんと GND に落とすべきですね。ただし IN 側はこれらのピンを GND に直接は落としません。浮かせるか、0.1uF のコンデンサを介して GND に落とします。折角フォトカプラで分離してるのに GND を直接ショートしたら意味ないということかなと思います。



6.2 MIDI OUT の回路と抵抗値

ここも最初は理解できませんでした。電流ループとか書かれてもねぇ。
結局、MIDI OUT 側の回路は、H 出力時、MIDI IN のフォトカプラ入力に 5mA 程度の電流を流し、L 出力時には電流を流さないという回路を考えればいいようです。電源電圧は 5V である必要はなく、3.3V でも良いのです。なぜならフォトカプラの入力に繋がる回路は発光ダイオードなので、そのダイオードが光る電流を流せばいいからですね。
ちなみに OUT 側の MIDI 端子 4番が電源電圧側(5V or 3.3V)と覚えれば良いです。フォトカプラのアノード側が繋がるので。

ところで抵抗はフォトカプラを動かす回路の電流制限という意味とショートした時の保護という意味で入れるようです。



VTX=5.5V RA=RC=220ohm
VTX=3.3V RA=33ohm, RC=10ohm


6.3 MIDI データフォーマットと R-8MK II


もう少し研究する必要があります。とりあえずプログラムチェンジだけ使いました。
0xC0 + (CH - 1), Pattern No. の 2byte 構成。

電池切れました。おしまい。

2019/09/08

micro:bit + LV8548MC (ステッピング モーター編)

責任感ゼロ、いじり放題の趣味のプログラミングやブログの書き込みは気楽でイイですよ。

さて、お待たせしました!ステッピング(ステッパ)モーター編です。micro:bit と LV8548MC を使って回してみます。ほとんど新しくなった LV8548MC のパッケージの解説となります。

ハードウェアの準備

モーターを除けば DC モーターと同じです。まずは前の記事を。

モーターはバイポーラ型ステッピングモーター MDP-35A を使いました。ググると仕様書が見つかると思いますが、4端子 A, A(上の線つき), B, B(上の線つき)で、A, B 二つのコイルそれぞれブレッドボードに刺さるようにピンヘッダを半田しました。


これを DC ブラシモーターのときに組んだブレッドボードに刺します。


LV8548MC の OUT1, OUT2, OUT3, OUT4 に先程のピンヘッダを刺します。
ハードの準備はこれでおしまいです。

ソフトウェアの準備

これも DC のソフトウェアで説明した通り。同じパッケージにステッピングモーターのブロックを追加しました。以下の GitHub の URL を拡張機能の追加で指定してください。詳しくは前回の記事で。

https://github.com/ttrsato/pxt-lv8548mc.git

ステッピングモーターブロックの説明

DC からいっぱい追加したので迷うかもしれませんが、最低限必要なものは STEP カテゴリーの最初の三つだけです。


ちなみに DC 用と混在できません。間違わないよう先頭に S: と書かれているのがステッピングモーター用。D: が DC モーター用です。

設定

set stepper で IN1〜IN4 の設定をすれば準備完了です。どのピンでもそれぞれが被らなければ構いません。プルダウンメニューから選んでください。全部のピンが見当たらない場合はマウスのスクロールで残りが見えると思います。
回したいモーターの仕様書をみて、A, B コイルの端子を調べて、それぞれのコイルの両端を A-A', B-B' に割り振れば良いです。

あと、Excitation(励磁)方法を選びますが、よくわからなければ 1/1(Full step, 2相励磁) を選んでおけば良いです。1/2 は(Half step, 1-2相励磁)。LV8548MC はこの2種類の励磁方法のみ選べます。マイクロステップをしたい方は別な IC を選んだ方がいいです。オンセミの Solution Kit なら、LV8702 か LV8714 ですね。
ちなみに 1/1 の場合、48ステップで軸が一回転するステッピングモーターの場合、48ステップで一周。1/2 の場合は倍の 96ステップで軸が一周します。

初めてのステッピングモータープログラム


3つのブロックを使っただけの簡単なプログラム。
ボタン A を押したら Forward 方向に48ステップ回って、Reverse(反対方向)に48ステップ回って、Forward に 24ステップ、Reverse に24ステップ回って終了します。


こんな感じ。


この run stepper ブロックは回転する方向 (Forward/Reverse) と動かすステップ数、速度を指定することができます。ms/step は 1ステップを動かす時間です。ms (1秒の1/1000) で指定します。最短は 1ms/step です。ただこの速度で動くかどうかはモーターと負荷次第です。プログラムの処理速度もどうだか。ちなみに負荷が重いなど期待した速度で回らなくなることを脱調と言います。


最後に指定しているのが stop stepper。ここでは Free(励磁無し) と Hold(励磁保持) を選択できます。run stepper では回し終わった後に Hold(励磁保持)状態になっています。電流が流れたままなので、コイルは磁力を持ち、軸は弱い力では動きません。Free ではコイルの磁力は無くなるので、軸は弱い力で回すことが出来るようになります。Hold 状態は電流を消費しますし、モーターがとても熱くなるので、位置を保持する必要がなければ Free しておいた方が良いかもしれません。

とりあえずこれらを組み合わせれば大体好きなことは出来るのではないかと思います。

残りの基本ブロック


run stepper accel と run stepper trap の二つがあります。

run stepper accel
加速、減速を実現するブロック。start の速度から stop の速度まで、段階的に steps で指定したステップ数回転します。

run accel デモ

run stepper trap
台形駆動します。台形駆動は、だんだん速く回転し、一定速度で回った後、止まる前に徐々に速度を遅くする機能です。グラフを書くと台形なのでそんな名前です。

run trap デモ

変換ブロック

残りは変換ブロックです。回す単位や、速度の単位を変えたい時に使います。物によっては STEPPER units ブロックで初期設定を入れる必要があります。
おまじないというわけではないのですが、


set steps/round を設定しておきましょう。今回使用した MDP-35A はステップ数 48 なので、48を設定します。ステップ角は 7.5° (360/48) なので、


set deg/step で設定しても同じです。これらを指定することによって、回転を角度や回転数で指定したり、速度を rpm で指定すると期待通りに動くようになります。つまり以下のブロックがようやく使えるようになるわけです。もちろん 1ステップ以下の動作は出来ないので丸められます。


これらのうち、STEPPER to steps 使うと最初のプログラムはこういう風に書き直せるわけです。


2周、1周、180°、90°など、直感的に値を設定することが出来るようになります。
応用編として、回転するステージがギアを介してステッピングモーターに繋がっていて、1 ステップで 0.1° 動くシステムなら、set 0.1 deg/step を設定すればステージの回転角度を与えて動かすことが出来ます。ちなみに set mm/step を設定しておくと、mm to steps を使えるようになります。これはスライダーなどのボールネジを使った直線駆動する機構に対する設定で、1ステップで移動する距離を mm でセットすると、mm to steps で移動したい距離を与えるとステップ数を返すようになり、上記の角度指定のように直感的な指定が可能になります。

STEPPER to ms/step は、速度の単位を変換するブロックです。
Hz や、rpm でステップの変化速度を与えたい場合はこれらを使ってください。

速度を周波数 Hz で与える

ちなみに上記のコードを実行すると、あれ?となりませんか。1Hz は 1秒間に回転する回数なので、1Hz だったら 1秒で 1回転するはずじゃんと。残念ながら 1ステップ移動する速度が 1Hz(1秒) です。一周するのに 48ステップなので遅いんです。rpm 指定も同様です。仕様です。いやいや、一周単位での Hz やら rpm で設定したいという方は Hz または rpm で与える数を rounds to steps で囲ってから Hz/rpm to ms/step に与えてください。


rounds to steps は一周のステップ数を掛けた答えを返すので、辻褄が合うんですね。

以上、で LV8548MC を使ったステッピングモーター駆動のためのブロックの説明はおしまいです。残念ながら micro:bit が一生懸命駆動パルスを生成しているので、モーターを回している最中は何も出来ませんので悪しからず。

おまけ

あっているかどうかわからないけど、台形駆動のパラメータの計算に苦労したので晒しておきます。面倒臭いのでバグがあると言われないと見直したくないです。間違いがあったら教えてね。

台形駆動は、トータルカウント(ステップ)数 Ca と、トータル時間 Ta、加減速時間 T1 と初期スピード S1 のみを与えて、残りは計算で求めています。

加速期間は速度 S1(ms/step) から S2(ms/step) まで徐々に1ステップの時間が短く(長く)なります。この時間を全部足したのが T1 になります(8)。また、T2 の時間をその時の1ステップ速度 S2 で割ったのが T2 という二つの方程式を解けばいい(4)。なんだけど意外に面倒臭い。答えは (10)。

台形駆動

余談。ステップ時間で見ると、台形じゃなく、上記のように台形の逆さま。じゃぁと速度に直すと 1/S1 とか逆数になるので、直線じゃないです。ただ周波数に変換すると S1 は実際は時間です。1/t=f なので周波数にすると台形になって、しかも直線になります。そういうこと?

今回から数式を埋め込めるように TeX のコード解釈できるようにした。TeX なんて学生の頃以来ですよ。でも数式書くならいまだに TeX いいよね。最高です!クヌース先生。

\begin{align}
T_{ams}=2 T1_{ms}+T2_{ms}
\end{align}
\begin{align}
C_{asteps}=2 C1_{steps}+C2_{steps}
\end{align}
\begin{align}
\Delta s=\dfrac {S1_{msps}-S2_{msps}}{C1_{steps}}
\end{align}
\begin{align}
C2_{steps}=\dfrac {T2_{ms}}{S2_{msps}}
\end{align}
\begin{align}
T1_{ms}&=(S2_{msps}+\Delta s)+(S2_{msps}+2\Delta s)+\cdots +(S2_{msps}+C_{asteps}\Delta s)\\
&= \sum^{C_{asteps}}_{i=1} (S2_{msps} + i \Delta s)\\
&= C_{asteps}S2_{msps} + (1 + 2 + \cdots + C_{asteps})\Delta s\\
&= C_{asteps}S2_{msps} + \dfrac {C_{asteps}(C_{asteps} + 1)}{2} \Delta s
\end{align}
\begin{align}
(C_{asteps} - 2)S2_{msps}^{2} + (C_{asteps}S1_{msps} - 4T1_{ms} - T2_{ms})S2_{msps} - T2_{ms}S1_{msps}
\end{align}
\begin{align}
S2_{msps} = \dfrac{-(C_{asteps}S1_{msps} - 4T1_{ms} - T2_{ms}) \pm \sqrt{(C_{asteps}S1_{msps} - 4T1_{ms} - T2_{ms})^{2} +4(C_{asteps} - 2)T2_{ms}S1_{msps}}}{2(C_{asteps} - 2)}
\end{align}



2019/09/01

micro:bit + LV8548MC (DC モーター編:プログラミング)

前回、micro:bit + LV8548MC (DC モーター編:とりあえず ハード)ではハードウェアに関してクドクド書きましたが今回は micro:bit に拡張機能で LV8548MC のパッケージを追加して、LV8548MC のブロックを使ってモーターを回してみます。プログラミングと言いつつ、単なるパッケージのブロック説明ですが。

ステッピングモーターブロックの追加に伴って内容アップデートしました。

拡張機能のインストール


GitHub に上げたパッケージを指定してインストールします(オリジナル)。
ブラウザーで MakeCode を開きます。既存のプロジェクトを開いてもいいですし、新規のプロジェクトを開いてもいいです。ちなみに iPhone 上でもプログラム作れますよ!

ちなみにこの拡張機能は LV8548MCSLDGEVK の機能を参考にはしていますが、完全にゼロから作っていますし、インターフェースも異なります。オシロスコープの私物が無いので、思ったような波形が出ているのかやや不安ですが、動作的にはまぁ、そんなに間違いは無いだろうといった感触です。

プロジェクトを開きます

拡張機能をインストールするために、高度なブロック、拡張機能のタブをクリックします。

拡張機能のインストール

LV8548MC の拡張機能を探します。検索ウィンドウに、
https://github.com/ttrsato/pxt-lv8548mc.git
を入力します。

拡張機能の検索ウィンドウ

検索すると lv8548mc が見つかります。クリックすると一瞬でインストールされます。

lv8548mc が見つかった!

MakeCode のエディターに LV8548MC のタブが増えています。
あとは使うだけ。


ブロックについて


LV8548MC の DC モーター用ブロックは3つあります(減りました)。残念ながらローカライズはやり方がいまいちわからなく(以前トライしたときにうまくいかなかった)、そのうち対応します。誰か知ってたら教えてー。

  • 初期化ブロック

Set DC Motor は LV8548MC のCH1 (IN1, IN2) または、CH2 (IN3, IN4) に繋ぐ micro:bit の端子を指定します。一つのチャネルに一つの初期化ブロックが必要です。DriveMode は PWM 駆動時の非通電時の動作の指定です。Open または Brake の指定ができます。
ちなみに DC モーター用のブロックの頭には D: が書かれています。ステッピングモーター用ブロック(S: で始まるブロック)とは共用出来ませんのでご注意を。

  • 速度指定ブロック

モーターを回すブロックはこれ一つです。ステッピングモーターブロックの追加の時に見直されました。

モーターの回る方向は Forward または Reverse (反転) で指定。速度は 0〜100 の割合 (duty) で与えることができます。ある一定以上の速度になるとモーターが回転を始めます。ほどほどに。定格外の電圧を加えている時は注意です。

  • 停止ブロック

 モーターを停止させます。
止めるときには Open または Brake を選ぶことができます。Open はモーターは慣性に従い緩やかに停止しますが、Brake はモーターを急激に停止させます。

サンプルプログラム


簡単なサンプルプログラムです。
徐々に速度をあげて、徐々に速度を下げるを繰り返すだけのプログラムです。




次はいよいよ ステッパー (ステッピング)モーターです。



micro:bit + LV8548MC (DC モーター編:とりあえず ハード)

オンセミLV8548MC が秋月で取り扱いが開始されました!

LV8548MC は DC ブラシモーターx2 またはステッピングモーターx1、電源は 4V〜16V のモータードライバーです。

また、そのままでは扱いづかいので、aitendo からピッチ変換基板が2種類(その1その2)が9月上旬から販売されるようです。

オンセミの LV8548MCSLDGEVK ならば付属の Arduino micro を使ってハードウェアの準備をほぼする必要なくモーターを回すことができるのですが、ここではmicro:bit で LV8548MC を動かしてみます。しかも安価に。ではそのハードウェアの準備をします。

まずはピッチ変換基板を使って、モータードライバー IC を使いやすくします。
待ちきれないので、aitendo の既存の SOP-10 ピッチ変換基板 を使いました。できれば新しく販売される基板を使ったほうが良いでしょう。フットパターンが LV8548MC に適しているので半田付けの際に位置決めしやすいし、配線が太めなようなので、大電流を流したいときに安心です。

さ、お試しならばとりあえず既存の変換基盤で大丈夫です。こんな風に半田付けしました。IC をよく見ると横棒が書いてあるのですが、横棒が近い辺が 1 pin (VCC) と 10 pin (OUT1) 側になります。




まぁまぁな感じで半田付けできました。


1 pin (VCC) と 6 pin (GND) の間にはデータシートにしたがって、パスコンを入れました。奮発してセラミックコンデンサ 10uF/50V。これがまた IC より高い。。(150円@千石電商)。データシートでの指定は 0.1uF〜10uFなので、安定性と財布次第で適宜変えてください。パスコンなので、無くても動いちゃうかもしれませんが、電源がプアだと動作が不安定になるので、入れるに越したことはありません。とりあえずセオリー通りに IC のなるべく近くに置きました。

micro:bit と DC モーターとの接続

micro:bit と LV8548MC の GND を一緒にすることを忘れないように。また 10uF のパスコンとは別に、100uF/50V の電解コンデンサーを LV8548MC の VCC - GND 間に入れています。パスコンは動作の安定のためですが、こちらは破壊防止です。壊したくなかったら入れておいたほうが無難です。
モーターが駆動しているときにモーターのコイルにエネルギーがたまります。モーターを急停止すると、このエネルギーをもとに回生電流が流れるのですが、ACアダプターなどの電源がこれを吸収しきれない場合、IC に印可される電圧が急上昇することがあり、IC が破壊に至る場合があるからです。100uF はこの上昇を抑える作用があります。
ちなみに LV8548MC の電源は手持ちの 6V/1A を使いました。LV8548MC は 4V〜16V で動作するので、この範囲の電源を接続してください。4V 以下では正常に動作しません。ちなみに、オンセミは LB1948MC という 2.5V〜16V で動作する LV8548MC とピンコンパチ(ファンクションも同じ)のモータードライバー IC もあります。4V 以下で動かしたい方はこちらを選択してもいいかもしれません。DigiKey などで取り扱いがあります。
モーターは子供達に破壊されたタミヤの2チャンネル リモコン・インセクトを分解して取り出したものです。

接続拡大

さてLV8548MC と micro:bit、モーターとの接続ですが簡単です。VCC, GND に電源、そして DC モーターを駆動するときは、

CH1: IN1, IN2 (OUT1, OUT2)
CH2: IN3, IN4 (OUT3, OUT4)
をペアとして接続してください。CH1, CH2 の定義は上記の通りとします。micro:bit でプログラムを書くときに指定するときに必要です。

IN1, IN2 および OUT1, OUT2 の極性にナーバスになる必要はないです。逆に回るだけなので、期待通りでなかったら接続を変えるか、ソフトの初期化の時の端子設定を逆にすればいいだけですから。

micro:bit と IN1〜IN4 を接続する必要がありますが micro:bit 側のピンは任意です(全部チェックしたわけではないですが)。また CH1, CH2 の両方のチャネルを接続しなくてもいいです。CH1 のみとか。IN1〜IN4 端子は内部でプルダウンされているので、何も接続していない場合は、例えば CH2 の IN3, IN4 に何も繋がない場合、OUT3, OUT4 はハイインピーダンスになるので問題ありません。

詳しくは LV8548MC のデータシートを参考にしてください。

ちなみに micro:bit に割り当てるピンに迷ったら、エッジコネクタとピンアウトの仕様を見てください。LED 表示やら、ボタン入力、アナログ入力など特別なファンクションに割り当てられていないのは P8 と P16 であることがわかります。自分の使いたい機能を持たないピンに割り当てれば良いと思います。
ただ、P0, P1, P2 以外の端子を利用しようとすると、Sparkfun などのマイクロビットブレイクアウトボード (リンクはマルツオンライン。色々な種類があって秋月などでも扱いがあります)が必要になります。上記写真では P13,14,15,16 に IN1,2,3,4 を割り当てています(これでは SPI 端子が使えません)。この手のボードを持っていない方は、まずは P0, P1, P2 を利用してみるのが良いかもしれません。

とりあえず DC モーターのハードはここまで。
micro:bit の LV8548MC 拡張機能パッケージやプログラミングについては次回