在这个项目中,我将向您展示如何制作Arduino触摸屏MP3音乐播放器和闹钟。您可以观看以下视频或阅读下面的书面教程。
主屏幕具有大时钟,日期和温度信息,以及音乐播放器和闹钟的两个按钮。
如果我们进入音乐播放器,我们可以通过按屏幕中间的大“播放”按钮开始播放音乐。在它旁边,还有两个按钮,用来播放前一首歌或下一首歌。
在这些按钮上方有歌曲进度栏,并且在屏幕底部我们有一个卷栏和两个按钮,用于减小和增加卷。在右上角有一个时钟,左侧是“菜单”按钮,使我们返回主屏幕。
另一方面,如果我们输入闹钟,我们可以使用两个按钮设置警报来设置小时和分钟。
当警报被激活时,一首歌会以更高的音量开始播放,并一直播放,直到我们按下“解散”键。
亚博88下载
现在让我们来看看这个设备是如何工作的。它使用Arduino Mega板和一个3.2“TFT触摸屏,一个适当的屏蔽连接屏幕与Arduino板。播放音乐使用BY8001 MP3播放器模块,闹钟使用DS3231实时时钟模块。
您可以从下面的链接获取此Arduino项目所需的组件:
- BY8001-16P MP3模块.........亚马逊/aliexpress.
- 3.2“TFT触摸显示器......... ...... ......亚马逊/伯格多德/aliexpress.
- TFT显示巨型盾......... ..亚马逊/伯格多德/aliexpress.
- 0.5 w的演讲者 ............................亚马逊/伯格多德/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 //==== Creating Objects 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);//==== define 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语句为真,因为我们已经将currentPage变量设置为0,这表示我们在主屏幕上。在下面的if语句中,我们检查时钟是否有变化,并且每秒钟都会发生变化。现在我们使用TFT库的7段字体,它除了数字外不支持任何字符,我们必须从getTimeStr()函数提供的字符串中提取数字,该字符串用于从DS3231 RTC模块读取时钟。
因此,使用substring()函数,我们将小时、分钟和秒作为单独的变量,并在秒、分钟或小时发生变化时将它们打印出来。
至于日期和温度,类似,我们检查与以前的状态相比是否存在变化。
void loop() {// Homes Screen if (currentPage == '0'){//检查时钟的变化if (currentClock != rtt . gettimestr ()) {timeString = rtt . gettimestr ();小时=时间戳。(0,2);minutess =时间戳。(3,5);秒=时间=时间戳。(6,8);myGLCD.setFont (SevenSegNumFont);myglcd.setcolor(0,255,0);myglcd.print(秒,224,50);if(prossminutes!= minutess){myglcd.print(Minutess,128,50);currentMinutes =分钟;}如果(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();//如果我们按下音乐播放器按钮,如果(x >= 55) && (x <= 120) && (Y >= 125) && (Y <= 190)) {drawFrame(87, 157, 33);当前页= ' 1 ';myGLCD.clrScr ();延迟(100);drawMusicPlayerScreen ();延迟(100);} //如果按下报警按钮,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语句用于更新轨道进度条。
//更新轨道栏如果(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 (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 } } } }
注意,我们需要调整这个字符串,使其具有与从getTimeString()函数中获得的字符串相同的形式。通过这种方式,我们将能够比较它们,并激活闹钟时,时钟将达到相同的值或时间。
如果我们按清除按钮,我们将清除alarmString,如果我们按菜单按钮,它将使我们退出while循环并返回到主屏幕。
为了激活警报,我们检查警报是否已设置,如果报警与时钟匹配,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我做了这个设计,这是它的外观。
您可以下载此型号,以便您可以在此处进行测量:
对于这个项目,我选择使用铝板金属,我使用a将其切割为尺寸多功能工具。然后在桌子的边缘,借助一些夹子和板条,我弯曲了金属板。
至于音箱,我打印了一个圆形的图案,把它固定在一个地方,用一个钻我做了所有的孔。
之后,我将侧面切割成适当的形式并使用胶枪将它们固定到先前弯曲的钣金中。
最后,我涂上了金属板盒,它已准备好附着电子元件。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);// URTouch myTouch(6, 5, 4, 3, 2);SoftwareSerial mp3Serial(11、10);// RX, TX BY8001 mp3;DS3231 rtc(SDA, SCL);//==== define 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来构建这个项目吗?
谢谢大家
嗨,谢谢。不是真的,因为你需要不同的TFT显示器,以及代码中的大量修改,使其适用于不同的显示器,该显示器适合于Arduino Uno板。
伟大的项目亲爱的Nedelkovski,
我将通过一些小变化来建立你的项目
我很感激你的帮助来制作它。
- 首先,我需要将“by8001模块”更改为可以与蓝牙协议通信的模块,因此您的推荐模块名称是什么?
- 第二个我需要分析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歌曲的阅读标记怎么样?这是本地的吗?
关于
你好
我来自斯洛文尼亚,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);
如果可以,请帮助我。
谢谢你 !
与朋友注册!
安德鲁
嗨。我担心您的显示可能与UTFT库不兼容。检查它们的兼容性列表,你可以在其文档文件中找到它。
德扬,
我真的很想尝试你的项目。
我有几个问题。
1)在你的电路图中开关和mp3模块之间的两个组件是什么?
2)我认为您正在使用非充电电池,这可能是因为RTC的充电功能吗?
3)当我使用可充电电池时,它是一个超载电池的机会,因为它是3V,主电源为5V?
1)这两个组件是两个去耦电容。
2)真实,电池在不可取的。
3)我不确定这一点,我想这取决于电池的类型,但5V主电源可能会对3V设备造成伤害。
这是一个很棒的项目。感谢分享代码。我注意到您在电源输入处使用了2个电容器。为什么他们使用以及您是如何计算其价值的?
谢谢!电容器用作去耦电容器,用于稳定功率。这些值对于解耦电容器很常见。
嗨似乎是一个很酷的项目,我试图尝试出来。但是我的编译器无法找到Urtouch库,任何想法为什么?
请使用您已经为触摸屏安装了正确的库。
伟大的建设!我已经购买了所有内容并组装了这一切,而我在编译器上没有错误,并且在上传时,没有迹象表明代码已经完成了任何东西,屏幕坐在那里亮起,没有任何东西。除了从名为“URTOUCH_BUTTESTEST”的URTOUCH库中的单个演示外,我已经看到了有关硬件的可能解决方案。即使有触摸方面也没有效果,而是它只是一个图像。我对解决方案的损失。你有什么想法?