Arduinoの16ビットのデータを表示する

2020.03.03

Arduinoから16ビットのデータをMIDIで転送し、Web MIDIで受信して表示するプログラムです。なかなか使う機会は無いかもしれません。16ビットデータ(下図のように、INT16と名前をつけておきます)の転送には、MIDIとしてはめったに使わないキープレッシャーのステータス(0xA0)を利用します。

転送フォーマットを下図を基に説明します。INT16をMMIDIで転送する方法です。MIDIは8ビット、3バイトのデータです。全部で24ビットのデータを転送することができます。INT16を3バイトに分けて送ります。ステータスの上位4ビットはステータスとして決まった値を送らないとなりません。またデータ1、データ2の最上位ビットはゼロでなければなりません。この条件を基に、16ビットを24ビットに下図のように割り振ります。

ステータスの上位4ビットは0xAを使います。それに続く2バイト(赤で示したxx)は、チャンネル番号とします。すなわち、この場合は4つのチャンネル(異なる種類)のデータを送ることができます。

Arduino側のプログラムを示します。

#include <usbmidi.h>	// USB MIDIのライブラリをインクルードします。

// 16ビットのデータをチャンネル番号にキープレッシャーとして送信します。
void SendData16(unsigned int data, unsigned char channel)
{
  unsigned char dataH;
  unsigned char dataM;
  unsigned char dataL;

  dataL=(unsigned char)(data&0x7F);
  dataM=(unsigned char)((data>>7)&0x7F);
  dataH=(unsigned char)((data>>14)&0x03);
  
  USBMIDI.write(0xA0+(channel<<2)+dataH);
  USBMIDI.write(dataM);
  USBMIDI.write(dataL);
  USBMIDI.flush();
}

void setup() {
}

int _x;

// テストデータを4チャンネルに別々に送信します。
void loop() {
  SendData16(_x,0);
  SendData16(_x<<4,1);
  SendData16(_x<<6+_x,2);
  SendData16(_x<<8+_x,3);
  _x++;
  delay(1000);
}

Web MIDIの受信プログラムは以下の通りです。配列dataにチャンネルごとにデータが入ります。

	var data=[0,0,0,0];

	status=event.data[0]&0xF0;
	if(status==0xA0){
		channel=(event.data[0]&0x0C)>>2
		data0=event.data[0]&0x03;
		data1=event.data[1];
		data2=event.data[2];
		data[channel]=data2+(data1<<7)+(data0<<14);
	}

このページにArduinoをつないで、上記スケッチを動作させると、以下のように表示されます。ここではArduino Leonardoを使っています。MIDI inport: のプルダウンメニューで、Arduino Leonardoを選択します。MIDI outport:は何でもかまいません。



↓↓↓ 以下がアプリケーションのビューになります。

MIDI outport:
MIDI inport:
Wait for preparation