本間メモ

本間のメモです。  

202010

Stepping Motor - Motor Driver - ラズパイの連携について

(10/24現在、連携できていません >_< ) * Steping Motor (28BYJ-48) * Motor Driver (A4988) * ラズパイ (Raspberry Pi Zero WH)

Steopping Motor (28BYJ-48)の改造(4相5線式 -> 2相バイポーラ化)

基板の真ん中の配線(通常は赤いコード)部分をカッターで削ると、ユニポーラ→バイポーラになる
Ref: 週刊中ロボ43 28BYJ-48 その3 改造

Connection

Stepping Motor A4988 ラズパイ GPIO Memo
2B
2A
1A
ピンク 1B
STEP 22
DIR 17
EN 23
VDD 3.3V
GND(VDD) GND
VMOT 5V ACアダプタ
GND(VMOT) GND GND(5V ACアダプタ

Software library

pigpioを使いたいが、pigpioとA4988を連携した例がなかなか見当たらない。
Rpi.GPIOは例が多い模様。python-stepperを参考にした。
ただしpython-steppreもそのままでは動かない(型変換エラーなどが起きる)ので、同ライブラリをforkして、python3で動くように一部手直ししました。
[tatoflam/python-stepper/tree/musicbox]https://github.com/tatoflam/python-stepper/tree/musicbox

→GPIOの設定更新はできているらしいが、ステッピングモーターはまだ動かせていません(2020.10.23)

ToDo

  • A4988の可変抵抗の調整
  • 導通状況に関して再チェック

202009

MIDIデータ入力

谷林さんご提案のうち"発展2: MIDIデータ入力 の方法を少し試してみたので、共有します。  


MIDIファイルの入手・作成

  • 方法1) フリーで公開されているMIDIファイルを使う <-まずはこれがいい  
  • 方法2) ソフトを使って作成する  
  • 方法3) コードで書く

方法1) フリーで公開されているMIDIファイルを使う

例えばこのサイト(音の素材屋さん)で"オルゴール"で検索する。
オルゴール用であってもTrackが複数の曲もある(Channel(楽器に種類に相当)は1つ)。
Channel, Track, NoteなどMIDIのデータの取り扱いは後述。
同サイトのファイルはフリーで利用可能。商用利用は禁止。   

方法2) ソフトを使って作成する

例えばflat.ioではブラウザ上で作成・編集した曲をMIDIファイル(.mid形式)にExportできる。
無料利用では、選べる楽器の種類などに制限があるが、今回のデータ作成の用途なら無料利用で十分。

方法3) コードで書く

ライブラリを使うとMIDIメッセージを作ったりファイルに保存したりできる。
(ソース内の1音ごとに関数を呼ばなければなりませんが、演奏でのインタラクティブな処理であればこれを使うと良いかも)
midoの例:create_midi_file.py


MIDIファイルを読み込む方法

MIDIのデータ形式については、このサイトが詳しい   今回必要な情報は以下。  

必要な入力(と出力) MIDI
曲を再生する速さ (DCモーターの回転速度) "Tempo" または MIDIではなく固定値か別途に調整(最初はプログラム起動時の引数とか)?
どの音を(どのサーボモーターを) Messageの"Note"(60がド、62がレ、64がミ・・)
いつ鳴らすか MIDI Messageの"time"(1つ前のメッセージからの差分のtick数)

MIDIファイル(またはリアルタイムな演奏による入力)からパース(解析)して取り出すのは、(今回はpythonのgpioを使う想定なので)
pythonの midoが分かりやすいように思いました。

とりあえず音の素材屋さんで落としてきた ”パッヘルベルのカノン(オルゴール用)"のMIDIファイル(mbox_Pachelbel_canon.mid)をパースする。

  1. MIDIのメッセージを人間が読める形で出力する例 - parse_midi_file.py

$ python parse_midi_file.py mbox_Pachelbel_canon.mid  

