ArduinoでMP3ファイルを再生する Cytron Easy MP3シールド 関数リファレンスマニュアル

Cytron SHILD-EZMP3 (Easy MP3シールド)のライブラリーが用意されているものの、リファレンスマニュアルは用意されておりません。
CytronEZMP3.h を見ると、メソッドの一覧がわかります。名称である程度わかります。さらに機能を知りたい場合は、ソースプログラムのCytronEZMP3.cpp を見て、使用しているチップ XY5200 のマニュアル(中国語)を見るとわかります。
それでは、大変なので、よく使いそうな関数の説明をまとめました。

初期化・通信のためのピン設定
 初期設定を行います。

bool begin(uint8_t rxpin, uint8_t txpin, long baudrate);

引数
rxpin シリアル通信受信ピン番号 省略時 2
txpin シリアル通信受信ピン番号 省略時 3
baudrate シリアル通信ボーレート 省略時 9600

戻り値
成功 true、失敗 false

再生中の確認
 曲が再生されているかどうかを確認します。

bool isPlaying();

引数
なし
戻り値
再生中 true 再生中でない false

物理トラック再生
SDカード、USBメモリーに記録された物理的なトラック番号(コピーした順)を指定して再生します。

void playPhysical (uint16_t num);

引数
num トラック番号(コピーした順)
戻り値
なし

再生
 トラック指定なしの再生

void play();

引数
なし
戻り値
なし

次のトラック再生

void next ();

引数
なし
戻り値
なし

前のトラック再生

void prev ();

引数
なし
戻り値
なし

音量設定

void setVolume (uint16_t volume);

引数
volume 0~30
戻り値
なし

イコライザー設定

void setEQ (uint16_t eq);

引数
eq  0~5  0:Normal  1:Pop 2:Rock  3:Jazz  4:Classic  5:Bass

戻り値
なし

デバイス選択

void setDevice (uint16_t device);

引数
device 1~5  1:USBメモリー 2:SD 3:AUX 4:SLEEP 5:FLASH戻り値
なし

スリープ

void sleep ();

引数
なし
戻り値
なし

リセット

void reset ();

引数
なし
戻り値
なし

一時停止

void pause ();

引数
なし
戻り値
なし

停止

void stop ();

引数
なし
戻り値
なし

ON

void on();

引数
なし
戻り値
なし

OFF

void off();

引数
なし
戻り値
なし

全曲再生

void playAll (boolean state = true);

引数
state
戻り値
なし

特定フォルダートラック再生
 mp3フォルダー内、特定のファイル名のファイルを指定して再生します。フォルダーは、mp3、ファイル名は、0001.mp3、0002.mp3、0003.mp3 という連番にします。
mp3_play (1);
とすると、mp3/0001.mp3 を再生します。

void playTrack (uint16_t num);

引数
num トラック番号
戻り値
なし

現在のデバイス取得

uint8_t getCurrentDevice ();

引数
なし
戻り値
1~5  1:USBメモリー 2:SD 3:AUX 4:SLEEP 5:FLASH

状態取得

uint8_t getCurrentStatus ();

引数
なし
戻り値
状態(XY5200から得た値)

音量設定値取得

uint16_t getVolume ();

引数
なし
戻り値
なし

デバイス指定ファイル数取得

uint16_t getTotalFiles (uint8_t disk);

引数
disk 1:USBメモリー 2:SDカード
戻り値
なし

ファイル数取得取得

現在設定されているデバイスのファイル数を得ます。

uint16_t getTotalFiles ();

引数
なし
戻り値
なし

再生中トラック取得(デバイス指定)

uint16_t getTrackNo(uint8_t disk);

引数
disk 1:USBメモリー 2:SDカード
戻り値
なし

再生中トラック取得

uint16_t getTrackNo();

引数
なし
戻り値
なし

フォルダー・トラック指定再生

void playTrackFromFolder(uint8_t folder, uint8_t track);

引数
folder フォルダー番号(最大99)
戻り値
track トラック番号(1フォルダーあたり最大255)

フォルダーリピート再生

指定したフォルダー内の曲を繰り返し再生します。

void playFolderRepeat(uint8_t folder);

引数
folder フォルダー番号
戻り値
なし

リピート再生

指定したトラックを繰り返し再生します。

void repeatTrack (uint16_t num);

