├── Circuit diagram ├── Schematic_SoundPod.png └── SoundPod.png ├── DFPlayer_Helper ├── DFplayer Helper.png └── DFplayer_helper.py ├── LICENSE ├── README.md └── soundpod ├── DFplayer └── DFplayer.ino ├── Input.ino ├── audio.ino ├── dispaly.ino └── soundpod.ino /Circuit diagram/Schematic_SoundPod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neutrino-1/Arduino-Soundpod/e1b15e6f7a20580bcd749186fd1a4fceeb835d00/Circuit diagram/Schematic_SoundPod.png -------------------------------------------------------------------------------- /Circuit diagram/SoundPod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neutrino-1/Arduino-Soundpod/e1b15e6f7a20580bcd749186fd1a4fceeb835d00/Circuit diagram/SoundPod.png -------------------------------------------------------------------------------- /DFPlayer_Helper/DFplayer Helper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neutrino-1/Arduino-Soundpod/e1b15e6f7a20580bcd749186fd1a4fceeb835d00/DFPlayer_Helper/DFplayer Helper.png -------------------------------------------------------------------------------- /DFPlayer_Helper/DFplayer_helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tkinter as tk 3 | from tkinter import * 4 | from tkinter.ttk import * 5 | from tkinter import filedialog 6 | from shutil import copyfile 7 | 8 | impo_path = [] 9 | expo_path = str 10 | folder_number = 1 11 | selected_folder = 0 12 | folders = [] 13 | 14 | def impo(): 15 | global impo_path 16 | global import_destination_count 17 | global folders 18 | global selected_folder 19 | folder_selection() 20 | progress['text'] = "Waiting to transfer the files" 21 | impo_path.append(list(filedialog.askopenfilenames(title="Select file", filetypes=( 22 | ("mp3 files", "*.mp3"), ("wav files", "*.wav"))))) 23 | 24 | #number_of_selected_files = 0 25 | # for each_import in impo_path: 26 | # number_of_selected_files += len(each_import) 27 | # number_of_songs['text'] = f"{number_of_selected_files} songs selected" 28 | final_path_list = [] 29 | 30 | for each_import in impo_path: 31 | if type(each_import)!= str: 32 | for each_each_import in each_import: 33 | final_path_list.append(each_each_import) 34 | else: 35 | final_path_list.append(each_import) 36 | 37 | impo_path = [] 38 | if len(folders) > (selected_folder+1): 39 | folders[selected_folder] += final_path_list 40 | else: 41 | list_filler() 42 | folders[selected_folder] = final_path_list 43 | 44 | show_folder_content() 45 | calculate_total_songs() 46 | 47 | 48 | def calculate_total_songs(): 49 | global folders 50 | total_song_count = 0 51 | for files in folders: 52 | total_song_count += len(files) 53 | number_of_songs['text'] = f'Number of Files : {total_song_count}' 54 | 55 | def expo(): 56 | global expo_path 57 | expo_path = filedialog.askdirectory() 58 | destination_path['text'] = expo_path 59 | 60 | def list_filler(): 61 | global folders 62 | global selected_folder 63 | while len(folders) < (selected_folder+1): 64 | folders.append([]) 65 | 66 | def remove_file(): 67 | selected_file = import_list.curselection()[0] 68 | del folders[selected_folder][selected_file] 69 | calculate_total_songs() 70 | show_folder() 71 | 72 | def folder_selection(): 73 | global selected_folder 74 | selected_folder = folder_list.curselection()[0]; 75 | selection_folder_lable['text'] = f'Selected Folder : {str(selected_folder+1).zfill(2)}'; 76 | 77 | def move(): 78 | global impo_path 79 | global expo_path 80 | song_names = "" 81 | for j,files in enumerate(folders): 82 | print(j/len(folders)*250) 83 | directory = str(j+1).zfill(2) 84 | parent_dir = expo_path 85 | path = os.path.join(parent_dir, directory) 86 | os.mkdir(path) 87 | song_names += "\n"+str(directory)+"\n\n" 88 | for i,file in enumerate(files): 89 | song_names += file.split("/")[-1]+"\n" 90 | copyfile(file, f'{path}/{str(i+1).zfill(3)}.{file.split(".")[-1]}') 91 | # insert code to execute main.py in Audio-FSK-Modulation- directory 92 | # with the arguments as content in song_names variable 93 | f = open(expo_path+"/000.txt", "w+") 94 | f.write(song_names) 95 | f.close() 96 | expo_path = "" 97 | progress['text'] = "Transfered successfully" 98 | 99 | def add_folder(): 100 | global folder_number 101 | folder_number += 1 102 | folder_list.insert(folder_number, str(folder_number).zfill(2)) 103 | number_of_folders['text'] = f'Number of Folders : {folder_number}' 104 | 105 | def remove_folder(): 106 | global folder_number 107 | folder_list.delete(folder_number-1, last=None) 108 | folder_number -= 1 109 | number_of_folders['text'] = f'Number of Folders : {folder_number}' 110 | 111 | def show_folder_content(): 112 | folder_selection() 113 | show_folder() 114 | 115 | def show_folder(): 116 | global selected_folder 117 | global folders 118 | 119 | import_list.delete(0,import_list.size()) 120 | 121 | if len(folders) < (selected_folder+1): 122 | list_filler() 123 | 124 | if folders[selected_folder] == []: 125 | import_list.insert(0,"No Files") 126 | else: 127 | n = 0 128 | for files in folders[selected_folder]: 129 | import_list.insert(n,files.split("/")[-1]) 130 | n += 1 131 | 132 | 133 | 134 | root = tk.Tk() 135 | root.geometry("370x355") 136 | root.title('DFPlayer Helper') 137 | root.resizable(height = False, width = False) 138 | 139 | tk.Label(root, text="Folders", width=20).grid(pady=5,row=0, column=1,columnspan=2) 140 | selection_folder_lable = tk.Label(root, text="Selected Folder : None", width=20) 141 | selection_folder_lable.grid(pady=5,row=0, column=5,columnspan=2) 142 | 143 | folder_list = tk.Listbox(root) 144 | folder_list.insert(folder_number,str(folder_number).zfill(2)) 145 | folder_list.grid(row=1, column=1,padx=0, columnspan=2) 146 | 147 | tk.Button(root, text="Add folder", width=10, command=add_folder).grid(padx = 5,pady=5,row=2, column=1) 148 | tk.Button(root, text="remove", width=10, command=remove_folder).grid(row=2, column=2) 149 | 150 | tk.Button(root, text=">>", width=2, command=show_folder_content).grid(row=1, column=3, columnspan=1) 151 | 152 | import_list = tk.Listbox(root) 153 | import_list.grid(row=1, column=5,padx=10,columnspan=2) 154 | tk.Button(root, text="Import", width=10, command=impo).grid(padx = 5,pady=5,row=2, column=5) 155 | tk.Button(root, text="remove", width=10, command=remove_file).grid(row=2, column=6) 156 | 157 | number_of_songs = tk.Label(root, text=f'Number of Files : 0', width=40) 158 | number_of_songs.grid(pady=5,row=3, column=1, columnspan=6) 159 | 160 | number_of_folders = tk.Label(root, text=f'Number of Folders : {folder_number}', width=40) 161 | number_of_folders.grid(pady=5,row=4, column=1, columnspan=6) 162 | 163 | tk.Button(root, text="Destination", width=10,command=expo).grid(row=5, column=0,columnspan=2) 164 | destination_path = tk.Label(root, text="destination", width=10) 165 | destination_path.grid(row=5, column=2) 166 | 167 | tk.Button(root, text="Move", width=10, command=move).grid(row=6, column=0, columnspan=2,pady = 5) 168 | 169 | # Progress bar widget 170 | progress = tk.Label(root, text='Waiting to transfer the files', width=40) 171 | progress.grid(row=6, column=2,columnspan=5) 172 | root.mainloop() 173 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Neutrino 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino-Soundpod 2 | An Arduino based MP3 player which uses a 1.3" OLED display along with DFPlayer. 3 | 4 | ![Soundpod final build](https://github.com/Neutrino-1/Arduino-Soundpod/blob/master/Circuit%20diagram/SoundPod.png) 5 | 6 | ### Getting Started 7 | 8 | Open **soundpod.ino** with arduino IDE [Tested on Arudino IDE 1.8.10 above] 9 | all the other files will open along with it. 10 | 11 | ### Prerequisites 12 | 13 | Arduino Libraries for DFplayer and 1.3inch oled display 14 | 15 | * [DFRobotDFplayerMini](https://github.com/DFRobot/DFRobotDFPlayerMini) - by DFRobot 16 | * [U8g2lib](https://github.com/olikraus/u8g2) - by olikraus 17 | 18 | ### Installing 19 | 20 | Open the Arduino IDE and follow the below steps: 21 | ``` 22 | Sketch -> include library -> ManageLibrary -> *Search for the above library* 23 | ``` 24 | Or 25 | follow the instructions on respective library repository. 26 | 27 | ### Python Script 28 | 29 | To ransfer files to DFPlayer, the folders needs to be named 01,02.. and files needs to be named 001,002,.. 30 | This python script should help you in transfering the files and folders without manually renaming the files. 31 | It also output's a 000.txt file, where all the original file names under each folder is stored. 32 | 33 | ![Soundpod final build](https://github.com/Neutrino-1/Arduino-Soundpod/blob/master/DFPlayer_Helper/DFplayer%20Helper.png) 34 | 35 | ## License 36 | 37 | This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/Neutrino-1/Arduino-Soundpod/blob/master/LICENSE) file for details 38 | 39 | ## Acknowledgments 40 | 41 | * [Stefan Wagner](https://easyeda.com/wagiminator/attiny85-tinydfplayer-smd) Refered his code for file and folder queries. 42 | * [kaushikrao77](https://github.com/kaushikrao77) helped in the python script 43 | -------------------------------------------------------------------------------- /soundpod/DFplayer/DFplayer.ino: -------------------------------------------------------------------------------- 1 | #include "SoftwareSerial.h" 2 | SoftwareSerial DFplayer(9,10); 3 | # define Start_Byte 0x7E 4 | # define Version_Byte 0xFF 5 | # define Command_Length 0x06 6 | # define End_Byte 0xEF 7 | # define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info] 8 | # define ACTIVATED LOW 9 | 10 | int buttonNext = 2; 11 | int buttonPause = 3; 12 | int buttonPrevious = 4; 13 | int buttomnVolume = 5; 14 | 15 | boolean isPlaying = false; 16 | 17 | void setup () { 18 | pinMode(buttonPause, INPUT); 19 | digitalWrite(buttonPause,HIGH); 20 | pinMode(buttonNext, INPUT); 21 | digitalWrite(buttonNext,HIGH); 22 | playFirst(); 23 | isPlaying = true; 24 | pinMode(buttonPrevious, INPUT); 25 | digitalWrite(buttonPrevious,HIGH); 26 | DFplayer.begin (9600); 27 | delay(1000); 28 | } 29 | 30 | 31 | 32 | void loop () { 33 | if (digitalRead(buttonPause) == ACTIVATED) 34 | { 35 | if(isPlaying) 36 | { 37 | pause(); 38 | isPlaying = false; 39 | }else 40 | { 41 | isPlaying = true; 42 | play(); 43 | } 44 | } 45 | if (digitalRead(buttonNext) == ACTIVATED) 46 | { 47 | if(isPlaying) 48 | { 49 | playNext(); 50 | } 51 | } 52 | if (digitalRead(buttonPrevious) == ACTIVATED) 53 | { 54 | if(isPlaying) 55 | { 56 | playPrevious(); 57 | } 58 | } 59 | 60 | 61 | if (digitalRead(buttonVolume) == ACTIVATED) 62 | { 63 | if(isPlaying) 64 | { 65 | currentVolume -= 5; 66 | if(currentVolume <= 0) 67 | { 68 | currentVolume = 30; 69 | } 70 | setVolume(currentVolume); 71 | } 72 | } 73 | 74 | } 75 | 76 | void playFirst() 77 | { 78 | df_CMD(0x3F, 0, 0); 79 | delay(500); 80 | setVolume(30); 81 | delay(500); 82 | df_CMD(0x11,0,1); 83 | delay(500); 84 | } 85 | 86 | void pause() 87 | { 88 | df_CMD(0x0E,0,0); 89 | delay(500); 90 | } 91 | 92 | void play() 93 | { 94 | df_CMD(0x0D,0,1); 95 | delay(500); 96 | } 97 | 98 | void playNext() 99 | { 100 | df_CMD(0x01,0,1); 101 | delay(500); 102 | } 103 | 104 | void playPrevious() 105 | { 106 | df_CMD(0x02,0,1); 107 | delay(500); 108 | } 109 | 110 | void setVolume(int volume) 111 | { 112 | df_CMD(0x06, 0, volume); // Set the volume (0x00~0x30) 113 | delay(2000); 114 | } 115 | 116 | void df_CMD(byte CMD, byte Par1, byte Par2) 117 | { 118 | // Calculate the checksum (2 bytes) 119 | word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2); 120 | // Build the command line 121 | byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge, 122 | Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte}; 123 | //Send the cmd to the module one byte at a time 124 | for (byte k=0; k<10; k++) 125 | { 126 | DFplayer.write( Command_line[k]); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /soundpod/Input.ino: -------------------------------------------------------------------------------- 1 | void preivousButtonClicked() 2 | { 3 | 4 | updateScreen = true; 5 | if(inSideMenuSelection && sMenuSelection < 2) 6 | { 7 | sMenuSelection++; 8 | } 9 | else if(selection < 4 && sMenuSelection == 1) 10 | { 11 | selection++; 12 | } 13 | else if(selection == 1 && volume < 30 &&sMenuSelection == 2 && !inSideMenuSelection) 14 | { 15 | volume++; 16 | } 17 | else if(selection == 2 && eq < 5 && sMenuSelection == 2 && !inSideMenuSelection) 18 | { 19 | eq++; 20 | } 21 | 22 | } 23 | 24 | void nextButtonClicked() 25 | { 26 | updateScreen = true; 27 | if(inSideMenuSelection && sMenuSelection > 1) 28 | { 29 | sMenuSelection--; 30 | } 31 | else if(selection > 1 && sMenuSelection == 1) 32 | { 33 | selection--; 34 | } 35 | else if(selection == 1 && volume > 0 &&sMenuSelection == 2) 36 | { 37 | volume--; 38 | } 39 | else if(selection == 2 && eq > 0 && sMenuSelection == 2) 40 | { 41 | eq--; 42 | } 43 | } 44 | 45 | void playButtonClicked() 46 | { 47 | //Selection button 48 | if(inSideMenuSelection) 49 | { 50 | inSideMenuSelection = false; 51 | updateScreen = true; 52 | delay(100); 53 | } 54 | else if(!inSideMenuSelection && sMenuSelection == 1) 55 | { 56 | if(selection == 1) 57 | { 58 | if(file > 1) 59 | { 60 | //previous audio 61 | myDFPlayer.previous(); 62 | file--; 63 | if(!playing) 64 | playing = true; 65 | EEPROM.write(2, file); 66 | } 67 | } 68 | else if(selection == 2) 69 | { 70 | //pause / play 71 | if(playing) 72 | { 73 | myDFPlayer.pause(); 74 | } 75 | else 76 | { 77 | myDFPlayer.start(); 78 | } 79 | playing = !playing; 80 | } 81 | else if(selection == 3) 82 | { 83 | //next audio 84 | file++; 85 | myDFPlayer.next(); 86 | if(!playing) 87 | playing = true; 88 | EEPROM.write(2, file); 89 | } 90 | else if(selection == 4) 91 | { 92 | //back to side menu 93 | selection = 1; 94 | inSideMenuSelection = true; 95 | } 96 | updateScreen = true; 97 | delay(200); 98 | }else if(!inSideMenuSelection && sMenuSelection == 2) 99 | { 100 | if(selection == 1) 101 | { 102 | selection = 2; 103 | myDFPlayer.volume(volume); 104 | EEPROM.write(0, volume); 105 | } 106 | else if(selection == 2) 107 | { 108 | selection = 4; 109 | myDFPlayer.EQ(eq); 110 | EEPROM.write(1, eq); 111 | } 112 | else if(selection == 4) 113 | { 114 | //back to side menu 115 | selection = 1; 116 | inSideMenuSelection = true; 117 | } 118 | updateScreen = true; 119 | delay(200); 120 | } 121 | 122 | } -------------------------------------------------------------------------------- /soundpod/audio.ino: -------------------------------------------------------------------------------- 1 | // starts to play the actual file in the actual folder 2 | void startFolderPlay() { 3 | filecounts = myDFPlayer.readFileCountsInFolder(folder); 4 | myDFPlayer.playFolder(folder, file); 5 | playing = false; 6 | } 7 | 8 | void updateDFplayer() 9 | { 10 | // check player status 11 | if (myDFPlayer.available()) { 12 | uint8_t type = myDFPlayer.readType(); 13 | int value = myDFPlayer.read(); 14 | 15 | switch (type) { 16 | case DFPlayerPlayFinished: 17 | if (file < filecounts) { 18 | file++; 19 | myDFPlayer.playFolder(folder, file); 20 | EEPROM.write(2, file); 21 | updateScreen = true; 22 | } 23 | break; 24 | default: 25 | break; 26 | } 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /soundpod/dispaly.ino: -------------------------------------------------------------------------------- 1 | void updateDisplay() { 2 | //Updating the dispaly 3 | if (updateScreen) { 4 | u8g2.firstPage(); 5 | do { 6 | int ch = (sMenuSelection); 7 | switch (ch) { 8 | case 1: 9 | player(); 10 | break; 11 | case 2: 12 | settings(); 13 | break; 14 | default: 15 | Serial.println(F("Default Screen")); 16 | } 17 | updateScreen = false; 18 | } while (u8g2.nextPage()); 19 | } 20 | } 21 | 22 | void settings() { 23 | sideMenu(); 24 | topMenu(); 25 | u8g2.setFont(u8g2_font_glasstown_nbp_tf); 26 | 27 | u8g2.setCursor(65, 17); 28 | u8g2.print(F("Setting")); 29 | 30 | u8g2.setFontMode(0); 31 | 32 | u8g2.setCursor(47, 40); 33 | u8g2.print(F("Volume")); 34 | if (selection == 1 && !inSideMenuSelection) { 35 | u8g2.setFont(soundpod_icon_pack_font); 36 | if (volume > 0) 37 | u8g2.drawGlyph(85, 40, 69); // drawing left ajustment button next to the volume 38 | if (volume < 30) { 39 | if (volume < 10) 40 | u8g2.drawGlyph(100, 40, 70); // drawing right ajustment button next to the volume for single digit volume 41 | else 42 | u8g2.drawGlyph(105, 40, 70); // drawing right ajustment button next to the volume for double digit volume 43 | } 44 | } 45 | u8g2.setFont(u8g2_font_glasstown_nbp_tf); 46 | u8g2.setCursor(95, 40); 47 | u8g2.print(volume); 48 | u8g2.setDrawColor(1); 49 | 50 | u8g2.setCursor(67, 60); 51 | u8g2.print(F("EQ")); 52 | if (selection == 2 && !inSideMenuSelection) { 53 | u8g2.setFont(soundpod_icon_pack_font); 54 | if (eq > 0) 55 | u8g2.drawGlyph(85, 60, 69); // drawing left ajustment button next to the volume 56 | if (eq < 5) 57 | u8g2.drawGlyph(100, 60, 70); // drawing right ajustment button next to the volume 58 | } 59 | u8g2.setFont(u8g2_font_glasstown_nbp_tf); 60 | u8g2.setCursor(95, 60); 61 | u8g2.print(eq); 62 | u8g2.setDrawColor(1); 63 | 64 | if (selection == 4 && !inSideMenuSelection) { 65 | u8g2.setDrawColor(0); 66 | } 67 | u8g2.setFont(soundpod_icon_pack_font); 68 | u8g2.drawGlyph(120, 60, 71); // drawing back button to the bottom off the screen 69 | u8g2.setDrawColor(1); 70 | } 71 | 72 | void flashPage() { 73 | drawIcon(soundpod_icon_pack_font, u8g2.getDisplayWidth() / 2 - 12, u8g2.getDisplayHeight() - 22, 66); //drawing spectrum for splash screen 74 | u8g2.setFont(u8g2_font_glasstown_nbp_tf); 75 | u8g2.setCursor(50, 63); 76 | u8g2.print(F("Soundpod")); 77 | } 78 | 79 | void topMenu() { 80 | u8g2.setFont(soundpod_icon_pack_font); 81 | 82 | if (volume >= 25) 83 | u8g2.drawGlyph(119, 9, 77); 84 | else if (volume > 10 && volume < 25) 85 | u8g2.drawGlyph(119, 9, 78); 86 | else if (volume <= 10) 87 | u8g2.drawGlyph(119, 9, 79); 88 | // 89 | // u8g2.setFont(u8g2_font_glasstown_nbp_tf); 90 | // u8g2.setCursor(25,9); 91 | // u8g2.print(batteryLevel); 92 | // u8g2.setCursor(35,9); 93 | // u8g2.print("%"); 94 | } 95 | 96 | void sideMenu() { 97 | const uint8_t menuListGlpy[2] = { 77, 64 }; 98 | 99 | u8g2.setFontMode(0); 100 | 101 | //Audio player selection 102 | if (abs(sMenuSelection) == 1 && inSideMenuSelection) { 103 | u8g2.drawRBox(0, 12, 20, 21, 3); 104 | u8g2.setDrawColor(0); 105 | } 106 | 107 | //Audio player 108 | drawIcon(soundpod_icon_pack_font, 2, 30, 76); 109 | 110 | u8g2.setDrawColor(1); 111 | 112 | //setting Selection 113 | if (abs(sMenuSelection) == 2 && inSideMenuSelection) { 114 | u8g2.drawRBox(0, 33, 20, 19, 3); 115 | u8g2.setDrawColor(0); 116 | } 117 | //settings 118 | drawIcon(soundpod_icon_pack_font, 2, 52, 65); 119 | // u8g2.setFont(menuList[1][1]); 120 | // u8g2.drawGlyph(2,52,menuList[1][0]); 121 | 122 | u8g2.setDrawColor(1); 123 | u8g2.drawLine(22, 0, 22, 68); 124 | } 125 | 126 | void player() { 127 | sideMenu(); 128 | topMenu(); 129 | 130 | u8g2_uint_t midOriginX = 64; 131 | u8g2_uint_t midOriginY = 44; 132 | 133 | u8g2.setFontMode(0); 134 | u8g2.setCursor(45, 25); 135 | u8g2.setFont(u8g2_font_glasstown_nbp_tf); 136 | u8g2.print("Track : "); 137 | u8g2.setCursor(78, 25); 138 | u8g2.print(file); 139 | u8g2.setCursor(88, 25); 140 | u8g2.print('/'); 141 | u8g2.setCursor(95, 25); 142 | u8g2.print(filecounts); 143 | 144 | if (selection == 1 && !inSideMenuSelection) { 145 | u8g2.drawRBox(midOriginX - 7, midOriginY - 5, 11, 9, 2); 146 | u8g2.setDrawColor(0); 147 | } 148 | u8g2.setFont(soundpod_icon_pack_font); 149 | u8g2.drawGlyph(midOriginX - 5, midOriginY + 4, 74); 150 | u8g2.setDrawColor(1); 151 | 152 | if (selection == 2 && !inSideMenuSelection) { 153 | u8g2.drawRBox(midOriginX + 7.5, midOriginY - 8.5, 16.5, 15, 3); 154 | u8g2.setDrawColor(0); 155 | } 156 | u8g2.setFont(soundpod_icon_pack_font); 157 | if (playing) { 158 | u8g2.drawGlyph(midOriginX + 7.5, midOriginY + 7.5, 72); 159 | } else { 160 | u8g2.drawGlyph(midOriginX + 7.5, midOriginY + 7.5, 73); 161 | } 162 | u8g2.setDrawColor(1); 163 | 164 | if (selection == 3 && !inSideMenuSelection) { 165 | u8g2.drawRBox(midOriginX + 25, midOriginY - 5, 12, 9, 2); 166 | u8g2.setDrawColor(0); 167 | } 168 | u8g2.setFont(soundpod_icon_pack_font); 169 | u8g2.drawGlyph(midOriginX + 27, midOriginY + 4, 75); 170 | u8g2.setDrawColor(1); 171 | 172 | if (selection == 4 && !inSideMenuSelection) { 173 | u8g2.setDrawColor(0); 174 | } 175 | u8g2.setFont(soundpod_icon_pack_font); 176 | u8g2.drawGlyph(120, 60, 71); 177 | u8g2.setDrawColor(1); 178 | } 179 | 180 | void drawIcon(const uint8_t* iconName, u8g2_uint_t x, u8g2_uint_t y, uint16_t glyph) { 181 | u8g2.setFont(iconName); 182 | u8g2.drawGlyph(x, y, glyph); 183 | } 184 | -------------------------------------------------------------------------------- /soundpod/soundpod.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "OneButton.h" 8 | 9 | // 65 - Audio Settings Icon 10 | // 66 - Flash screen Spectrum 11 | // 67 - Battery empty 12 | // 68 - Battery full 13 | // 69 - left adjustment button 14 | // 70 - right adjustment button 15 | // 71 - back button 16 | // 72 - pause button 17 | // 73 - play button 18 | // 74 - previous button 19 | // 75 - Next button 20 | // 76 - Music Icon 21 | // 77 - volume full 22 | // 78 - volume half 23 | // 79 - volume low 24 | 25 | extern const uint8_t soundpod_icon_pack_font[350] U8G2_FONT_SECTION("soundpod_icon_pack_font") = 26 | "\17\0\4\4\5\6\3\3\7\34 \0\0\16\0\16\0\0\0\0\0\1AA&p\341\241\22\64\214\310" 27 | "!BE\210\11\24\206\210 !D\4\11!\42H\10\21ABD\10\25\42TL\320 \0BZ\34" 28 | "$\301\17\202 30) 101 | volume = 30; 102 | 103 | eq = EEPROM.read(1); 104 | if(eq > 5) 105 | eq = 5; 106 | 107 | file = EEPROM.read(2); 108 | if(file >= 255) 109 | file = 1; 110 | 111 | delay(1000); 112 | myDFPlayer.volume(volume); //Set volume value. From 0 to 30 113 | delay(500); 114 | foldercounts = myDFPlayer.readFolderCounts(); 115 | startFolderPlay(); 116 | // 117 | } 118 | 119 | void loop() { 120 | 121 | //Check constantly for button inputs 122 | PreviousBTN.tick(); 123 | PlayBTN.tick(); 124 | NextBTN.tick(); 125 | //Update the display as required 126 | updateDisplay(); 127 | updateDFplayer(); 128 | 129 | } 130 | --------------------------------------------------------------------------------