ArduinoタッチスクリーンMP3プレーヤー&アラームクロック自作:ステップバイステップガイド
概要
3.2インチTFTタッチスクリーン搭載のArduino MP3プレーヤー兼アラームクロックを製作します。ホーム画面には大型時計、日付、温度、ミュージックプレーヤーとアラームクロックへのボタンを配置。

ミュージックプレーヤー画面
中央に大きな再生/一時停止ボタン、左右に前/次曲ボタン。上部に再生プログレスバーと経過/残り時間。下部に音量バーと音量±ボタン。右上に時計、左上にメニューボタン(ホーム復帰)。

アラームクロック画面
時・分設定ボタン(H/M)でアラーム時刻設定。SETで確定、CLEARでクリア。アラーム時刻になると最初の曲が大音量で再生開始、DISMISSボタン押下まで継続。


仕組み
Arduino Mega + 3.2" TFTタッチスクリーン(専用シールド)+ BY8001-16P MP3モジュール(MicroSD、3Wアンプ内蔵)+ DS3231 RTCモジュール(時計・温度)。

必要な部品
- BY8001-16P MP3モジュール
- 3.2" TFTタッチディスプレイ
- TFTディスプレイ Megaシールド
- 0.5Wスピーカー
- DS3231 RTCモジュール
- Arduino Mega
回路図

TFTシールドがArduinoピンを塞ぐため、シールドとArduinoの間にカスタムピンヘッダーを挟んで配線取り出し。また、シールドがArduino VCCピンを全て使用するため、シールド上の5Vピンに追加ピンヘッダーをはんだ付けして電源取り出し。

TFTタッチスクリーンとDS3231 RTCの詳細接続は過去チュートリアル参照。BY8001 MP3モジュールはここで簡単に説明。
BY8001-16P MP3プレイヤーモジュール
MicroSD対応、MP3/WAV再生、内蔵3Wアンプでスピーカー直駆動可能。5入力ピンでボタン制御、またはシリアル通信でマイコン制御。


シリアルピンは3.3V動作のため、RXピンは1kΩ抵抗経由でArduino TXに接続。モード選択パッドA/B/Cの抵抗を除去してマイコン制御モードに。スピーカーはピン6/7(直駆動)または4/5(外部アンプ用)。Arduino側はBY8001ライブラリ(GitHub)使用が最簡単。
ソースコード解説
TFT用UTFT/URTouch、BY8001、DS3231、SoftwareSerialライブラリをインクルード。オブジェクト生成と変数定義。
#include <UTFT.h> #include <URTouch.h> #include <SoftwareSerial.h>
#include <BY8001.h> #include <DS3231.h>
UTFT myGLCD(SSD1289, 38, 39, 40, 41); // シールド/ディスプレイに合わせて調整
URTouch myTouch(6, 5, 4, 3, 2);
SoftwareSerial mp3Serial(11, 10); // RX, TX
BY8001 mp3; DS3231 rtc(SDA, SCL);
// フォントとビットマップ画像定義
extern uint8_t SmallFont[]; extern uint8_t BigFont[]; extern uint8_t SevenSegNumFont[];
extern unsigned int MusicPlayerButton[0x1040]; extern unsigned int AlarmButton[0x1040];
extern unsigned int ButtonPlay[0x1AE9]; extern unsigned int ButtonPause[0x1AE9];
extern unsigned int PreviousButton[0x9C4]; extern unsigned int NextButton[0x9C4];
extern unsigned int VolumeDown[0x170]; extern unsigned int VolumeUp[0x3B8];
// 変数群
int x, y; char currentPage, playStatus; int iV = 15; int trackNum = 1;
int aHours = 0, aMinutes = 0; boolean alarmNotSet = true; String alarmString = "";
// ... 時間・日付・温度・プログレスバー用変数 ...
ビットマップ画像はImageConverter565ツールで変換した.cファイルをスケッチフォルダに配置。画像と.cファイルダウンロード。

