DIY Arduino Touchscreen MP3-Player & Wecker: Schritt-für-Schritt-Anleitung
In diesem Projekt zeige ich, wie man einen Arduino-Touchscreen-MP3-Player und Wecker baut. Video oder schriftliche Anleitung unten. Startbildschirm: Große Uhr, Datum, Temperatur, Buttons für Music Player und Alarm Clock. Music Player: Großer Play-Button mittig, Previous/Next daneben. Darüber Fortschrittsbalken. Unten Lautstärkebalken mit +/- Buttons. Oben rechts Uhr, links Menu-Button für Startbildschirm. Alarm Clock: Stunden/Minuten per Buttons einstellen. Bei Alarm: Lied startet mit höherer Lautstärke, läuft bis „Dismiss“-Button gedrückt wird. Hardware: Arduino Mega, 3,2″ TFT Touchscreen mit passendem Shield, BY8001-16P MP3-Modul (MicroSD, MP3/WAV, 3W Verstärker), DS3231 Echtzeituhr (RTC). Komponenten-Links: Hinweis: TFT-Shield blockiert freie Arduino-Pins → Custom-Pinheader zwischen Shield & Arduino löten. Zusätzlicher Pinheader an 5V-Pin des Shields (Shield belegt alle VCC-Pins). Empfehlung: Vorher meine Tutorials zu TFT Touchscreen & DS3231 ansehen. MP3-Modul kurz erklärt: Unterstützt MicroSD, MP3/WAV, eingebauter 3W-Verstärker für direkten Lautsprecheranschluss. Steuerung per 5 Tasten oder per Mikrocontroller via Serial. Serial-Pins arbeiten mit 3,3V → RX des Moduls über 1k-Widerstand an Arduino TX. Pads A, B, C für Steuerungsmodus: Für Mikrocontroller-Steuerung 3 Widerstände entfernen. Pins 6/7 für direkten Lautsprecher, 4/5 für externen Verstärker. Arduino: BY8001-Library (GitHub) nutzen. Nach Initialisierung im Setup stehen Funktionen wie Code in Abschnitten erklärt, am Ende komplett. Bibliotheken: UTFT, URTouch (TFT), SoftwareSerial, BY8001, DS3231. Objekte & Variablen definieren. Bitmaps: Buttons als Bilder, mit ImageConverter565 (aus TFT-Library) in .c-Dateien konvertiert. Diese müssen im Sketch-Ordner liegen. Setup: Display, Touch, RTC, Serial (9600) für MP3, MP3-Modul cold boot warten (800ms), Home-Screen zeichnen, Startwerte setzen (Lautstärke 15, Temp, Datum, Uhrzeit). Loop: Drei Hauptbildschirme (Home, Music Player, Alarm Clock) per Uhrzeit jede Sekunde aktualisieren (SevenSegNumFont nur Zahlen → substring für Stunden/Minuten/Sekunden). Datum & Temperatur bei Änderung aktualisieren. Touch abfragen. Play-Button: toggelt Play/Pause. Previous/Next Track, Volume +/- per MP3-Library. Menu-Button → Home. Fortschrittsbalken & Uhrzeit oben rechts aktualisieren. Grafik zeichnen: Uhr, Text, Buttons H/M für Stunden/Minuten, SET, CLEAR. Alarm-Aktivierung: Wenn Kompletter Quellcode am Ende (inkl. aller Draw-Funktionen: Design in SolidWorks. Aluminiumblech per Multitool zuschneiden, an Tischkante mit Schraubzwingen & Latten biegen. Lautsprecher: Lochmuster drucken, aufkleben, bohren. Seiten zuschneiden, an Blech heißkleben. Lackieren, Elektronik einbauen (Heißkleber), Rückdeckel mit 2 Schrauben. Fertig! Fragen in den Kommentaren, Arduino-Projektsammlung anschauen.Überblick




Funktionsweise

Schaltplan


BY8001-16P MP3-Player-Modul


playTrackFromFolder(), pause(), nextTrack(), setVolume() etc. zur Verfügung.Quellcode
#include <UTFT.h>
#include <URTouch.h>
#include <SoftwareSerial.h>
#include <BY8001.h>
#include <DS3231.h>
// Objekte
UTFT myGLCD(SSD1289, 38, 39, 40, 41); // Parameter an Display/Shield anpassen
URTouch myTouch(6, 5, 4, 3, 2);
SoftwareSerial mp3Serial(11, 10); // RX, TX
BY8001 mp3;
DS3231 rtc(SDA, SCL);
// Fonts & Bitmaps (Buttons als Bilder)
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 b = 16;
int aHours = 0; int aMinutes = 0;
boolean alarmNotSet = true; String alarmString = "";
float currentTemperature, temperature;
static word totalTime, elapsedTime, playback, minutes, seconds, lastSeconds, minutesR, secondsR;
String currentClock, currentHours, currentMinutes, currentSeconds, currentDate;
String timeString, hoursString, minutesString, secondsString, hoursS, minutesS, secondsS, dateS;
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 Variable.Home-Screen (currentPage == '0')
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; }
// Datum
dateS = rtc.getDateStr(); delay(10);
if (currentDate != dateS) { myGLCD.setColor(255,255,255); myGLCD.setFont(BigFont); myGLCD.print(rtc.getDateStr(), 153, 7); }
// Temperatur
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();
}
// Touch abfragen
if (myTouch.dataAvailable()) {
myTouch.read(); x = myTouch.getX(); y = myTouch.getY();
// Music Player Button
if (x>=55 && x<=120 && y>=125 && y<=190) {
drawFrame(87,157,33); currentPage='1'; myGLCD.clrScr(); delay(100); drawMusicPlayerScreen(); delay(100);
}
// Alarm Button
if (x>=195 && x<=260 && y>=125 && y<=190) {
drawFrame(227,160,29); currentPage='2'; myGLCD.clrScr();
}
}
}Music Player Screen (currentPage == '1')
if (currentPage == '1') {
if (myTouch.dataAvailable()) {
myTouch.read(); x = myTouch.getX(); y = myTouch.getY();
// Play Button
if (x>=116 && x<=204 && y>=77 && y<=165) {
if (playStatus=='0') { drawFrame(159,121,42); drawPauseButton(); mp3.playTrackFromFolder(00,001); delay(100); playStatus='2'; return; }
if (playStatus=='1') { drawFrame(159,121,42); drawPauseButton(); mp3.play(); delay(100); playStatus='2'; return; }
if (playStatus=='2') { drawFrame(159,121,42); drawPlayButton(); mp3.pause(); delay(100); playStatus='1'; return; }
}
// Previous
if (x>=45 && x<=95 && y>=97 && y<=147) { drawFrame(70,121,26); mp3.previousTrack(); delay(100); drawTrackBar(); }
// Next
if (x>=227 && x<=277 && y>=97 && y<=147) { drawFrame(252,122,26); mp3.nextTrack(); delay(100); drawTrackBar(); }
// Volume Down
if (x>=35 && x<=75 && y>=165 && y<=209) { drawUnderline(45,205,65,205); if(iV>=0 && iV<=30){ iV--; drawVolume(iV);} mp3.decreaseVolume(); delay(100); }
// Volume Up
if (x>=230 && x<=280 && y>=165 && y<=209) { drawUnderline(235,205,275,205); if(iV>=0 && iV<=30){ iV++; drawVolume(iV);} mp3.increaseVolume(); delay(100); }
// Menu
if (x>=0 && x<=75 && y>=0 && y<=30) { myGLCD.clrScr(); drawHomeScreen(); currentPage='0'; return; }
}
// Trackbar updaten
if (playStatus=='1' || playStatus=='2') trackPlayTime();
// Uhr oben rechts
myGLCD.setFont(BigFont); myGLCD.setColor(255,255,255); printClock(187,5);
}trackPlayTime() nutzt MP3-Library-Funktionen (getTotalTrackPlaybackTime(), getElapsedTrackPlaybackTime()) für vergangene/verbleibende Zeit & Balken. Bei Titelende → nächster Track.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); }
}Alarm Clock Screen (currentPage == '2')
alarmNotSet = true → While-Schleife für Einstellung. H/M Buttons erhöhen Werte (Modulo 24/60). SET speichert formatierten String in alarmString (Format HH:MM:00 passend zu rtc.getTimeStr()). CLEAR löscht Alarm. Menu → Home.if (currentPage == '2') {
myGLCD.setFont(BigFont); myGLCD.setColor(255,255,255);
myGLCD.print("MENU",5,5); myGLCD.print("Set Alarm",CENTER,20);
myGLCD.setColor(0,255,0); myGLCD.fillCircle(112,65,4); myGLCD.fillCircle(112,85,4); // Doppelpunkt
myGLCD.setFont(SevenSegNumFont); myGLCD.setColor(0,255,0);
myGLCD.printNumI(aHours,32,50,2,'0'); myGLCD.printNumI(aMinutes,128,50,2,'0');
myGLCD.setColor(255,255,255);
myGLCD.drawRoundRect(42,115,82,145); myGLCD.drawRoundRect(138,115,178,145);
myGLCD.setFont(BigFont); myGLCD.print("H",54,122); myGLCD.print("M",150,122);
myGLCD.drawRoundRect(215,60,303,90); myGLCD.print("SET",236,67);
myGLCD.drawRoundRect(215,115,303,145); myGLCD.print("CLEAR",220,122);
alarmNotSet = true;
while (alarmNotSet) {
if (myTouch.dataAvailable()) {
myTouch.read(); x=myTouch.getX(); y=myTouch.getY();
// H Button
if (x>=42 && x<=82 && y>=115 && y<=145) { drawRectFrame(42,115,82,145); aHours++; if(aHours>=24) aHours=0; myGLCD.setFont(SevenSegNumFont); myGLCD.setColor(0,255,0); myGLCD.printNumI(aHours,32,50,2,'0'); }
// M Button
if (x>=138 && x<=178 && y>=115 && y<=145) { drawRectFrame(138,115,178,145); aMinutes++; if(aMinutes>=60) aMinutes=0; myGLCD.setFont(SevenSegNumFont); myGLCD.setColor(0,255,0); myGLCD.printNumI(aMinutes,128,50,2,'0'); }
// SET Button
if (x>=215 && x<=303 && y>=60 && y<=80) {
drawRectFrame(215,60,303,90);
// alarmString formatieren HH:MM:00
if (aHours<10 && aMinutes<10) alarmString = "0"+String(aHours)+":0"+String(aMinutes)+":00";
else if (aHours<10 && aMinutes>9) alarmString = "0"+String(aHours)+":"+String(aMinutes)+":00";
else if (aHours>9 && aMinutes<10) alarmString = String(aHours)+":0"+String(aMinutes)+":00";
else alarmString = String(aHours)+":"+String(aMinutes)+":00";
myGLCD.setFont(BigFont); myGLCD.print("Alarm set for:",CENTER,165); myGLCD.print(alarmString,CENTER,191);
}
// CLEAR Button
if (x>=215 && x<=303 && y>=115 && y<=145) { drawRectFrame(215,115,303,145); alarmString=""; myGLCD.setColor(0,0,0); myGLCD.fillRect(45,165,275,210); }
// Menu Button
if (x>=0 && x<=75 && y>=0 && y<=30) { alarmNotSet=false; currentPage='0'; myGLCD.clrScr(); drawHomeScreen(); }
}
}
}alarmNotSet == false und alarmString == rtc.getTimeStr() → Lautstärke 25, ersten Track spielen, „ALARM“ Grafik + DISMISS-Button anzeigen, alarmOn = true → While-Schleife bis DISMISS gedrückt → Alarm stoppen, Lautstärke zurück auf 15, Home-Screen.if (alarmNotSet == false) {
if (alarmString == rtc.getTimeStr()) {
myGLCD.clrScr(); mp3.setVolume(25); mp3.playTrackByIndexNumber(1); delay(100);
myGLCD.setFont(BigFont); myGLCD.setColor(255,255,255);
myGLCD.print("ALARM",CENTER,90); myGLCD.drawBitmap(127,10,65,64,AlarmButton);
myGLCD.print(alarmString,CENTER,114);
myGLCD.drawRoundRect(94,146,226,170); myGLCD.print("DISMISS",CENTER,150);
boolean alarmOn = true;
while (alarmOn) {
if (myTouch.dataAvailable()) {
myTouch.read(); x=myTouch.getX(); y=myTouch.getY();
if (x>=94 && x<=226 && y>=146 && y<=170) {
drawRectFrame(94,146,226,170); alarmOn=false; alarmString="";
myGLCD.clrScr(); mp3.stopPlayback(); delay(100);
currentPage='0'; playStatus='0'; mp3.setVolume(15); drawHomeScreen();
}
}
}
}
}drawHomeScreen, drawMusicPlayerScreen, drawFrame, drawRectFrame, drawUnderline, drawVolume, drawTrackBar, printClock, drawColon, drawHomeClock)./* Arduino Touch Screen MP3 Music Player and Alarm Clock
by Dejan Nedelkovski, www.HowToMechatronics.com
Libraries: UTFT, URTouch, DS3231 (Henning Karlsen), BY8001 (borland) */
#include <UTFT.h> #include <URTouch.h> #include <SoftwareSerial.h> #include <BY8001.h> #include <DS3231.h>
// ... (vollständiger Code wie im Original) ...
Gehäuse bauen




Herstellungsprozess
- Arduino POV-Uhr: Persistence-of-Vision LED-Display selbst bauen
- Einen eigenen LED-Master-Clock mit Alarm bauen – aus 12 Metern Entfernung ablesbar
- Arduino Temperaturoverwachung & Echtzeituhr mit 3,2″ TFT-Display
- Audio-Wiedergabe mit Arduino UNO und DFPlayer Mini – Schritt-für-Schritt-Anleitung
- TM1637 Digitaluhr mit Zeiteinstellung & Alarm – Arduino Nano Prototyp
- Arduino Web-MP3-Player: Browsergesteuerte Audio-Wiedergabe
- Arduino Tic Tac Toe mit MAX7219 LED-Matrix und Karton-Gehäuse
- DIY-Voltmeter mit Arduino und Nokia 5110 Display – Schritt-für-Schritt-Anleitung
- Zuverlässigen Arduino-Countdown-Timer mit SparkFun 7-Segment-Display bauen
- Zuverlässigen Wecker mit DS1302 RTC und Arduino UNO bauen