にせねこメモ

はてなダイアリーがUTF-8じゃないので移ってきました。

サーバルちゃんボタンをつくる、あるいはDFPlayer Miniによる音声再生を試す

f:id:nixeneko:20170511235410p:plain

「すごーい!」

って、全肯定されたい。


けものフレンズ』のインタビューで、福原プロデューサーは次のように語っている。

福原:サーバルちゃんは全肯定してくれるキャラクターだけど、あれはサーバルちゃん自身が本当にそう思ってて、クチに出してるだけなんです。(略)それがいまのアニメファンに受け入れられた現象を考えると……みんな疲れてるのかなぁ? と思いますね。

すごーい!の連続、『けものフレンズ』チームに3万字インタビュー | アニメイトタイムズ

そう、疲れているのである。

という訳で、現実にサーバルちゃんはいないので*1、ボタンを押すとサーバルちゃんのセリフが流れるという風で手を打つことにする。まあ、ないよりはマシだと思う。

完成品

たのしい。

DFPlayer Mini

さて、前回Arduinoを使ってボタンで音を出そうとしたときは、音声を8bit PCMにしてArduinoのメモリに書きこんでいたのだが、音質の悪さと記録できる容量が少ないことがネックだった。

これを解決するために音声再生用ICを利用しようというのが今回の目的である。
調べたところ、DFPlayer Miniというmp3再生用のモジュールが安くて良さそうなので、Amazonで購入した。

これ。一個250円と安いのだが、中国発送なので、到着まで2週間ほどかかる。


公式Wikiを参考に再生を試した。

音声ファイルの用意

Micro SDカードを用意し、ルートにmp3ディレクトリを作成してそこに音声ファイルを突っ込んだ。mp3プレーヤとのことだが、waveファイルを突っ込んでも普通に再生してくれる。
ファイル名は先頭4文字が連番数字になるようにする(0001hoge.wav, 0002moge.wav, 0003hage.wav, …)。
アンプ内蔵なので、音声ファイルの音量が小さくても結構な音量で鳴る。

音声ファイルを入れたらDFPlayer MiniのMicro SDスロットに装着する。


実はこれでもう電源・ボタン・スピーカーだけ配線をすればArduinoがなくても再生ができる。IO_2(やIO_1)端子をGNDに短時間ショートさせると次の曲(前の曲)が再生されるので、そこにボタンをつなぐだけで、ボタンを押す度に順繰りに音声が流れるようになる。音量が初期値で最大音量になっているのでうるさい。

配線

f:id:nixeneko:20170511213921p:plain

  • 今回はArduinoからSoftwareSerialライブラリを利用してDFPlayer Miniとのシリアル通信を行う。
    • RXが10番ピン、TXが11番ピンと設定する。
  • DFPlayer Miniの電源VinはArduinoの3.3V電源ピンに接続する。
    • これは、Arduino Uno電源の中で一番ノイズが小さいのが3.3Vピンだから。5Vに繋ぐとノイズが出るが3.3Vにするとノイズがなくなるという場合がある。
  • DFPlayer MiniのRX~ArduinoのTXの間に1.0kΩの抵抗を挟む。
    • DFPlayer Miniが3.3Vで動いているために、Arduinoとの電圧差を吸収する必要があるようだ。入れないとノイズになることがある。

Arduinoからボタンへの配線は前回の記事と同じなのでそちらを参照。プルダウン回路で19番(A5)ピンに繋いでいる。

Arduinoコード

ライブラリを導入する。

  1. Releasesから最新のリリース(2017/05/11時点では1.0.1)からSource codeをダウンロードしてくる。
  2. ダウンロードしてきた圧縮ファイルを解凍し、 DFPlayer_Mini_Mp3 ディレクトリを C:\Program Files (x86)\Arduino\libraries\ (Windowsの場合)に突っ込む。


実装したソースコードを次に示す。(といっても公式wikiのコードを弄っただけ)

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

// ボタンに繋がるピン
#define BUTTON 19
// SoftwareSerialのRX, TXピン
#define RX_PIN 10
#define TX_PIN 11

SoftwareSerial mySoftwareSerial(RX_PIN, TX_PIN); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

int numfile;   //楽曲ファイル数
int lastval=0; //ボタンの値保存用

void setup()
{
  pinMode(BUTTON, INPUT);
  randomSeed(analogRead(0)); 
  
  // SoftwareSerialとDFPlayerの初期化
  mySoftwareSerial.begin(9600);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    while(true);
  }

  myDFPlayer.volume(25);  // 音量の設定(0~30)
  numfile = myDFPlayer.readFileCounts(DFPLAYER_DEVICE_SD); //音楽ファイル数取得
}

void loop()
{
  lastval = (lastval << 1) | digitalRead(BUTTON); // チャタリング回避
  if(lastval == 0x7FFF){                // ボタンが押されたら
    myDFPlayer.play(random(numfile)+1); //ランダムにファイルを再生 [1, numfile]
  }
  delay(1);
}

エラー処理なんかやってないのでアレだが、コードはすごくシンプルになった。
長かったり高音質な音声ファイルの再生が簡単にできるので便利。

さらに細かいことが知りたければ公式wikiを参照。

参考

*1:少なくとも、私の身近には