実験室 » Arduino » この記事

DFPlayerMiniでMP3を鳴らしてみた

中身(左)と100均タッパーのケース

 お正月休みに、ネットで検索すると色々でてくるMP3プレーヤーを自分も作ってみました。

 作ってて気付いたことなどを備忘録として書いてみました。今回はお手軽に作りたかったので、Aitendなどで売っている小さいブレッドボードを2つ並べて回路を組みました。ケースはセリアで100円で売っているタッパーに穴をあけて加工したものにブレッドボードを収納(割とぴったりはまりました)した簡便な構成にしました。

 回路は、以下のメーカーサイトや参考ブログ様の例を参考に作りました。

https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299

回路
蓋部(スピーカーと制御用タクトスイッチ)

 コード無しで持ち運びしたかったので、電源は3.7Vのリチウムポリマー電池にしました。DFPlayerMiniには、このまま3.7Vで送り込んでいますが、ArduinoNanoに対しては電圧が足りませんでしたので、写真右側に斜めに配置してある昇圧回路(7Vに調整)を介して送り込んでいます。

(Memo) 蓋の裏にスピーカーを接着していますが、セメダインやグルーガンで接着しても電池の充電時などで蓋をめくった際に、脱落してしまいました。最終的にちょっと見た目は悪いのですが、ホームセンターなどで売っている外壁補修用の目地材を使って固定しました。今の所脱落はその後ありません。また、タクトスイッチの固定にダイソーで買った100円セメダインで固定させようとしましたが、あんまり良くないですね。付きもいまいちだし、タッパー(アクリルなのかな)が部分的に白く変色したりしましたので、何か別の方法で固定させたほうがいいと思いました。

Arduinoに書き込んだコードです。参考サイトのコードをもとにしてちょっとだけアレンジしています。ボリュームとPrev・Nextがあればとりあえず良かったので。何もしなければ、SDカードの連番どおりに再生をしていきますね。

/*
 * ▼ベースは、下記の公式チュートリアル
 * https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299
 * 
 * それに、タクトスイッチによる制御を追加。以下のアドレスのものを改造
 * https://www.electronics-lab.com/project/mp3-player-using-arduino-dfplayer-mini/
 * 
 * コマンド群(関数)の説明はこちらのサイトから
 * https://www.wwwmaplesyrup-cs6.work/entry/2019/02/10/152415
 */


/***************************************************
DFPlayer - A Mini MP3 Player For Arduino
 <https://www.dfrobot.com/index.php?route=product/product&amp;product_id=1121>

 ***************************************************
 This example shows the basic function of library for DFPlayer.

 Created 2016-12-07
 By [Angelo qiao](Angelo.qiao@dfrobot.com)

 GNU Lesser General Public License.
 See <http://www.gnu.org/licenses/> for details.
 All above must be included in any redistribution
 ****************************************************/

/***********Notice and Trouble shooting***************
 1.Connection and Diagram can be found here
 <https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299#Connection_Diagram>
 2.This code is tested on Arduino Uno, Leonardo, Mega boards.
 ****************************************************/

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

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

/* 追加分 */
# define ACTIVATED LOW   // ※pinModeを設定後、セットアップでHIGHにする。
int buttonNext = 4;
int buttonPause = 6;
int buttonPrevious = 5;
int buttonVup = 3;
int buttonVdown = 2;
boolean isPlaying = false;


void setup()
{
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(20);  //Set volume value. From 0 to 30
  
  myDFPlayer.enableLoopAll(); //loop all mp3 files.
 
/* 追加分 */
  pinMode(buttonPause, INPUT);
  digitalWrite(buttonPause,HIGH);
  pinMode(buttonNext, INPUT);
  digitalWrite(buttonNext,HIGH);
  pinMode(buttonPrevious, INPUT);
  digitalWrite(buttonPrevious,HIGH);
  pinMode(buttonVup, INPUT);
  digitalWrite(buttonVup,HIGH);
  pinMode(buttonVdown, INPUT);
  digitalWrite(buttonVdown,HIGH);

  isPlaying = true;
}

