DFPlayerをPICで操作する その4 日本じゃあ、2番目だ。
前回、ボタンによって1曲目、2曲目を演奏するプログラムを紹介しました。
ところで、DFPlayerの中では何が1曲目で、何が2曲目なのか。
実はこれ、落とし穴です。
MP3ファイルに001,002…とつけて、SDカードにコピーして、前回のプログラムで再生させると、1曲目を指示したボタンなら001とついた曲がかかりますし、2曲目用のボタンでは002とついた曲がかかります。
なので、DFPlayerはファイル名で判断しているように見えるのですが、違うのです。
DFPlayerにとって1番目の曲は、そのSDカードに1番最初に書き込まれた曲です。ファイル名関係ありません。
なので、002から始まるファイル名を先に、001からのファイル名を後に書き込むと、1番目の曲を再生しろという命令を受けたとき、DFPlayerは002のファイルを再生します。
「001.mp3ファイル。その名前から自分が1番のつもりかもしれないが、このSDカードの中じゃあ、2番目だ」
というわけですね。
まあ事前にPC上で001, 002, というファイル名で用意してSDカードにコピーすると、001, 002, という順番でコピーされるので、普通はそういうこと起きない。のですが、後からファイルを入れたり消したりしてると、順番が名前通りでなくなってそういうことが起こります。(起こってしばらく悩みました。)
音声ファイル関係の話ついでに、私は音声ファイルの作成にAudacityというソフトを使っています。PCでそのとき再生している音を録音してくれるというもので、これで銃の発射音を拾い、同じソフトで適宜加工して使いました。
似たような機能のソフトはいろいろあるようなので、これが一番よいかどうかはわからないのですが、私はありがたく使わせてもらっています。
ほんと興味のない人にはどうでもいい話だと思うのですが、無印ヤマトと2199ヤマトでコスモガンの発射音が違うとか、工作のために録音して初めて知りましたよ。
今回もプログラムを載せておきます。中身は前回と同じなのですが、シリアル設定のところの冗長な注釈を省いたのと、DFPlayerのボリュームをPICから指定できるように関数を書き足しているところだけ違います。プログラム中赤色の部分です。
DFPlayerのデータシートを見て、欲しい機能があればをこれを参考に自分で関数を作って書き足してやることで、PICからDFPlayerに指示させることができる内容は追加してゆくことができますよ、という参考例です。
次回は、省電力について。
/////////////////////////////////////////////////////////////////
#include <xc.h>
#define _XTAL_FREQ 8000000 //8Mhzで動かすので_XTAL_FREQは8000000 これ書いとかないとdelayが使えない。
//コンフィグ設定
#pragma config FOSC = INTOSC //内部クロック使用
#pragma config WDTE = OFF //ウオッチドッグタイマーなし
#pragma config PWRTE = ON //電圧の立ち上がり後の安定待ちをする
#pragma config MCLRE = OFF //RA3をリセットに使わない
#pragma config CP = OFF //プログラムメモリ保護なし
#pragma config CPD = OFF //データメモリ保護なし
#pragma config BOREN = ON //電圧降下したらPIC停止(許容する程度はBORVで指定)
#pragma config CLKOUTEN = OFF//クロック出力無効
#pragma config IESO = OFF //2段階起動モードON
#pragma config FCMEN = OFF //外部クロック監視をしない
#pragma config WRT = OFF //書き込み禁止しない
#pragma config PLLEN = OFF //高速クロック(32MHz)使わない
#pragma config STVREN = ON //スタックがオーバーフローしたらリセット
#pragma config BORV = HI //PIC停止電圧設定HIGH
#pragma config LVP = OFF //低電圧プログラミングしない
//関数のプロトタイプ宣言
void UART_Write(char data);
void DF_SpecifyPlay(int n);
void DF_Volume(int n);
//メイン関数ここから
void main(void) {
//特殊レジスタの設定
OSCCON = 0b01110010 ; // 内部クロックは8MHzとする
OPTION_REG = 0b00000000 ; // デジタルI/Oに内部プルアップ抵抗を使用する
ANSELA = 0b00000000 ; // アナログは使用しない(すべてデジタルI/Oに割当てる)
TRISA = 0b00011000 ; // RA4、RA3は入力その他のピンは出力
WPUA = 0b00011000 ; // RA4、RA3には内部プルアップ抵抗をつなぐ
PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする)
//シリアル通信の初期設定
TXSTA = 0b00100100 ;
SPEN = 1;
SPBRGL = 51 ;
TXCKSEL = 0 ;
//シリアル通信の初期設定ここまで
DF_Volume(31);//ここの数値を変えるとボリュームが変わる(0~31)
while(1) {
if (RA3 == 0 ) { //ボタンを押すと
DF_SpecifyPlay(1) ;//関数DF_SpecificPlayに曲番号1を送る
__delay_ms(1000);
}
if (RA4 == 0 ) { //ボタンを押すと
DF_SpecifyPlay(2) ;//関数DF_SpecificPlayに曲番号2を送る
__delay_ms(1000);
}
}//while(1)ここまで)
}//メイン関数ここまで
//シリアル通信書き込み用関数
void UART_Write(char data)
{
while(TRMT==0);
{
TXREG = data;
}
}
//シリアル通信書き込み用関数ここまで
//DFPlayer用の関数
//ルートディレクトリのn番目の曲を再生する関数
void DF_SpecifyPlay(int n){
UART_Write(0x7E);
UART_Write(0xFF);
UART_Write(0x06);
UART_Write(0x03);
UART_Write(0x00);
UART_Write(0x00);
UART_Write(n);
UART_Write(0xEF);
}
//ボリュームをコントロールする関数
void DF_Volume(int n){
UART_Write(0x7E);
UART_Write(0xFF);
UART_Write(0x06);
UART_Write(0x06);
UART_Write(0x00);
UART_Write(0x00);
UART_Write(n);
UART_Write(0xEF);
}
//DFPlayer用の関数ここまで