HOME | Raspberry Pi | ビジネス書籍紹介 | 2026-01-04 (Sun) Today's Access : 296 Total : 1260994. Since 10 Sep. 2019

USB-MIDI
2022.09.16 / 2024.12.31更新

YouTube でも紹介しています。画像をクリックすると再生できます。

MIDIキーボードコントローラーはそれ自体には音声出力機能がないので、DAW(Digital Audio Workstation)ソフトや 音源モジュールなどに繋いで利用するのが一般的です。 今回は、以前にも紹介したAdafruit Music Maker FeatherWingを用いて直接演奏してみます。

■構成図

MIDIキーボードコントローラーには、Nektar Technology SE25 を使いました。
Arduino のアドオンボードである、USB HOST SHIELD にこのコントローラーを繋ぎます。
Arduinoボードは、Diecimila ATmega328です。
※Uno以前のArudinoからの大きな違いは、USBシリアル変換ICがFTDI FT232RLチップからの変更です。 Uno Rev3はATmega16U2、Rev1,Rev2はATmega8U2を搭載しています。

■Nektar Technology SE25■
Nektar SE25 は、25鍵 MIDI キーボードコントローラーです。

Nektar Technology SE25
●ベロシティ対応、ミニサイズの25鍵盤
●3つのベロシティカーブ(デフォルト、ソフト、ハード)
●6つのボタン : オクターブアップ / ダウン、PB1 / PB2、サステイン、パート2
●PB1 / PB2 ボタン : ピッチベンド*、トランスポーズ、ボリューム、パン、トラック**もしくはパッチチェンジ**を割り当て可能
●パート "2" ボタン : オクターブ、MIDI チャンネル、トランスポーズ、レイヤー、ラッチ(モメンタリー)を割り当て可能
●"S" ボタン : サステイン、もしくはモジュレーションを割り当て可能
●ボタンの第2機能として、トランスポートコントロールが可能
●接続 : マイクロ USB ポート(USB バスパワー駆動)

■USB HOST SHIELD
USB Host Shield は、Arduino 開発プラットフォーム用アドオン ボードです。 MIDIキーボードコントローラー接続端子の主流派、USB-MIDIへと移り変わっています。 Arduinoなどのマイコンと通信するためには、USB HOST SHIELDが必要になります。

シールドは USB ホストインターフェイスを提供し、キーボード、マウス、ジョイスティック、MIDI、デジタル カメラ、Bluetooth などの USB デバイスとのフルおよび低速通信を可能にします。

USB Host Shield Hardware Manual
USB ホストシールド

5V で使う場合
赤枠のピンをショートさせます。
電源選択「5V」と「3.3V」とマークされた 2 つのはんだジャンパー。 これらは、さまざまな電源構成に使用されます。 両方のジャンパーが閉じている場合の構成は、UNO、Duemilanove、Mega、Mega 2560 などの公式の Arduino に適しています。


【補足】3.3V で使う場合

赤枠のピンをショートさせます。

■Arduino Diecimila
Arduino Diecimila の ATmega328P-PU版です。



■Adafruit Music Maker FeatherWing

Adafruit Music Maker FeatherWing は、Feather Board のアドオンボードです。 MIDIモードに切り替えることにより、UART RXピンから 31250Kbaud MIDIデータを読み込ませ、シンセ/ドラムマシンのように機能させることができます。 ドラムとサンプルのエフェクトが多数組み込まれています。
詳細は下記の記事を参考にしてください。
MIDI制御/Adafruit Music Maker

■USB HOST SHIELDアドオンボードの接続

USB HOST SHIELD -  DIECHIMILA 
SCK[13] - SCK[13]
MISO[12] - MOSI[12]
MOSI[11] - MISO[11]
5V - 5V
GND   GND
SS[10] - SS[10]
INT[9]   9
電源ピンは、Arduino ボードの電源ピンに接続するために使用されます。
ICSP コネクタは、SPI インターフェイスを使用してデータを送受信するためにシールドによって使用されます。 このコネクタからの SCK、MOSI、MISO、および RESET 信号が使用されます。
※LEONARDO や MEGA2560 でも使えるように、ICSP端子を介して通信を行います。

まずは、USB HOST SHIELD のテストを行います。

写真左は、Raspberry Pi 3 model B です。Pimoroni Piano Hat を被っていますが、Hat は使っていません。 ラズベリーパイのOSは、Raspbian GNU/Linux 10 (buster) です。 ノートパソコンから、TeraTermによりラズベリーパイにSSH接続して、ビルドおよびデバイスモニターに利用します。

