在这个项目中,我将向您展示如何制作Arduino触摸屏MP3音乐播放器和闹钟。您可以观看以下视频或阅读下面的书面教程。
主屏幕上有一个大时钟、日期和温度信息,还有两个音乐播放器和闹钟按钮。
如果我们进入音乐播放器,我们可以通过按屏幕中间的大“播放”按钮开始播放音乐。在它的旁边,还有两个按钮,用于播放上一首或下一首歌曲。
在这些按钮上方有歌曲进度栏,并且在屏幕底部我们有一个卷栏和两个按钮,用于减小和增加卷。在右上角有一个时钟,左侧是“菜单”按钮,使我们返回主屏幕。
另一方面,如果我们输入闹钟,我们可以使用两个按钮设置警报来设置小时和分钟。
当警报被激活时,一首歌会以更高的音量播放,它会一直播放,直到我们按下“解散”按钮。
亚博88下载
现在让我们来看看这个设备是如何工作的。它使用Arduino Mega板和3.2英寸TFT触摸屏,并配有合适的屏蔽板连接屏幕和Arduino板。播放音乐使用BY8001 MP3播放器模块,闹钟使用DS3231实时时钟模块。
您可以从下面的链接获取此Arduino项目所需的组件:
- BY8001-16P MP3模块.........亚马逊/aliexpress.
- 3.2″TFT触摸屏.............亚马逊/伯格多德/aliexpress.
- TFT显示屏巨盾...........亚马逊/伯格多德/aliexpress.
- 0.5W扬声器............................亚马逊/伯格多德/aliexpress.
- DS3231实时时钟......... ..亚马逊/伯格多德/aliexpress.
- Arduino Mega ........................... ..亚马逊/伯格多德/aliexpress.
yaboAG娱乐城披露:这些是附属链接。作为一个亚马逊助理,我从合格的购买中赚取。
电路示意图
这是该项目的电路原理图:
我们可以在此处注意到TFT屏蔽阻挡了Arduino板的自由销,因此我们需要制作定制的销标题,我们将能够在盾牌和arduino之间插入它们。
还需要注意的是,为了驱动Arduino,我们需要焊接额外的引脚头到屏蔽上的5 V引脚,因为屏蔽已经使用了所有Arduino VCC引脚。
一旦我们将所有东西连接在一起,我们就可以继续编程Arduino。但是,在我们继续之前,我会建议您查看我以前的详细教程TFT触摸屏和DS3231实时时钟模块。至于MP3播放器模块,我将在本文中进行简要说明。
BY8001-16P MP3播放器模块
BY8001-16P是一种用MICROD卡配合使用MP3模块,支持MP3和WAV音频格式文件。该模块具有内置的3W功率放大器,可直接驱动单个3W扬声器。
MP3播放器模块可以使用5个输入引脚进行按钮控制,也可以通过串行通信使用微控制器。
请注意,模块的串行端口引脚在3.3V下工作,因此模块的RX引脚需要通过1K电阻连接到Arduino TX引脚。还要注意用于选择控制模式的3个端口A,B和C.为了使用微控制器控制模块,需要去除这些焊盘处的3个电阻。如果使用外部放大器,则引脚6和7可用于直接连接低功率扬声器或引脚数4和5。
至于Arduino部分最简单的方法是使用BY8001图书馆可以从GitHub下载。如果我们打开它的一些演示例子,我们可以看到它是如何工作的。亚博88下载因此,在设置部分初始化模块后,我们可以使用任何定制函数来控制模块。
源代码
现在我们准备看看这个Arduino触摸屏MP3屏幕音乐播放器和闹钟的代码。由于代码更长,因此为了更好地理解,我将在每个部分的描述中发布程序的源代码。并且在本文的末尾,我将发布完整的源代码。
所以,首先,我们需要包括图书馆TFT.触摸屏,BY8001-16P MP3播放器和DS3231实时时钟模块以及串行通信库。然后,我们必须创建适当的对象,并定义程序所需的一些变量。
#include#include #include #include #include //====创建对象UTFT myGLCD(SSD1289, 38,39,40,41);//参数应该调整到您的Display/Schield模型URTouch myTouch(6,5,4,3,2);SoftwareSerial mp3Serial(11、10);// RX, TX BY8001 mp3;//创建一个类BY8001的实例并调用它'mp3' DS3231 rtc(SDA, SCL);//==== Defining Fonts extern uint8_t SmallFont[];走读生uint8_t BigFont [];走读生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; // Variables for the coordinates where the display has been pressed 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;
我们可以在这里注意位图的定义。程序中的一些按钮实际上是使用TFT库附带的ImageConverter565工具将其转换为位图的图像。
因此,这些“.c”文件需要包含在代码文件的目录中,以便在启动草图时加载。在这里,您可以下载这些图像和“.c”文件。
在初始化对象后的“设置”部分中,我们调用绘制屏幕()自定义函数,该函数绘制主屏幕的所有图形。此外,我们还设置一些变量的初始值,如playstatus,currenttemp和日期,卷的初始值等。
void setup(){//启动display myglcd.initlcd();myglcd.clrscr();mytouch.inittouch();mytouch.setPrecision(prec_medium);//初始化rtc.begin();//音乐串行.Begin(9600);//将串行监控波特率设置为Arduino IDE mp3serial.begin(9600);// by8001设置为9600波特(必填)MP3.Setup(MP3Serial);//告诉By8001库使用哪个串行端口使用。延迟(800); // allow time for BY8001 cold boot; may adjust depending on flash storage size drawHomeScreen(); // Draws the Home Screen currentPage = '0'; // Indicates that we are at Home Screen 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); }
接下来是循环部分。第一个IF语句是真的,因为我们将CharecatPage变量设置为0,表示我们在主屏幕上。在这里,我们检查我们是否有时钟的变化,这会发生这种情况。Now as we are using the seven segment font of the TFT libraries, which doesn’t support any character except numbers, we have to extract only the numbers from the string that is coming with the getTimeStr() function for reading the clock from the DS3231 RTC module.
所以使用子字符串()函数我们将小时数,分钟和秒数变成单独的变量,并每次在秒,分钟或时间发生更改时打印它们。
至于日期和温度,类似,我们检查与以前的状态相比是否存在变化。
void loop(){// homes屏幕if(currentpage =='0'){//检查时钟的更改if(currenclock!= rtc.gettimestr()){timestring = rtc.gettimestr();小时=时间戳。(0,2);minutess =时间戳。(3,5);秒=时间=时间戳。(6,8);myglcd.setfont(sevEndebygnumfont);myglcd.setcolor(0,255,0);myglcd.print(秒,224,50);if(prossminutes!= minutess){myglcd.print(Minutess,128,50);CurrentMinutes = Moutess;}如果(Currenthours!=少次){myglcd.print(小时,32,50); currentHours = hoursS; } // Checks for change of the date dateS = rtc.getDateStr(); delay(10); if ( currentDate != dateS){ myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(BigFont); // Sets font to big myGLCD.print(rtc.getDateStr(), 153, 7); } // Checks for change of the temperature temperature = rtc.getTemp(); delay(10); if ( currentTemperature != temperature ){ myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(BigFont); // Sets font to big myGLCD.printNumI(temperature, 39, 7); currentTemperature = temperature; } delay(10); currentClock = rtc.getTimeStr(); }
接下来,使用MyTouch.DataAvailable()函数我们检查我们是否已触摸屏幕,并检查它是音乐播放器还是报警按钮。因此,如果这是音乐播放器按钮,首先我们调用绘制框架()自定义函数,该函数在按钮上绘制红色圆圈,指示按下该按钮。此外,此自定义功能也有一段时间循环,该循环按住堆叠的程序,直到我们释放按钮。在此之后,我们将CurrendPage变量设置为1,清除屏幕并调用绘制函数的自定义功能,绘制音乐播放器屏幕的所有图形。类似,如果我们按下警报按钮,我们将CurrendPage变量设置为2并清除屏幕。
//检查屏幕是否已被触摸(mytouch.dataavailable()){mytouch.read();x = mytouch.getx();// x坐标屏幕已按下y = mytouch.gety();// y坐标,其中按下屏幕//如果((x> = 55)&&(x <= 120)&&(y> = 125)&&(y <= 190)){拉丝框架(87,157,33);currationPage ='1';myglcd.clrscr();延迟(100);drawmusicplayerscreen();延迟(100); } // If we press the Alarm Button if ((x >= 195) && (x <= 260) && (y >= 125) && (y <= 190)) { drawFrame(227, 160, 29); currentPage = '2'; myGLCD.clrScr(); } }
接下来,让我们看看音乐播放器屏幕中会发生什么。在这里,我们一直在检查我们是否触摸了屏幕。如果我们触摸播放按钮,当前PlayStatus变量为0,我们将调用MP3.PlayTrackFromFolder()函数,这将开始播放MicroSD卡的第一首歌曲。同时,我们调用drawPauseButton()自定义函数,它绘制暂停按钮并将PlayStatus变量设置为2.使用接下来的两个IF语句,具体取决于PlayStatues变量,我们在播放和暂停歌曲之间切换。
//音乐播放器屏幕if(currentpage =='1'){if(mytouch.dataavailable()){mytouch.read();x = mytouch.getx();// x坐标屏幕已按下y = mytouch.gety();// y坐标,如果我们按下屏幕//如果我们按下播放按钮((x> = 116)&&(x <= 204)&&(y> = 77)&&(y <= 165)){if(playstatus =='0'){drawFrame(159,121,42);TraxPauseButton();mp3.playtrackfromfolder(00,001);延迟(100);playstatus ='2';返回; } 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; } }
以类似的方式,对于每个按下按钮,我们调用适当的功能来播放上一个或下一曲目,减少或增加音量,以及将我们带回主屏幕的“菜单”按钮。
//如果((x> = 45)&&(x <= 95)&&(y> = 97)&&(y <= 147)))&&(y <= 147)),则按先前按钮(x <= 147));mp3.previoustrack();延迟(100);drawtrackbar();} //如果我们按下下一个按钮((x> = 227)&&(x <= 277)&&(y> = 97)&&(y <= 147)){drawFrame(252,122,26);mp3.nexttrack();延迟(100);drawtrackbar();如果((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); } // If we press the VolumeUp Button 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); } // If we press the MENU Button if ((x >= 0) && (x <= 75) && (y >= 0) && (y <= 30)) { myGLCD.clrScr(); drawHomeScreen(); // Draws the Home Screen currentPage = '0'; return; }
下一个IF语句用于更新轨道进度条。
//更新跟踪条if (playStatus == '1' || playStatus == '2') {trackPlayTime();}
因此,如果音乐正在播放,我们调用trackPlayTime()自定义函数,该函数使用一些音乐播放器库函数,如mp3.getElapsedTrackPlaybackTime(),计算和打印经过和保留的时间以及轨道进度条图形。使用printClock()自定义函数,我们在右上角打印时钟。
//更新曲目栏void trackplayTime(){totaltime = mp3.gettotaltrackplay walktime();延迟(10);ElapsedTime = mp3.getelapsedtrackplaybacktime();延迟(10);分钟=(int)闪光时间/ 60;秒=((((浮点)闪光时间/ 60) - 分钟)* 60;播放= TOMPTIME - ELAPSEDTIME;分钟=(int)播放/ 60;秒=(((浮点)播放/ 60) - 分钟数* 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, 50 + 8); if (totalTime == elapsedTime) { mp3.nextTrack(); delay(30); myGLCD.setColor(255, 255, 255); myGLCD.fillRect (48, 50, 48 + 224, 50 + 8); } }
接下来是闹钟屏幕。在这里,首先我们绘制所有图形,时钟,文本和按钮,并将变量analarnotset设置为真实,以便我们可以进入下一个循环。在这里使用两个按钮,h和m,我们设置警报,一旦我们单击“Set”按钮,警报的值将存储到辐射变量中。
//闹钟屏幕if(currentpage =='2'){myglcd.setfont(bigfont);myglcd.setcolor(255,255,255);myglcd.print(“菜单”,5,5);myglcd.print(“设置警报”,中心,20);//在几小时内绘制冒号,分钟myglcd.setcolor(0,255,0);myglcd.fillcircle(112,65,4);myglcd.setcolor(0,255,0);myglcd.fillcircle(112,85,4);myglcd.setfont(sevEndebygnumfont);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(); // X coordinate where the screen has been pressed y = myTouch.getY(); // Y coordinates where the screen has been pressed //Set hours 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'); } // Set minutes buttons 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 alarm button if ((x >= 215) && (x <= 303) && (y >= 60) && (y <= 80)) { drawRectFrame(215, 60, 303, 90); 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 alarm 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); } // If we press the MENU Button if ((x >= 0) && (x <= 75) && (y >= 0) && (y <= 30)) { alarmNotSet = false; currentPage = '0'; myGLCD.clrScr(); drawHomeScreen(); // Draws the Home Screen } } } }
请注意,我们需要调整此字符串以具有与来自GetTimestring()函数获得的字符串相同的表单。通过这种方式,我们将能够将它们进行比较并在时钟达到相同的值或时间时激活警报。
如果我们按下清除按钮,我们将清除AlarmString,如果我们按MENU按钮,它将让我们退出WHILL并发送回主屏幕。
为了激活警报,我们检查警报是否已设置,如果报警与时钟匹配,MicroSD卡上的第一首歌曲将开始播放更高的卷。此外,我们也将与“解雇”按钮一起绘制所有图形,并将AlarmOn变量设置为True。这将使我们进入下一个循环,这将使歌曲能够继续播放,直到我们按下“解雇”按钮。
//报警激活(Alarmnotset == false){if(anallstring == rtc.gettimestr()){myglcd.clrscr();mp3.setvolume(25);mp3.playtrackbyIndexNumber(1);延迟(100);myglcd.setfont(Bigfont);myglcd.setcolor(255,255,255);myglcd.print(“闹钟”,中心,90);myglcd.drawbitmap(127,10,65,64,anallbutton);myglcd.print(anallstring,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(); // X coordinate where the screen has been pressed y = myTouch.getY(); // Y coordinates where the screen has been pressed // Stop alarm button 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(); } } } } }
这就是代码的工作原理,您可以在本文的底部找到完整的源代码。
建筑设备
我使用Solidworks制作了这个设计,下面是它的外观。
你可以下载这个模型,在这里进行测量:
对于这个项目,我选择使用铝板金属,我用一个多的工具。然后在桌子的边缘,借助一些夹子和板条,我弯曲了金属板。
至于扬声器,我印了一个圆形图案,把它固定在地方,然后用钻头钻出所有的洞。
在那之后,我切边到适当的形式和固定他们之前弯曲的金属板使用胶枪。
最后,我涂了金属片盒,它已经准备好电子元件被附加。yabo7. com再次,我使用胶枪固定了所有的组件,连接在一起,并使用两个螺栓固定了设备的后盖。
这就是,随意询问以下意见部分中的任何疑问。
这是设备的完整源代码:
/ * * arduino触摸屏MP3音乐播放器和闹钟* *由Dejan Nedelkovski叮叮当如Crated,L * www.www.kuaixg.com * * uftf,亚搏手机版官方下载urtouch和ds3231由Henning Karsen制作的库,可以从他的网站www.rinkydinkelectronics找到和下载yabo7. com.com。* BY8001 MP3播放器库由Borland of Arduino论坛制造,在公共领域发布。dowload链接:https://github.com/r0ndl/by8001 * / #include#include #include #include #include // ====创建对象UTFT MyGLCD(SSD1289,38,39,40,41);//参数应该调整到您的Display/Schield模型URTouch myTouch(6,5,4,3,2);SoftwareSerial mp3Serial(11、10);// RX, TX BY8001 mp3;//创建一个类BY8001的实例并调用它'mp3' DS3231 rtc(SDA, SCL);//==== Defining Fonts extern uint8_t SmallFont[];走读生uint8_t BigFont [];走读生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; // Variables for the coordinates where the display has been pressed 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() { // Initiate display myGLCD.InitLCD(); myGLCD.clrScr(); myTouch.InitTouch(); myTouch.setPrecision(PREC_MEDIUM); // Initialize the rtc object rtc.begin(); // Music Serial.begin(9600); // set serial monitor baud rate to Arduino IDE mp3Serial.begin(9600); // BY8001 set to 9600 baud (required) mp3.setup(mp3Serial); // tell BY8001 library which serial port to use. delay(800); // allow time for BY8001 cold boot; may adjust depending on flash storage size drawHomeScreen(); // Draws the Home Screen currentPage = '0'; // Indicates that we are at Home Screen 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); } void loop() { // Homes Screen if (currentPage == '0') { // Checks for change of the clock 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; } // Checks for change of the date dateS = rtc.getDateStr(); delay(10); if ( currentDate != dateS){ myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(BigFont); // Sets font to big myGLCD.print(rtc.getDateStr(), 153, 7); } // Checks for change of the temperature temperature = rtc.getTemp(); delay(10); if ( currentTemperature != temperature ){ myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(BigFont); // Sets font to big myGLCD.printNumI(temperature, 39, 7); currentTemperature = temperature; } delay(10); currentClock = rtc.getTimeStr(); } // Checks whether the screen has been touched if (myTouch.dataAvailable()) { myTouch.read(); x = myTouch.getX(); // X coordinate where the screen has been pressed y = myTouch.getY(); // Y coordinates where the screen has been pressed // If we press the 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); } // If we press the Alarm Button if ((x >= 195) && (x <= 260) && (y >= 125) && (y <= 190)) { drawFrame(227, 160, 29); currentPage = '2'; myGLCD.clrScr(); } } } // Music Player Screen if (currentPage == '1') { if (myTouch.dataAvailable()) { myTouch.read(); x = myTouch.getX(); // X coordinate where the screen has been pressed y = myTouch.getY(); // Y coordinates where the screen has been pressed // If we press the 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; } } // If we press the Previous Button if ((x >= 45) && (x <= 95) && (y >= 97) && (y <= 147)) { drawFrame(70, 121, 26); mp3.previousTrack(); delay(100); drawTrackBar(); } // If we press the Next Button if ((x >= 227) && (x <= 277) && (y >= 97) && (y <= 147)) { drawFrame(252, 122, 26); mp3.nextTrack(); delay(100); drawTrackBar(); } // If we press the VolumeDown Button 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); } // If we press the VolumeUp Button 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); } // If we press the MENU Button if ((x >= 0) && (x <= 75) && (y >= 0) && (y <= 30)) { myGLCD.clrScr(); drawHomeScreen(); // Draws the Home Screen currentPage = '0'; return; } } // Updates the track bar if (playStatus == '1' || playStatus == '2') { trackPlayTime(); } // Printing the clock in the upper right corner myGLCD.setFont(BigFont); myGLCD.setColor(255, 255, 255); printClock(187, 5); } // Alarm Clock Screen if (currentPage == '2') { myGLCD.setFont(BigFont); myGLCD.setColor(255, 255, 255); myGLCD.print("MENU", 5, 5); myGLCD.print("Set Alarm", CENTER, 20); // Draws a colon between the hours and the minutes myGLCD.setColor(0, 255, 0); myGLCD.fillCircle (112, 65, 4); myGLCD.setColor(0, 255, 0); myGLCD.fillCircle (112, 85, 4); 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(); // X coordinate where the screen has been pressed y = myTouch.getY(); // Y coordinates where the screen has been pressed //Set hours 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'); } // Set minutes buttons 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 alarm button if ((x >= 215) && (x <= 303) && (y >= 60) && (y <= 80)) { drawRectFrame(215, 60, 303, 90); 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 alarm 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); } // If we press the MENU Button if ((x >= 0) && (x <= 75) && (y >= 0) && (y <= 30)) { alarmNotSet = false; currentPage = '0'; myGLCD.clrScr(); drawHomeScreen(); // Draws the Home Screen } } } } // Alarm activation 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(); // X coordinate where the screen has been pressed y = myTouch.getY(); // Y coordinates where the screen has been pressed // Stop alarm button 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(); } } } } } } void drawHomeScreen() { myGLCD.setBackColor(0, 0, 0); // Sets the background color of the area where the text will be printed to black myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(BigFont); // Sets font to big myGLCD.print(rtc.getDateStr(), 153, 7); myGLCD.print("T:", 7, 7); myGLCD.printNumI(rtc.getTemp(), 39, 7); myGLCD.print("C", 82, 7); myGLCD.setFont(SmallFont); myGLCD.print("o", 74, 5); if (alarmString == "" ) { myGLCD.setColor(255, 255, 255); myGLCD.print("by www.HowToMechatronics.com", CENTER, 215); } else { myGLCD.setColor(255, 255, 255); myGLCD.print("Alarm set for: ", 68, 215); myGLCD.print(alarmString, 188, 215); } drawMusicPlayerButton(); drawAlarmButton(); drawHomeClock(); } void drawMusicPlayerScreen() { // Title myGLCD.setBackColor(0, 0, 0); // Sets the background color of the area where the text will be printed to black myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(BigFont); // Sets font to big myGLCD.print("MENU", 5, 5); // Prints the string on the screen myGLCD.setColor(255, 0, 0); // Sets color to red myGLCD.drawLine(0, 26, 319, 26); // Draws the red line myGLCD.setColor(255, 255, 255); // Sets color to white myGLCD.setFont(SmallFont); // Sets font to big myGLCD.print("by www.HowToMechatronics.com", CENTER, 215); // Prints the string on the screen // Volume Bar myGLCD.setColor(255, 255, 255); myGLCD.fillRect (78, 184, 78 + 150, 184 + 8); myGLCD.setColor(240, 196, 30); myGLCD.fillRect (78, 184, 78 + 75, 184 + 8); // Track Bar myGLCD.setColor(255, 255, 255); myGLCD.fillRect (48, 50, 48 + 224, 50 + 8); myGLCD.setFont(SmallFont); myGLCD.setColor(255, 255, 255); myGLCD.print("0:00", 8, 48); myGLCD.print("-0:00", 276, 48); drawPlayButton(); if (playStatus == '2') { drawPauseButton(); } drawPreviousButton(); drawNextButton(); drawVolumeDown(); drawVolumeUp(); } void drawMusicPlayerButton() { myGLCD.drawBitmap (55, 125, 65, 64, MusicPlayerButton); } void drawAlarmButton() { myGLCD.drawBitmap (195, 125, 65, 64, AlarmButton); } void drawPlayButton() { myGLCD.drawBitmap (118, 79, 83, 83, ButtonPlay); } void drawPauseButton() { myGLCD.drawBitmap (118, 79, 83, 83, ButtonPause); } void drawNextButton() { myGLCD.drawBitmap (227, 97, 50, 50, NextButton); } void drawPreviousButton() { myGLCD.drawBitmap (45, 97, 50, 50, PreviousButton); } void drawVolumeDown() { myGLCD.drawBitmap (50, 177, 16, 23, VolumeDown); } void drawVolumeUp() { myGLCD.drawBitmap (241, 175, 34, 28, VolumeUp); } // check for if Mp3 Player is stopped bool checkFor_mp3IsStopped() { if (mp3Serial.available() > 0) { if (mp3.getPlaybackStatus() == 0) { return true; } } else return false; } // Highlights the button when pressed void drawFrame(int x, int y, int r) { myGLCD.setColor(255, 0, 0); myGLCD.drawCircle (x, y, r); while (myTouch.dataAvailable()) myTouch.read(); myGLCD.setColor(0, 0, 0); myGLCD.drawCircle (x, y, r); } void drawRectFrame(int x1, int y1, int x2, int y2) { myGLCD.setColor(255, 0, 0); myGLCD.drawRoundRect (x1, y1, x2, y2); while (myTouch.dataAvailable()) myTouch.read(); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (x1, y1, x2, y2); } void drawUnderline(int x1, int y1, int x2, int y2) { myGLCD.setColor(255, 0, 0); myGLCD.drawLine (x1, y1, x2, y2); while (myTouch.dataAvailable()) myTouch.read(); myGLCD.setColor(0, 0, 0); myGLCD.drawLine (x1, y1, x2, y2); } // Sound bar void drawVolume(int x) { myGLCD.setColor(255, 255, 255); myGLCD.fillRect (78 + 5 * x, 184, 78 + 150, 184 + 8); myGLCD.setColor(240, 196, 30); myGLCD.fillRect (78, 184, 78 + 5 * x, 184 + 8); } // Clears the track bar void drawTrackBar() { myGLCD.setColor(255, 255, 255); myGLCD.fillRect (48, 50, 48 + 224, 50 + 8); } // Updates the track bar 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, 50 + 8); if (totalTime == elapsedTime) { mp3.nextTrack(); delay(30); myGLCD.setColor(255, 255, 255); myGLCD.fillRect (48, 50, 48 + 224, 50 + 8); } } void printClock(int x, int y) { if ( currentClock != rtc.getTimeStr()) { myGLCD.print(rtc.getTimeStr(), x, y); currentClock = rtc.getTimeStr(); } } void drawColon() { myGLCD.setColor(0, 255, 0); myGLCD.fillCircle (112, 65, 4); myGLCD.setColor(0, 255, 0); myGLCD.fillCircle (112, 85, 4); myGLCD.setColor(0, 255, 0); myGLCD.fillCircle (208, 65, 4); myGLCD.setColor(0, 255, 0); myGLCD.fillCircle (208, 85, 4); } void drawHomeClock() { timeString = rtc.getTimeStr(); currentHours = timeString.substring(0, 2); currentMinutes = timeString.substring(3, 5); currentSeconds = timeString.substring(6, 8); myGLCD.setFont(SevenSegNumFont); myGLCD.setColor(0, 255, 0); myGLCD.print(currentSeconds, 224, 50); myGLCD.print(currentMinutes, 128, 50); myGLCD.print(currentHours, 32, 50); drawColon(); }
随意询问下面的评论部分中的任何问题,不要忘记看看我收集的Arduino项目足彩网女欧洲杯。
嗨,我只是在思考,你使用的扬声器是什么,你使用的是mp3的链接不可用。我希望您提供一个与MP3的相同芯片,一个用于您在项目中使用的扬声器。其他好人伟大的项目。
谢谢。请重新检查一下链接,我已经更新了。
如何制作你提到的PIN标题?这是我的第一个Arduino项目,所以我不确定大多数事情。
只是看看照片。它们只有两个90度销钉焊接在一起,形成180度引脚头。您甚至不必使用,您可以使用简单的电线来实现连接。
嗨
我注意到你把扬声器连接到SPK1/SPK1和GND。
BY8001数据表报告将扬声器连接到SPK1和SPK2。
我试图在SPK1和GND之间连接扬声器。扬声器消耗300mA!
真的,300mA?好吧,我没有在案件中测试放大器消费。是的,根据数据表,扬声器连接到SPK1和SPK2。您是否尝试过此连接,它绘制的电流是多少?
而不是手动绘制分号,您可以使用相同“sevEndebygnumfont”加上A':'字符的“evEndebygnumfontplus”字体。
找到更多关于它的信息https://www.rinkydinkyabo7. comelectronics.com/r_fonts.php.
好的项目。谢谢你分享它。
我没有注意到有其他字体可以下载。那太棒了!
谢谢你的评论!
嗨。伟大的工作。
我可以使用Arduino Uno R3来构建这个项目吗?
ks
大家好,谢谢。不完全是,因为您将需要一个不同的TFT显示,以及,在代码中进行大量修改,以使它适合于一个不同的显示,该显示适用于Arduino UNO板。
伟大的项目亲爱的Nedelkovski,
我要对你的项目做一些小改动
我很感谢你的帮助
-首先我需要将“BY8001 Module”更改为一个可以与蓝牙协议通信的模块,您推荐的模块名称是什么?
-其次,我需要分析mp3的声音文件,以建立一个数字均衡器,这是可以在Arduino吗?
第三,如果我想用10瓦或15瓦的扬声器呢?我需要放大器吗?
谢谢。确保您的想法是可以使用Arduino建造的,但它与此更大的项目有完全不同。我无法建议任何具体的东西,因为我没有使用任何类似的模块。
嘿每个人
我将建立一个带有Arduino的PC扬声器,我想要的扬声器详细说明如下:
1. 3.5 mm插孔,蓝牙和USB作为输入部分。
2.我需要做一些过程输入信号(FFT和互相关)为了创建视觉EQ液晶,加强/削弱一些信号的频率在需要的情况下,通过信号抛出一个自适应噪声对消器RLS(或LMS算法在内存不足的情况下),指挥官,打开/卷,下一个/上一个和暂停/停止命令与语音命令。(这完全取决于处理速度和内存,我怀疑Arduino能处理)
3.在输出部分中,两个大约60瓦的扬声器(我不知道哪一个更准确!!!两个单声道放大器或一个立体声放大器。)
所以给你对它的观点及其优势/弱点。
我在Matlab环境中做了很多DSP,我知道了信号处理的基础,但我不知道在Arduino上运行它的可行性。
您是否会推荐您的预期模块,以便第一个和三个问题。
你的项目想法听起来不错,但我无法提出任何具体的建议,这是一个相当大的项目……
伟大的项目......工作
请我想制作时钟12小时格式的AM/PM
我能做什么…。
谢谢。我在本教程中使用的DS3231 RTC模块的特定库不支持12小时格式,但可能有一些其他库支持它。
大家好,我正在考虑为我在学校的最后一个项目制作这个播放器。我找不到你用过的电容器。我想一个是陶瓷圆盘,另一个是电解圆盘。但是没有显示值。你能帮我个忙吗?
这些价值观没有太大区别。我想我用了0.1uF和1uF。
谢谢德詹,
我正在使用您的计划作为我想做的依据。我正在融合PL-680,以添加FM收音机,也可以连接到我的无线网络并获得互联网时间(甚至可以挂钩Google日历)进行告警)。如果我完成了,我会提供和更新
听起来是个很酷的项目。祝你做得愉快!
伟大的项目......工作。但只有一个问题 - 如何设置主屏幕上的时间和数据(不是警报?)
谢谢!首先,您需要将实时时钟模块设置为正确的时间,电池将保留。检查我的特定教程。
感谢您的回复!
从mp3歌曲中读取Tag怎么样?这是可能吗?
带着敬意
你好
我来自斯洛文尼亚,Andrej是我的名字,今天我尝试使用Arduino 1.8,用TFT SSD1963 7“,编译和上传还可以,但显示是黑色的,只是Arduino已经打开了没有另一种设备(SD卡,RTC,...)
我的TFT显示屏设置7“
UTFT myGLCD(CTE70, 38, 39, 40, 41);//参数应该调整到你的Display/Schield模型
URTouch myTouch(6, 5, 4, 3, 2);
如果可能的话,请帮助我。
谢谢你!
与朋友Regaeds !
安德鲁
你好呀。我担心您的显示可能与UTFT库不兼容。检查其兼容性列表,您可以在其文档文件中找到它。
德州,
我真的很想尝试你的项目。
我有几个问题。
1)DE开关和电路原理图中的MP3模块之间的2个组件是什么?
2)我认为您正在使用非充电电池,这可能是因为RTC的充电功能吗?
3)当我使用可充电电池时,它是一个超载电池的机会,因为它是3V,主电源为5V?
1)这两个组件是两个去耦电容器。
确实,电池是不充电的。
3)我不确定这一点,我想这取决于电池的类型,但5V主电源可能会对3V设备造成伤害。
这是一个很棒的项目。感谢分享代码。我注意到您在电源输入处使用了2个电容器。为什么他们使用以及您是如何计算其价值的?
谢谢!电容器用作去耦电容器,用于稳定功率。这些值对于解耦电容器很常见。
嗨似乎是一个很酷的项目,我正在尝试它。然而,我的编译器在寻找URtouch库时遇到了麻烦,有什么想法吗?
使用您已安装正确的触摸屏库。
伟大的建设!我已经购买了一切,并组装了它所有的,然而,当我得到没有错误的编译器,当上传时,没有迹象表明代码已经做了任何事情,屏幕坐在那里照明,并没有做更多。我在硬件方面寻找了一些可能的解决方案,但除了URTouch库的一个名为“URTouch_ButtonTest”的演示之外,没有任何运气。即使在那里,触摸方面没有影响,而只是一个图像。我找不到解决办法。你有什么主意吗?