Arduinoを用いて毎時00分に音楽再生をする装置を作る


毎時00分に音楽再生する装置を作ります。例えば、毎時00分にディズニーの音楽をランダム再生して心を癒す日常業務の自動化などに使えます。

準備

こちらこちらの過去記事で用いたものを再利用します。

Arduino UNO R3 互換品
HiLetgo® 2個セットDC 5V HD44780 1602 LCD ディスプレイモジュール 16×2キャラクタ LCDブルーブラックライト
HiLetgo® 5個セット5V 1602LCD IIC/I2C/TWI/SPIシリアルインターフェイスモジュールポートarduinoに対応
RTC DS3231 AT24C32 時計モジュール
電池 LIR2032
DFPlayerMini
・マイクロSDカード
・スピーカ(100均のものでOK)
・ブレットボード
・ジャンパワイヤ 多数

回路図

こちらこちらの過去記事で用いた回路を繋げます。

コード

毎時00分に音楽をランダム再生します。
ランダム再生する曲番号のrangeは適宜調整下さい。

setup関数: RTC/LCD/DFPlayerMiniの初期化を行います
PrintRTCInfoToLCD関数: RTCの情報をLCDに出力します
PLAYBACK_MP3_MUSIC関数:DFPlayerが再生可能な場合に音楽再生を行います
GetIntegerFromRTC関数: RTCの情報から日、月、年をint型で取得します。
loop関数: 1秒置きに処理を繰り返します

#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include <string.h>
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#define BUSY_PINNO 7

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
DS3231  rtc(SDA, SCL);
//SoftwareSerial mySoftwareSerial(10, 11); // (TX, RX)
SoftwareSerial mySoftwareSerial(3, 2); // (TX, RX)
DFRobotDFPlayerMini myDFPlayer;
long randNumber;

void setup() {
  lcd.init();                      // initialize the lcd 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Hello, world!");
  lcd.setCursor(0,1);
  lcd.print("Arduino LCM IIC 2004");

  // Setup Serial connection
  Serial.begin(115200);
  // Initialize the rtc object
  rtc.begin();

  delay (3000);
  String BLANK = "                ";
  lcd.setCursor(0,0);
  lcd.print( BLANK );
  lcd.setCursor(0,1);
  lcd.print( BLANK );

  // set the date and time.
  //rtc.setDOW(SUNDAY);     // Set Day-of-Week
  //rtc.setTime(13, 20, 0);     // Set the time to HH:MM:SS (24hr format)
  //rtc.setDate(10, 2, 2019);   // Set the date (DD, MM, YYYY)


    // software serial init
  mySoftwareSerial.begin(9600);
  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);
  }

  // BUSY_PINNO init
  pinMode(BUSY_PINNO, INPUT);

  // DFPlayer Init
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms  
  myDFPlayer.volume(25);  //Set volume value (0~30).
  // myDFPlayer.volumeUp(); //Volume Up
  // myDFPlayer.volumeDown(); //Volume Down  
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);   

  //randomSeed  
  randomSeed(analogRead(0));

  /*
  for (int i=1; i<43; i++) {
    randNumber = random(1,43);
    myDFPlayer.play(randNumber); // play randnumber..
    //myDFPlayer.play(i);
    Serial.print("Play Num:");Serial.println(randNumber);
    delay(5000);
  }*/
}

void PrintRTCInfoToLCD() {

  String strDOW = rtc.getDOWStr();
  String strDate = rtc.getDateStr();
  String strTime = rtc.getTimeStr();
  int iTemp = rtc.getTemp();

  lcd.setCursor(0,0);
  lcd.print( strDate );

  lcd.setCursor(0,1);
  lcd.print( strTime );

  lcd.setCursor(9,1);
  lcd.print( strDOW );  
}

void PLAYBACK_MP3_MUSIC(void) {
  int isBusy = digitalRead(BUSY_PINNO); // 0:playing, 1:not playing (refer website)
  Serial.println(isBusy);
  if (isBusy == 1) {
    randNumber = random(1,43);   // get random number from range 1-42
    myDFPlayer.play(randNumber); // play randnumber..
  }
}

void GetIntegerFromRTC() {

  String strDate = rtc.getDateStr();
  String strTime = rtc.getTimeStr();  
  int len = strDate.length() + 1;
  int len_Time = strDate.length() + 1;
  char tmpstr[len];
  char tmpstr_Time[len_Time];
  char *tp;
  char cDay[3], cMonth[3], cYear[5], cHour[3], cMin[3], cSec[3];
  int  iDay, iMonth, iYear, iHour, iMin, iSec;

  strDate.toCharArray(tmpstr, len);
  Serial.println(tmpstr);

  // get day
  tp = strtok(tmpstr, ".");
  strcpy(cDay, tp);
  iDay = atoi(cDay);

  // get month
  tp = strtok(NULL, ".");
  strcpy(cMonth, tp);
  iMonth = atoi(cMonth);

  // get year
  tp = strtok(NULL, ".");
  strcpy(cYear, tp);
  iYear = atoi(cYear);

  strTime.toCharArray(tmpstr_Time, len_Time);

  // get day
  tp = strtok(tmpstr_Time, ":");
  strcpy(cHour, tp);
  iHour = atoi(cHour);

  // get month
  tp = strtok(NULL, ":");
  strcpy(cMin, tp);
  iMin = atoi(cMin);

  // get year
  tp = strtok(NULL, ":");
  strcpy(cSec, tp);
  iSec = atoi(cSec);

  Serial.println("----");
  Serial.print("Day   :");Serial.println(iDay);
  Serial.print("Month :");Serial.println(iMonth);
  Serial.print("Year  :");Serial.println(iYear);
  Serial.print("Hour  :");Serial.println(iHour);
  Serial.print("Min   :");Serial.println(iMin);
  Serial.print("Sec   :");Serial.println(iSec);
  Serial.println("----");

  if (iMin == 0) {
    PLAYBACK_MP3_MUSIC();
  }
}

void loop() {

  PrintRTCInfoToLCD();
  GetIntegerFromRTC();

  delay (1000);
}

テスト

毎時00分になるのを待ち、ランダムでSDカードに保存しているMP3の曲を再生できればOKです。

現状、深夜1:00-以降も毎時00分に音楽再生を行ってしまい睡眠の妨げになることが課題です。
おやすみモードの追加が必要かもしれません。

参考

組み込みエンジニアでなくても週末にArduinoを使って遊ぶ
ArduinoにDFPlayerMiniを繋いでmp3音楽再生をする
Arduinoにリアルタイムクロックモジュール とLCDを繋いで小さな時計を作成する