■サンプルプログラムのビルド
プログラミングには、GitHubから、USB Host Shield_ライブラリーをダウンロードして使います。

felis/USB_Host_Shield_2.0


まずは、USBH_MIDI_dump.ino をビルドして実行してみます。

ソースコードのビルドには、PlatformIOを使用しています。
Arduino開発環境構築 PlatformIO

$ mkdir diecimila
$ cd diecimila
$ pio init -b diecimilaatmega328
$ pio run -t upload

つぎに、USB HOST SHIELD に MIDIキーボードコントローラーを取り付けて、鍵盤を叩いてみます。

$ pio device monitor -p /dev/ttyUSB0 -b 115200

キーボードの鍵盤をド・レ・ミの順に叩いてみました。 デバイスモニター上には、MIDIメッセージが表示されています。
09 90 3C 48 ドの鍵盤を押す
08 80 3C 40 ドの鍵盤を離す
09 90 3E 53 レの鍵盤を押す
08 80 3E 40 レの鍵盤を離す
09 90 40 55 ミの鍵盤を押す
08 80 40 40 ミの鍵盤を離す

イベントコード(MIDIメッセージ)解説 09 90 3C 48
0x09 eventType
MIDIコマンドタイプ上位4ビットの値。 USB MIDIHOST SHIELD / USB MIDIライブラリが独自に出力するもので、標準MIDIコマンドには含まれません。 Music Maker に出力する際には省きます。
0x90 eventType<<4 | channel
MIDIコマンドタイプにチャンネル番号を付与した値。 MIDIコマンドタイプを上位に4ビットシフトして、そこにチャンネル番号との論理和を取ります。 この例では、チャンネル番号は0としています。
0x3C Note No.
音色番号
0x48 Velocity(0x01~0x7F)
鍵盤を押した強さ

■Music Maker への出力用に改造

それでは、先のUSBH_MIDI_dump.inoを改造して、Music Maker に UART接続によりMIDIコマンドを送信するように変更します。

$ vi src/usb_midi.ino
#include <usbh_midi.h>
#include <usbhub.h>
#include <SoftwareSerial.h>

#define VS1053_BANK_DEFAULT 0x00
#define GM_ACOUSTIC_PIANO   0x00
#define VELOCITY_FFF         127
#define MIDI_CHAN_BANK      0x00
#define MIDI_CHAN_VOLUME    0x07
#define MIDI_CHAN_MSG       0xB0
#define MIDI_CHAN_PROGRAM   0xC0
#define VELOCITY_MP           64

USB Usb;
USBHub Hub(&Usb);
USBH_MIDI  Midi(&Usb);

void MIDI_poll();

void onInit() {
	char buf[20];
	uint16_t vid = Midi.idVendor();
	uint16_t pid = Midi.idProduct();
//	sprintf(buf, "VID:%04X, PID:%04X", vid, pid);
//	Serial.println(buf); 
}

void setChannelBank(uint8_t channel, uint8_t bank) {
	Serial.write(MIDI_CHAN_MSG | channel);
	Serial.write((uint8_t)MIDI_CHAN_BANK);
	Serial.write(bank);
}

void setChannelVolume(uint8_t channel, uint8_t vol) {
	Serial.write(MIDI_CHAN_MSG | channel);
	Serial.write(MIDI_CHAN_VOLUME);
	Serial.write(vol);
}

void setInstrument(uint8_t channel, uint8_t instrument) {
	Serial.write(MIDI_CHAN_PROGRAM | channel);
	Serial.write(instrument);
	delay(10);
}

void setup() {

	uint8_t channel =  0;

	Serial.begin(31250);

	if (Usb.Init() == -1) {
		while (1); //halt
	}
	delay( 200 );

	// Register onInit() function
	Midi.attachOnInit(onInit);

	setChannelBank(channel, VS1053_BANK_DEFAULT);
	setChannelVolume(channel, VELOCITY_FFF);
	setInstrument(channel, GM_ACOUSTIC_PIANO);
}

void loop() {
	Usb.Task();
	if ( Midi ) MIDI_poll();
}

// Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll() {
	uint8_t bufMidi[MIDI_EVENT_PACKET_SIZE];
	uint16_t  rcvd;

	if (Midi.RecvData( &rcvd,  bufMidi) == 0 ) {
		switch(bufMidi[0]) {
			case 0x09: // Note-on
				bufMidi[3] = VELOCITY_MP;
				Serial.write(&bufMidi[1],3);
				break;
			case 0x08: // Note-off
			case 0x0B: // Continuous controller
			case 0x0E: // Pitch bend
				Serial.write(&bufMidi[1],3);
				break;
			case 0x0A: // After-touch
			case 0x0C: // Program change
				Serial.write(&bufMidi[1],2);
				break;
			case 0x0D: // Channel Pressure
				break;
			case 0x0F: // System Realtime message (non-musical commands)
				Serial.write(&bufMidi[1],1);
				break;
		}
 	}
}

コード解説
void MIDI_poll() {
  uint8_t bufMidi[MIDI_EVENT_PACKET_SIZE];
  uint16_t  rcvd;

  if (Midi.RecvData( &rcvd,  bufMidi) == 0 ) {
    switch(bufMidi[0]) {
      case 0x09: // Note-on
        bufMidi[3] = VELOCITY_MP;
        Serial.write(&bufMidi[1],3);
        break;
      case 0x08: // Note-off
      case 0x0B: // Continuous controller
      case 0x0E: // Pitch bend
        Serial.write(&bufMidi[1],3);
        break;
      case 0x0A: // After-touch
      case 0x0C: // Program change
        Serial.write(&bufMidi[1],2);
        break;
      case 0x0D: // Channel Pressure
        break;
      case 0x0F: // System Realtime message (non-musical commands)
        Serial.write(&bufMidi[1],1);
        break;
    }
  }
}
イベントタイプごとに対応したMIDIコマンドを送信します。
CommandMeaningparametersparam 1param 2
0x80Note-off 2key velocity
0x90Note-on 2key veolcity
0xA0Aftertouch 2key touch
0xB0Continuous controller2controllervalue
0xC0Patch change 2instrument
0xD0Channel Pressure 1pressure
0xE0Pitch bend 2lsb (7 bits)msb (7 bits)
0xF0(non-musical commands)
MIDIメッセージのタイプにより、メッセージの長さが異なるので、必要なバイト数を送信します。

MIDIキーボードでは、打鍵の強さが安定しないので、強さを固定に変更しています。
bufMidi[3] = VELOCITY_MP;

setup()関数内で、チャンネル指定、音量、音色(楽器)を指定しています。
また、MIDIのボーレート(転送速度)は 31250bps になります。
#define VS1053_BANK_DEFAULT 0x00
#define GM_ACOUSTIC_PIANO   0x00
#define VELOCITY_FFF         127
#define MIDI_CHAN_BANK      0x00
#define MIDI_CHAN_VOLUME    0x07
#define MIDI_CHAN_MSG       0xB0
#define MIDI_CHAN_PROGRAM   0xC0
#define VELOCITY_MP           64

void setChannelBank(uint8_t channel, uint8_t bank) {
  Serial.write(MIDI_CHAN_MSG | channel);
  Serial.write((uint8_t)MIDI_CHAN_BANK);
  Serial.write(bank);
}

void setChannelVolume(uint8_t channel, uint8_t vol) {
  Serial.write(MIDI_CHAN_MSG | channel);
  Serial.write(MIDI_CHAN_VOLUME);
  Serial.write(vol);
}

void setInstrument(uint8_t channel, uint8_t instrument) {
  Serial.write(MIDI_CHAN_PROGRAM | channel);
  Serial.write(instrument);
  delay(10);
}

void setup() {

  uint8_t channel =  0;

 ~~~~~~~~

  Serial.begin(31250);
  setChannelBank(channel, VS1053_BANK_DEFAULT);
  setChannelVolume(channel, VELOCITY_FFF);
  setInstrument(channel, GM_ACOUSTIC_PIANO);
}

ビルドして、Arduino に書き込みます。
$ pio run -t upload

■DIECIMILA と Music Maker の接続
Arduino と Music Maker をシリアル接続して、Music Maker で、MIDIメッセージを演奏してみます。

 DIECHIMILA  - Music Maker
TX -(5V)分圧(3V)-  RX
3.3V - 3.3V
GND -  GND

5V→3.3Vレベル変換(分圧抵抗)
3.3VのマイコンのHIGHの閾値はおおよそ2Vなので, 3VはHIGHと認識されます.