引数
num トラック番号
戻り値
なし

ランダム再生

void randomPlay ();

引数
なし
戻り値
なし

Arduinoの入出力を拡張増設するIOエキスパンダーシールドの使い方

「IOエキスパンダーシールド(Arduino I/O増設 デジタル28点 アナログ16点)」を使うと、比較的簡単にArduinoにデジタル入出力、アナログ入力を拡張増設することができます。

お求めは、下記のサイトでどうぞ。

http://www.elefine.jp/SHOP/IOEXPANDERSHLD.html

Arduinoとの通信は、I2Cを利用しますので、A4(SDA)、A5(SCL)、およびアナログ入力としてA0を使い、合計3点のI/Oを使うだけで済みます。

I2Cで通信を行うデジタル入出力用デバイスMCP23017が2個搭載されています。その各MCP23017のI2Cアドレスは、基板上のジャンパーピンで設定します。

アドレスの上位4ビットは、0x20(16進数) で固定されていますので、下位3ビットをジャンパーピンで設定します。
AD1、AD2、AD3はU2用、AD4、AD5、AD6はU4用です。
AD3、AD2、AD1の順でそれぞれ1、2、4の重みです。同様にAD6、AD5、AD4の順でそれぞれ1、2、4の重みです。
よって、AD1、AD2、AD3のジャンパーをすべて0側(真ん中と0をまたぐようにジャンパーピンを挿す)に挿すとU2のアドレスは、0x20になります。また、AD4、AD5を0側、AD6を1側に挿すとU4のアドレスは、0x21になります。

デジタル入出力ピンとMCP23017のピンの対応

MCP23017の入出力ピンとIOエキスパンダーシールドのピンの対応は、以下のとおりです。

0 – U2 PORT B ビット0
1 – U2 PORT B ビット1
2 – U2 PORT B ビット2
3 – U2 PORT B ビット3
4 – U2 PORT B ビット4
5 – U2 PORT B ビット5
6 – U2 PORT B ビット6
7 – U2 PORT B ビット7

8 – U2 PORT A ビット0
9 – U2 PORT A ビット1
10 – U2 PORT A ビット2
11 – U2 PORT A ビット3
12- U2 PORT A ビット 4
13 – U2 PORT A ビット5
14 – U2 PORT A ビット6
15 – U2 PORT A ビット7

16 – U4 PORT B ビット0
17 – U4 PORT B ビット1
18 – U4 PORT B ビット2
19 – U4 PORT B ビット3
20 – U4 PORT B ビット4
21 – U4 PORT B ビット5
22 – U4 PORT B ビット6
23 – U4 PORT B ビット7

24- U4 PORT A ビット 4
25 – U4 PORT A ビット5
26 – U4 PORT A ビット6
27 – U4 PORT A ビット7

U4 PORT Aの下位4ビットは、アナログマルチプレクサのアナログ入力切替に使用しているため、デジタル入出力としては使用できません。

デジタル入力

サンプルスケッチhttps://github.com/numato/samplecode/blob/master/Arduino/shields/IOExpander/DigitalIn.ino

このサンプルでは、ジャンパーピンをAD6のみ1にして、ほかはすべて0に設定して使用します。よって、U2のI2Cアドレスは0x20、U4は0x21です(7ビット表記アドレス)。

 

入出力の方向設定

setup()内で各MCP23017の入出力の方向を設定しています。
MCP23017には、8ビットのポートが二つあり、PORT A、PORT Bの名称がつけられています。

下記の部分でU2(アドレス0x20)の設定を行っています。
初めの0x00は、MCP23017の内部アドレスで0x00は、PORT Aの入出力方向設定のためのレジスターです。
次の行の0xFFは、入出力の方向を設定しています。8ビットの各ビットが入出力ピンに対応し、0で出力、1で入力です。Outなので0、Inなので1と覚えると覚えやすいです(Z80で8255を使っていた頃の覚え方)。
よって、0xFFは、すべて入力です。

Wire.beginTransmission(0x20);
Wire.write(0x00);
Wire.write(0xFF);
Wire.endTransmission();

同様に次の行で内部アドレス指定を0x01にして、U2のPORT Bの設定を行っています。

Wire.beginTransmission(0x20);
Wire.write(0x01);
Wire.write(0xFF);
Wire.endTransmission();