void loop()
{

// 一時停止
 if (digitalRead(buttonPause) == ACTIVATED)
  {
    if(isPlaying)
    {
      myDFPlayer.pause();
      isPlaying = false;
      delay(1000);    // ※処理が早すぎて、delayを入れないと指が離れる前に、次の判定が来てフラグを立ててもすぐ倒してしまう。
    }else
    {
      myDFPlayer.start();   //start the mp3 from the pause
      isPlaying = true;
      delay(1000);    // ※処理が早すぎて、delayを入れないと指が離れる前に、次の判定が来てフラグを立ててもすぐ倒してしまう。
    }
  }

// 次へ
 if (digitalRead(buttonNext) == ACTIVATED)
  {
    if(isPlaying)
    {
      myDFPlayer.next();
      delay(1000);  
    }
  }

// 前へ
   if (digitalRead(buttonPrevious) == ACTIVATED)
  {
    if(isPlaying)
    {
      myDFPlayer.previous();
      delay(1000);
    }
  }

// 音量増大
   if (digitalRead(buttonVup) == ACTIVATED)
  {
    if(isPlaying)
    {
      myDFPlayer.volumeUp();
      delay(1000);
    }
  }

// 音量増大
   if (digitalRead(buttonVdown) == ACTIVATED)
  {
    if(isPlaying)
    {
      myDFPlayer.volumeDown();
      delay(1000);
    }
  }

  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
  }
}

void printDetail(uint8_t type, int value){
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));

      // ※次へボタンを押すと、演奏終了後に停止してループが終了してしまうので。
      myDFPlayer.next();
      delay(1000);  
      
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

(Memo) 参考元にあったシリアルモニタにメッセージを書き出すコードが残ってます。最後の曲の演奏終了を通知するメッセージには、手を加えててまた先頭に戻る様にしています。Nextボタンを連打して最後の曲まで進めると演奏終了になってしまったのでそうしたような記憶があります。あと一時停止のコードも残っていますね。最初は入れてあったけど、後にいらなくなったのでなにもさせていません。

 再生した感じでは、スピーカーのせいなのでしょうか何というか、安っぽい音が(。・_・。)なんとも表現しにくいんですが、スコスコと抜けてしまうような音がしますね。好きじゃない。

(Memo) 蓋のスピーカーからの音が出てくる穴の上を覆いかぶせるように、コルクを載せてみたりすると音の感じがちょっと変わってきますね。手作りスピーカーのサイトなどを調べれば音の反響のさせ方など載っているみたいですが、難しそう。現状は秋月で買ったスピーカーの入っていた空のプラスチック箱を蓋の上に載っけるとなんかいい感じの音に変化したのでそれでよしとしています。ごく軽い中空の箱だからいいのかな。

リチウムポリマー電池

 リチウムポリマー電池ですが、アマゾンで買った2個セットで1150円のものは、充電器のコネクタの形状がちょっと変わってて、よく見る中華タイプのものは挿せません。650mAhのもので、何回か充電した後は1回の充電で現在1~2時間は再生できています。

 最後に材料費の一覧を載せておきます。大体の値段です。それと送料とか税は入っていません。主要な部品はAmazonで購入しています。2個セットでしか販売してないとかの理由でなんだかんだで出費がかさんで5000円ぐらいかかっているのかもしれませんね。