setup()でディスプレイ初期化、タッチ精度設定、RTC開始、シリアル通信開始(9600bps)、MP3モジュール初期化(コールドブート待ち800ms)、ホーム画面描画、初期値設定(音量15、現在温度/日付/時刻取得)。
void setup() {
myGLCD.InitLCD(); myGLCD.clrScr(); myTouch.InitTouch(); myTouch.setPrecision(PREC_MEDIUM);
rtc.begin();
Serial.begin(9600); mp3Serial.begin(9600); mp3.setup(mp3Serial); delay(800);
drawHomeScreen(); currentPage='0'; playStatus='0'; mp3.setVolume(15); delay(100);
currentTemperature = rtc.getTemp(); currentDate = rtc.getDateStr(); currentClock = rtc.getTimeStr();
// 時刻文字列分解
timeString = rtc.getTimeStr();
currentHours = timeString.substring(0,2); currentMinutes = timeString.substring(3,5); currentSeconds = timeString.substring(6,8);
}
メインループ:ホーム画面(currentPage='0')
毎秒RTCから時刻取得、SevenSegNumFontで時:分:秒表示(文字非対応フォントのためsubstringで数字抽出)。日付・温度変化時のみ再描画。
if (currentPage == '0') {
if (currentClock != rtc.getTimeStr()) {
timeString = rtc.getTimeStr();
hoursS = timeString.substring(0,2); minutesS = timeString.substring(3,5); secondsS = timeString.substring(6,8);
myGLCD.setFont(SevenSegNumFont); myGLCD.setColor(0,255,0);
myGLCD.print(secondsS, 224, 50);
if (currentMinutes != minutesS) { myGLCD.print(minutesS, 128, 50); currentMinutes = minutesS; }
if (currentHours != hoursS) { myGLCD.print(hoursS, 32, 50); currentHours = hoursS; }
// 日付・温度チェック同様
dateS = rtc.getDateStr(); delay(10);
if (currentDate != dateS) { myGLCD.setColor(255,255,255); myGLCD.setFont(BigFont); myGLCD.print(rtc.getDateStr(), 153, 7); }
temperature = rtc.getTemp(); delay(10);
if (currentTemperature != temperature) { myGLCD.setColor(255,255,255); myGLCD.setFont(BigFont); myGLCD.printNumI(temperature, 39, 7); currentTemperature = temperature; }
delay(10); currentClock = rtc.getTimeStr();
}
タッチ検出でミュージックプレーヤーボタン(座標判定)なら赤フレーム表示→currentPage='1'→画面クリア→ミュージック画面描画。アラームボタンならcurrentPage='2'→画面クリア。
ミュージックプレーヤー画面(currentPage='1')
タッチ判定で各ボタン処理:
- 再生ボタン:playStatus='0'なら初回再生(playTrackFromFolder)、『一時停止』ボタン画像表示、playStatus='2'。'1'なら再開(play())、'2'なら一時停止(pause())。トグル動作。
- 前/次曲ボタン:previousTrack()/nextTrack()、プログレスバー再描画。
- 音量±ボタン:increaseVolume()/decreaseVolume()、音量バー更新(iV変数0-30管理)。
- メニューボタン:ホーム画面復帰(currentPage='0')。
再生中(playStatus='1'または'2')はtrackPlayTime()でプログレスバー更新。mp3.getTotalTrackPlaybackTime()/getElapsedTrackPlaybackTime()で時間取得、map()でバー長算出。曲終了検知で自動次曲再生。右上時計表示(printClock())。
void trackPlayTime() {
totalTime = mp3.getTotalTrackPlaybackTime(); delay(10);
elapsedTime = mp3.getElapsedTrackPlaybackTime(); delay(10);
minutes = (int)elapsedTime / 60; seconds = (((float)elapsedTime/60)-minutes)*60;
playback = totalTime - elapsedTime; minutesR = (int)playback/60; secondsR = (((float)playback/60)-minutesR)*60;
myGLCD.setFont(SmallFont); myGLCD.setColor(255,255,255);
myGLCD.printNumI(minutes, 8, 48); myGLCD.print(":", 16, 48); myGLCD.printNumI((int)seconds, 24, 48, 2, '0');
myGLCD.print("-", 276, 48); myGLCD.printNumI(minutesR, 284, 48); myGLCD.print(":", 292, 48); myGLCD.printNumI((int)secondsR, 300, 48, 2, '0');
int trackBarX = map(elapsedTime, 0, totalTime, 0, 224);
myGLCD.setColor(255,0,0); myGLCD.fillRect(48, 50, 48+trackBarX, 58);
if (totalTime == elapsedTime) { mp3.nextTrack(); delay(30); myGLCD.setColor(255,255,255); myGLCD.fillRect(48,50,272,58); }
}
アラームクロック画面(currentPage='2')
画面描画後、alarmNotSet=trueで設定ループ突入。H/Mボタンで時/分インクリメント(24/60でロールオーバー)、SETでalarmString生成(RTCのgetTimeStr()形式"HH:MM:SS"に合わせる)、CLEARでクリア、メニューでホーム復帰。
if (aHours < 10 && aMinutes < 10) alarmString = "0"+String(aHours)+":0"+String(aMinutes)+":00";
// 他ケース同様
myGLCD.print("Alarm set for:", CENTER, 165); myGLCD.print(alarmString, CENTER, 191);
アラーム作動判定
alarmNotSet=false(設定完了)かつ alarmString == rtc.getTimeStr() で作動。音量25に上げ、1曲目再生、アラーム画面描画、DISMISSボタン待ちループ。押下で停止、音量15復帰、ホーム画面戻り、alarmStringクリア。
if (alarmNotSet == false) {
if (alarmString == rtc.getTimeStr()) {
myGLCD.clrScr(); mp3.setVolume(25); mp3.playTrackByIndexNumber(1); delay(100);
// 画面描画...
boolean alarmOn = true;
while (alarmOn) {
if (myTouch.dataAvailable()) { // DISMISSボタン判定
drawRectFrame(94,146,226,170); alarmOn=false; alarmString="";
myGLCD.clrScr(); mp3.stopPlayback(); delay(100);
currentPage='0'; playStatus='0'; mp3.setVolume(15); drawHomeScreen();
}
}
}
}
筐体製作
SolidWorksで設計。アルミ板をマルチツールで切断、机のエッジとクランプ・木材で曲げ加工。


スピーカー部は円形パターン印刷・貼り付け→ドリルで穴あけ。側面を切断成形、グルーガンで接着。塗装後、電子部品をグルーガン固定、配線、裏蓋をボルト2本で固定して完成。


完全なソースコード
記事末尾に完全版掲載(描画関数drawHomeScreen/drawMusicPlayerScreen/drawHomeClock等、ヘルパー関数含む全コード)
質問はコメント欄へ。Arduinoプロジェクトコレクションもご覧ください。
製造プロセス
- Arduino POVクロック:残像効果で浮かび上がるLED時計を自作する
- 12メートル先から見える大型LEDマスタークロック(アラーム機能付き)を自作しよう
- Arduino Dueと3.2インチTFTで作る温度監視付きリアルタイムクロック
- Arduino UNOとDFPlayer Miniで音声を再生する方法 - ステップバイステップガイド
- TM1637デジタル時計:時刻設定・アラーム機能付き Arduino Nano試作版
- Arduinoウェブ制御MP3プレーヤー:ブラウザから簡単オーディオ再生
- Arduino三目並べ:MAX7219 LEDマトリクスと段ボールケースで自作
- ArduinoとNokia 5110ディスプレイで自作電圧計:ステップバイステップガイド
- SparkFun 7セグメントディスプレイで作る信頼性の高いArduinoカウントダウンタイマー
- eDOT:高精度Arduino時計・気象ステーション(IRリモコン・自動輝度調整内蔵)
- DS1302 RTCとArduino UNOで作る信頼性の高い目覚まし時計