さらに次の行でI2Cアドレスを0x21にして、U4のPORT A、PORT B の設定を行っています。

U4のPORT Aの設定

Wire.beginTransmission(0x21);
Wire.write(0x00);
Wire.write(0xFF);
Wire.endTransmission();

厳密には、U4のPORT Aの下位4ビットは、アナログ入力のマルチプレクサーの切り替えに使用しているため、0xFFではなく、0xF0のほうがいいでしょう。

U4のPORT Bの設定

Wire.beginTransmission(0x21);
Wire.write(0x01);
Wire.write(0xFF);
Wire.endTransmission();

デジタル入力値の取得

デジタル入力の読み出しは、loop() 内で行っています。
下記は、U2のPORT Aを読み出す例です。8ビット分まとめて読み出されます。

Wire.beginTransmission(0x20); //I2CのアドレスでU2を指定
Wire.write(0x12);     // MCP23017の内部アドレスの指定
Wire.endTransmission();
Wire.requestFrom(0x20, 1);     // 読み出すアドレスを指定する
U2PortA=Wire.read();     // 読み出す

上記の0x20を0x21にするとU4、0x12を0x13にするとPORT Bのデータを読み出すことができます。
読み出した値は、8ビットをまとめた数値ですので、ビットごと、例えばビット0のH,L を確認したい場合は、下記のように &でマスク(対象以外を0にする)して、0以外かどうかを確認します。1がビットを表し、2進数の重みです。
つまり、ビット0からビット7まで、それぞれ1, 2, 4, 8 ,16, 32, 64, 128 です。

if ((U2PortA & 1) != 0) {
    // true (H)の処理
}
else {
// false (L)の処理
}

入力のプルアップ

サンプルスケッチには、記述されておりませんが、MCP23017には、入力を内部の抵抗でプルアップする機能があります。これを使うと、スイッチ入力時、外部でプルアップ抵抗を接続する必要がなく、配線の手間が省けます。プルアップ設定のレジスターのアドレスは、PORT Aが0x0C、PORT Bが0x0Dです。8ビットのビットを1にするとそれに対応したピンがMCP23017の内部の抵抗100kΩでVDD(5V)にプルアップされます。

U2のPORT Aの全端子をプルアップする例

Wire.beginTransmission(0x20);
Wire.write(0x0C);
Wire.write(0xFF);
Wire.endTransmission();

これをsetup()内に入れるとよいでしょう。

デジタル出力

サンプルスケッチhttps://github.com/numato/samplecode/blob/master/Arduino/shields/IOExpander/DigitalOut.ino

このサンプルでは、ジャンパーピンをAD6のみ1にして、ほかはすべて0に設定して使用します。よって、U2のI2Cアドレスは0x20、U4は0x21です(7ビット表記アドレス)。

 

入出力方向設定

デジタル入力と同様、setup()内で各ポートの入出力方向を設定しています。

Wire.beginTransmission(0x20);   // I2Cアドレス U2のアドレス
Wire.write(0x00);      //内部アドレス 入出力方向方向設定レジスター
Wire.write(0x00);     // 入出力方向方向設定
Wire.endTransmission();

1番目の0x00でPORT Aの入出力設定レジスターのアドレスを設定しています。PORT Bの場合は、0x01です。
2番目の0x00で入出力方向を設定しています。出力の場合は、0です。

デジタル出力を行う

loop() 内でデジタル出力を行いますが、サンプルスケッチでは、
DigitalIO(255);
と、関数を介して行っています。
サンプルスケッチでは、全ポート同じ状態を出力しています。
そのDigitalIOの定義を見ると、実際に出力する方法がわかります。
下記は、U2のPORT Aの例です。

Wire.beginTransmission(0x20);
Wire.write(0x12);
Wire.write(i);
Wire.endTransmission();

0x12 でPORT A のデジタル出力レジスターを指定しています。PORT Bの場合は、0x13 です。
Wire.write(i);  が実際に出力するところです。8ビット分まとめて、出力します。8ビットのうち、1ビットのみ変化させたい場合は、前回の状態を保持しておき、その値との | (OR、論理和)、^ (ExOR、排他的論理和)を行います。

OFFにする場合、対象以外を1にして(上記の場合だと、0xf7)、ANDでマスクする方法もあります(この方が正当な方法)が、上記の方が計算が楽です。