Music Maker との通信にハードウェアシリアルを使用しているので、 ビルドに使用した Raspberry Pi とのUSBケーブルを外して、Arduino のUSBポートには電源ケーブルを差し込みます。
写真にあるラジオにはLINE-IN端子があるので、スピーカーとして用いています。
MIDIコントローラ SE25の消費電力は5V100mAと少ないので、USB HOST SHIELDからのUSB電力供給で十分賄えてしまいます。

さくら便り 国府弘子


MIDIフォーマットについては、下記の記事も参考にしてください。
MIDIフォーマット解析

●USB HOST SHIELD 汎用化
USB HOST SHIELD(5V)とESP32をシリアル接続するための汎用化を行いました。
DIECIMILA(UNO)のハードウェアシリアル(RX,TX)はUSB共用で使い勝手がわるいので、ソフトウェアシリアルに変更しています。
#include SoftwareSerial midiSerial(15, 14); // RX(A1), TX(A0)
※USBホストシールドの標準構成として、9ピン、10ピンはUSBホストコントローラのチップに接続されており、 SPIで通信するために必要な割り込みピン(INT)とChipSelectピン(SS)になるので使用できません。
シリアルケーブルにはQWIICケーブルを流用しました。
 DIECHIMILA  QWIIC ESP32
TX[14] -(5V)分圧(3V)-  RX
RX[15] NC TX
5V NC 3V3
GND -  GND



USB HOST SHIELDに被せた様子です


■参考文献
Bitwig Studio 8-Track
マイコンで電子ピアノのMIDI信号を読み取る - West Gate Laboratory
DTM技術情報/1.MIDIメッセージ一覧
Arduino MicroでMIDIUSBを使う
Essentials of the MIDI protocol
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
2020.01.05 第1回 abcjs 楽譜作成・演奏スクリプト
2020.01.09 I2S通信によるハイレゾ音源再生
2020.01.18 MIDI再生:FM音源YMF825+Arduino編
2020.01.24 FM音源YMF825+micro:bit編
2020.02.13 Piano Hat & Rosegarden
2020.03.18 テキスト読み上げ gTTS
2020.05.19 テキスト読み上げ AquesTalk pico LSI
2020.06.22 波形処理 第1回 音の波と三角関数
2020.07.22 波形処理 第2回 平均律と純正律
2020.08.26 波形処理 第3回 黒鍵と白鍵
2020.11.21 深層学習 第1回環境整備
2020.12.19 深層学習 第2回マルコフ連鎖・自動歌詞生成
2021.01.02 深層学習 第3回コード進行解析
2021.01.16 波形処理 第4回 コード演奏
2021.08.07 MIDI制御/Adafruit Music Maker
2021.08.23 MIDIフォーマット解析
2021.10.10 音声ファイルの切貼り
2022.09.16 USB-MIDI
2023.01.16 MAX98537 & PCM5102
2023.03.15 音源サンプリング
2023.06.16 ヤマハ音源IC YMZ294
2024.01.07 内蔵DACによるWAV再生
2024.03.23 Piano Hat for MIDI
2024.08.08 シンプルな16bit DAC
2024.09.09 ESP32-S3 USB MIDI
2024.11.10 音声変換・参照音声編集
2024.11.24 音声変換 Seed-VC
2024.12.11 音源IC SN76489
2025.01.10 ttymidi + SAM2695
2025.02.08 YMF825 + ESP32
2025.05.08 Small World 4MH711
YAMAHA YMU251-D
2025.05.23 Small World 4MH711
NJM2073
2025.06.08 Small World 4MH711
オリジナル・クロック
2025.06.23 Bluetooth Emitter
2025.11.20 NANO ESP32 統合環境
2025.11.24 MIDIキーボード→VS1053再生
2025.12.08 MP3 Player Shield

たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」 「一念発起して何かを始めても、いつも三日坊主で終わってしまう」 「色んなことを先延ばしにしたまま、時間だけが過ぎていく」 そこで本書では、そんな著者が独自に開発した、 まったく新しい目標達成メソッド「100日デザイン」について、 その知識と技術を、余すところなくご紹介します。

まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。 ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。

今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。

ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。 29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!

【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。 基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。

Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説! 500以上のサンプルを掲載。実行結果も確認。 全24章の包括的なチュートリアル。

ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS… 全WEB媒体で効果バツグン! カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術

小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。

Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード

電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)

Copyright © 2011-2027 Sarako Tsukiyono All rights reserved®.