品名金額備考・その他
HiLetgo® 3個セット Nano V3.0 ATmega328P 5V 16M CH340 Arduinoと互換 Nano V3.0 [並行輸入品] 4503個セット1350円
2個セット 650mAh 3.7V Lipoバッテリー SYMA X5SW X5用リポバッテリー USB充電器付き リチウム バッテリー [並行輸入品] 5752個セット1150円
KKHMF 2A DC-DC ブーストステップアップ 転換モジュール Micro USB 2V-24V に 5V-28V 9V 12V 24V653個セット195円
KKHMF TFカード Uディスクミニ MP3プレーヤー オーディオ 音声 モジュールボード Arduino DFPlayに対応400300~400円程度。
グリーンハウス microSDHCカード 32GB Class10 UHS-I対応 GH-SDMRHCUB32G 763 
ケース100セリアで売ってる100円タッパ
ブレッドボード360Aitend
8Ω・0.4Wスピーカー 50mm100秋月等
セメダイン100ダイソーで売ってる安いやつ
パテ200ホームセンターなどで売っている目地用のもの
合計3113 

 部品の中には、年末にはまだ在庫のあったもののこの1月末では在庫がなくなっちゃってるものも結構あるようです。代替品も似たような値段でありますのでそれで計算してみてください。

ここ最近の電子工作 (ディップメーターを作ってみた)

更新がすっかり滞っていましたが、今年最初の投稿は電子工作から。

 

ラジオ製作の本などを読んでいると、ディップ・メータなるものを使って同調周波数を調べましょうとか書いてあったりしますが、ディップ・メータなんて売ってないし中古品はオークションで一万円近くして中々手が出ません。無いものをどうやって調達しているのか知りたくなったのでネットで調べてみると、自作するという方法もあるらしい(?)のが分かりましたので、とりあえず製作方法が書いてある本を購入して、いけそうだったら作ってみようかということにしました。これが無くてもAMラジオ作りに支障はないのですが、まぁなんとなくね。

 

折角ですので、材料等調達コストが幾らぐらいかかったのかも書いていきたいと思います。

 

本はこの本ですね。

 

「作りながら理解するラジオと電子回路」2,000円(税別)

 

Amazonから購入したような気がします。2010年に初版が出ているのでそんなに古い本ではありません。この本のP.51からP.55の内容で作りました。

 

参照した本は、周波数を測定できるテスターに計測値を出力する仕様になっていましたが、ネットで周波数カウンターを埋め込んでいたかっちょいい方がいましたので、そちらを真似っ子して作ってみました(但し、!MHzからしか計測できない。NHK第一が表示できない)。

 

秋月電子やaitendなどで部品購入しました。
エクセルのキャプチャ画像から、この時点で5,000円です。周波数が表示できるテスターが2,700円なのが大きいです。

 

dipmater_cost

 

この他、交通費とAmazonで購入するしか無い、中華製の周波数カウンター1,500円(SODIAL(R) 高精度1-500MHz周波数カウンタ テスター 測定メーター)その他諸々を加算すると、10,000円に達する勢いです。しかも上手くいくかわかんないものをこれから作ろうとしているので、手早く計測だけしたいならやっぱりオークションでメーカー品の中古を手に入れたほうがいいのかもしれませんねぇ(・∀・)

 

また材料ですが、本で指定のパーツそのものは無かったり高かったりして、互換品で代用したりしているので本当に本の通りに完成するのか作る前から結構ドキドキです。

 

以下は、製作中に撮ったキャプチャー。

 

20190130c

 

発振器自体作ったことが無いので、コルピッツ回路の練習からしました。

 

左下の隅に写っているのが、周波数も計測できるテスター(最初うっかりoffにするの忘れていきなりボタン電池を4つ全部消耗させてしまった。で、10個30円とかいう破格の電池買ったら、Amazonレビュー通り放電してるのが3~4個に1個あったり)。右上のは、ラジケーターを抽出するつもりで、100円ショップで買ったグリーンオーナメントの電池チェッカー。ばらすつもりがボタン電池の容量チェックもできたりして意外と重宝)

 

20190130d

 