実行結果

(中略)
note_on channel=0 note=91 velocity=0 time=94
note_on channel=0 note=57 velocity=81 time=16
note_on channel=0 note=93 velocity=91 time=0
control_change channel=0 control=64 value=0 time=0
note_on channel=0 note=78 velocity=0 time=11

"time"はややこしい。ここでいう"time"は、前メッセージ(前行)から当メッセージ(当行)までのtick数。
tickとは、1Beatの中を刻む回数。MIDIファイルのヘッダで指定する。
tempoとは、MIDIの世界ではMicrosecond per Beat(四分音符に割り当てるマイクロ秒数)。よく演奏などで使う "BPM"(Beat per Minute(1分あたりの四分音符の数))とは違うので注意。
tempoは、"set tempo”メッセージで、曲中に変更される場合もある。
tickとtempoで、実際にどれだけ待つかが決まる。
midoでは、tickとtempoを元にこれを秒に直す関数がある (tick2second())。

  1. 必要な情報(Tempo, Note, Time)を抽出・計算して出力する例 - parse_midi_file_with_time.py  

$ python parse_midi_file_with_time.py mbox_Pachelbel_canon.mid 

実行結果

Ticks per beat: 480
Track 0:  Grand Piano *merged
Tempo is changed to 240000
Tempo is changed to 681818
MIDI note:62, time:0, delta_sec:0
MIDI note:93, time:0, delta_sec:0
MIDI note:93, time:131, delta_sec:0.186079495833
MIDI note:69, time:109, delta_sec:0.154829504167
MIDI note:90, time:0, delta_sec:0
MIDI note:91, time:120, delta_sec:0.1704545
MIDI note:90, time:20, delta_sec:0.0284090833333
MIDI note:74, time:100, delta_sec:0.142045416667
  • Tempo: Microsecond per beat。DCモーターの回転速度に合うように計算が必要。 
  • MIDI note: 音階。Note番号とサーボモーターの番号をマッピング。
    今回のオルゴールの音階の範囲内になるように、プログラムで上限・下限をチェック。
    また、入力するMIDIファイルそのものを編集。
  • delta_sec: 前回メッセージからの差分(秒数)。0の場合は前回と同じタイミングで鳴らす(和音)。

DCの回転速度は、MIDIから読み込まなくてもいい気もしますが、
曲として成立させるには、サーボを動かすタイミングとDCを動かすタイミングを同期する必要はあるため、
MIDIで入力する場合はやはり"Tempo"を使ってDCモーターを動かすのが良さそうです。


MIDIデータ入力のメリット

  • 入力をソフトウェアに任せられる
  • ありもののMIDIデータ(とその音楽演奏を目的にしたフォーマット)を使える
  • 広く使われているフォーマットでプログラムから操作しやすい  

MIDIデータ入力のデメリット

  • MIDIはフォーマットやデータの中身が独特でとっつきづらい。
    →今回の用途で使うデータは限られている。
    →オルゴール(MusicBox)用のMIDIファイルは比較的、データの内容が簡単。

  • 今回のオルゴールで演奏できない音階やトラックを含んでいるファイルを使う場合、不要なデータを読み飛ばす処理が必要
    →trackやnoteという決まった形式で指定されているので、チェックすればよい。

・・・ということで本間はMIDIデータの入力から進めてもいいのではと思っていますが、いかがでしょう・・。  


補足) piano-hatのexaples/midi-piano.py

githubのexamplesページのガイドラインに沿って、
必要なライブラリをインストールしてPiZeroで動かそうとしたのですが、Runtimeエラーで起動しませんでした。
pianohatのタッチセンサー入力を、 出力先としてのMIDIシーケンサーソフト(sunvoxまたはyoshimi)に渡すプログラムのようです。
特定のソフトにのみ対応しており、あまり汎用的な例でもなさそうなので、少なくともexamples/midi-piano.pyは参考にしなくて良いと思います。