ブレッドボード上で試しに組んで…カオスですね。見た目は悪いですが、最終的にインダクタとコンデンサを組み合わせた同調回路を近づけてみると、ちょこっと、ほーんのちょこっとピコピコ反応する回路が出来上がりました。本の指定どおりにラジケーターにある程度安定した電流が流れる真ん中あたりで計測すると実に微妙な振れ方をします。電流量を減らしてギリギリ出力周波数の表示が維持出来る程度のヘリあたりに針を置いて、同調回路を近づけるとぱたーんと左側に針が倒れます。但し、同調回路を離しても針が戻らないというなんとも言えないものに。ラジケーターは指定の500μAではなく、250μAとかもっと微量の電流変化を捕まえられるやつの方がいいのではとか思ったり、互換品のトランジスタじゃまずかったのか、思うところがある出来上がりになりました。

 

20190130b

 

ランド法というやり方で組んでいるところ。

 

20190130a

 

完成したもの。AMラジオの周波数帯を調べたかったので、470μHのインダクタと親子バリコンの組み合わせで。ケースはセリアで売っているはがき用のケースで(108円)。加工もしやすいし透明なので、各パーツの配置もざっくり配置して裏から見て問題ないなら穴を開ける位置を油性マジックペンで線引きしてPカッターでカリカリ切り出せます(軽い・安い・加工時間が短くて済む。但し、ハンダごてを近づけすぎると溶ける!)。

 

完成したものに同調コイルを近づけてみますが、なんかブレッドボードの時と大差ない結果に(´;ω;`)

 

こりゃあ、1万近くかけて失敗なのかぁとかなりがっかりしましたが、まだ実際のラジオで調べてません。

 

で、せっかくなのでこのレビューでも以前紹介した「電子工作は失敗から学べ」にあるワンチップAMラジオをベースに、スピーカーから音が出るように手直ししたものを追加で作りました。これも、ケースはダイソーで3個100円で売ってるタッパーに収めました。なんか100円ショップ結構利用してますね。

 

20190130e

 

こんな感じで作ってみました。タッパーラジオは作ってて楽しいです。

 

20190130f

 

完成したタッパーラジオ。

 

このラジオに、微妙な出来のディップメーターを近づけて、出力を上げていくとスピーカーから聞こえている放送がかき消されていきます。続けて周波数のダイヤルを放送局の周波数に合わせて(周波数カウンターで確認できる)みると、おーなんかYoutubeでディップメーターのテストを公開している人のように、ぴゅいーんとか明らかに(不快な)異質の音がスピーカーから聞こえてきます。この状態で、ラジオを他局にすると音がかき消されるだけでしたので識別は出来るようです。発振器としてちゃんと機能しているみたいです。ラジケーターは相変わらず反応しているのか反応してないのかさっぱりアテにできないままですが、同調すればAMラジオに関してはスピーカーからの音で識別できるようです。

 

三行要約
・自作すると一万円近く掛かった。
・出来上がったディップメーターの性能は、本の様に完璧には動いてくれなかった(特に、メーター)
・ラジオに近づけると、ラジオスピーカーからの音で同調している様子が確認できた。

UnityとAndroidを連携させBluetoothでArudinoと通信してみた(5)

やっとArduinoパートまで進めました。

 

ここは、参考サイトには無い項目なので自力で作ってみました。(´・∀・` )

 

スクリプトを書き出してみました。こんな風になります。

 

// スマホとブルートゥース(シリアル)通信で、やり取りするプログラム
// スマホのUnityアプリに配置してあるスライダーからのRGB値を受信してRGB_REDの色を変更する


// Bluetooth通信ライブラリ
#include <SoftwareSerial.h>
SoftwareSerial BT(10, 11);  // RX:10,TX:11 それぞれブレッドボードのBT機器の逆にRXはTXへ、TXはRXへ

// char配列->int変換用
#include <stdlib.h>


// バッファ
char buffer[4]={0};  // 初期化 4byte(3+\n)

// RGB値
int R = 0, G = 0, B = 0;

void setup() {
  
  // [1] アルディーノ側初期設定
  Serial.begin(9600);

  // [2] HC-06 側初期設定
  BT.begin(9600);

  Serial.println("setup passed");

  
}

void loop() {

  int byteRead = 0;
  int rgb_value;


  // Bluetooth 受信処理
  if (BT.available()) {

       byteRead = BT.available(); // バッファに溜まっている文字数を取得

       /*
       Serial.println("Reading To Buffer...");
       Serial.println(byteRead);
       Serial.println();
       */
       delay(100);  // 上のシリアルモニターへの処理(負荷)がなくなると、RGB_LEDがうまく点灯しなくなるので、代わりに遅延をかけている。
       
      for(int i=0; i<3; i++){
        buffer[i]= (BT.read());
        buffer[i+1] = '\0';
      }
      //Serial.println(buffer);
  }

  rgb_value = atoi(buffer);   // int型に変換

  if(0<=rgb_value && rgb_value<256){
    // R値
    analogWrite(5,rgb_value);
  }else if(256<=rgb_value && rgb_value<512){
    // G値
    analogWrite(6,rgb_value - 256); // ゲタは外しておく
  }else if(512<=rgb_value && rgb_value<768){
    // B値
    analogWrite(7,rgb_value - 512); // ゲタは外しておく
  }else{
    // error
    //Serial.println("無効値を受信");
  }

  
}

 

Arduinoのリファレンスにあるソフトウェアシリアルのread()関数の戻り値は、char型で受けているので、このスクリプトも文字の終端1byteを加えた4byteのバッファを用意して受け取っています(終端文字を挿入しては上書きするといったおかしなこともしてますが)。バッファに値が入ったら、もう一度int型に変換し直します。RGB値にゲタを履かせてずらして飛ばせば戻すのも切り分けも平易に出来るのでこう言う風にしました。

 

これで準備が整ったので、後は、Arduinoにこのスクリプトを流し込んで、スマホに書き込んだアプリを起動すれば、すでにペアリング済みのBluetooth機器を選択するダイアログが出てくるので、HC-06(実験ではHC-06を使用)を選択すれば、コネクションを確立します。コネクションを確立後、Unityのロゴが出てスライダー画面が出てくるので、スライドするとArduino側に接続されたRGB_LEDが指定のRGB値で点灯するようになります。

 

余談
Arduinoの電源にモバイルバッテリーが使えたらいいなぁとかねてから思ってて、ダイソーで買った300円バッテリーをつなげてみたらやっぱり使えませんでした。5Vの出力あるのになんでかな~とかしばらく考えてましたが、よくよく考えたらArduinoの入力電源はUNOもNANOも7V~12Vだということをすっかり失念してました。そりゃムリだよね。ところで、このダイソーの300円バッテリーせめて他の用途で使えないかなぁと思って、色々調べてみたら(参考サイト http://d.hatena.ne.jp/wakwak_koba/20170603)のような記事をみつけました。なるほど、以前ラジオの電源にしようと使ったらリセットがかかって何度も再起動した原因はこれか~と、納得しました。本当にこのモバイルバッテリーは、充電以外なんの用途にも使えないんですねぇ。残念。

これ1冊でできる! ラズベリー・パイ 超入門 改訂第4版

 

これ1冊でできる! ラズベリー・パイ 超入門 改訂第4版
福田 和宏 (著)

 

まだ実際にラズベリーパイを使っていないので、どんな感じなのかなと思い買ってみました。

 

読みやすい本です。実機を買ってきてやってみたいと思いました。できれば、「Zero W」あたりを都合出来ればコストもかけないで実験できてハッピーなのですが、スイッチサイエンス社のサイトを見ても「Zero」「Zero W」ともに売り切れ状態なのでしばらく待つことになりそうですね。秋葉原のマルツ無線に「Zero W」あるよーというので見にいったんですが、4000円じゃねぇ(;´Д`) それだったらPi3型を買った方がいいんじゃんと思い、結局買いませんでした。でも、秋になったら、Pi3型をやっぱり買おうかなぁと現在迷い中…。

 

★★★★☆ 4点