聚豐項目 > 基于手勢識別控制的音樂播放器
中科藍訊公司推出的 AB32VG1 開發(fā)板,這個開發(fā)板自帶 按鍵模塊、audio 模塊和 TF card 模塊,基于該開發(fā)板結合 OLED12864 模塊作為顯示屏幕,加上 PAJ7620U2 手勢識別模塊,制作了一款基于手勢識別的音樂播放器,這樣就可以實現(xiàn)非接觸式控制音樂播放,這個模塊作為一個基礎,之后也能構造出更炫酷的作品 該音樂播放器目前實現(xiàn)了如下功能: 1、可以通過 OLED12864 模塊顯示播放器信息。 2、可以通過按鍵控制音樂播放和設置一些信息。 3、讀取 SD 卡的音樂文件并播放。 4、通過手勢識別模塊控制播放器
Eureka1024
Eureka1024
團隊成員
Eureka1024 軟件開發(fā)
按鍵模塊使用如下 GPIO 引腳:
S2 -- PF1 (單擊為向下選擇)
S3 -- PF0(單擊為確定,雙擊為返回)
S4 -- PA2(單擊為向上選擇)
使用按鍵軟件包:multibutton
使用的引腳如下:
SDA -- PA6
SCL -- PA0
沒有使用 u8g2 的驅動軟件包,因為內(nèi)存不夠。使用了網(wǎng)上的軟件 IIC 實現(xiàn),做了一些修改。
使用的 SDIO 協(xié)議對應的引腳如下:
SD_CMD -- PB0
SD_CLK -- PB1
SD_DAT -- PB2
SD_DET -- PE5
使用到 RT-Thread 提供的 SDIO 驅動,使用到的組件和服務層有 DFS、Fatfs 和 POSIX。
VOUTRP -- DACR
VOUTLP -- DACL
FMANT -- FM_ANT
MICIN -- MICL/PF2
使用到的驅動 audio device, 軟件包為 wavplayer(需要optparse軟件包),可以用來播放 wav 格式的音樂文件。
SDA -- PE2
SCL -- PE3
INT -- PA5
使用了軟件 IIC 驅動、PAJ7620軟件包。
開發(fā)環(huán)境:
- RT-Thread 版本 latest(2021-10-20)
- RT-Thread Studio版本 V2.12
- AB32VG1 開發(fā)板 BSP 版本 V1.08
音樂播放器雖說功能不多,但是不同的狀態(tài)切換還是蠻多的,所以理所當然會想到使用狀態(tài)機的方式實現(xiàn)。
目前實現(xiàn)的狀態(tài)主要包括如下幾個,同時,該樹狀圖也表明了狀態(tài)間的轉移關系。
網(wǎng)上關于狀態(tài)機的實現(xiàn)有很多方法,我看了好多文章都是直接一個狀態(tài)對應一個動作函數(shù),但是應用在音樂播放器上會有點問題,因為如果你一個狀態(tài)對應一個函數(shù)的話,如果你的音樂歌曲有幾百首,那豈不是有幾百個函數(shù),所以我對一般的狀態(tài)機做了點改進。
如下代碼所示,主要是狀態(tài)轉移表的實現(xiàn),該表給出了所有狀態(tài)對應的情況,以及狀態(tài)轉移的跳轉位置。
typedef struct { uint8_t coordinate; //當前狀態(tài)索引號 uint8_t back; //返回 void (*enter_operation)(int8_t* ); //指向執(zhí)行函數(shù),作為當前狀態(tài)執(zhí)行的操作 //當 entry鍵按下時 sub_base_addr提供子狀態(tài)的基地址索引,sub_offset_addr提供偏移量,兩者相加,得到下一個狀態(tài) uint8_t sub_base_addr; //子狀態(tài)基地址 uint8_t sub_offset_addr; //子狀態(tài)偏移地址 (用于記錄下一步要跳轉到的子狀態(tài)) uint8_t leaf_node_flag; //標志是否為葉子節(jié)點(最底層的狀態(tài)),方便在該狀態(tài)下按確定可以實現(xiàn)返回功能 } Menu_table; //針對下表,一些想法:其實可以增加一個變量來實現(xiàn)樹的收縮的(解決音樂播放時,點擊任意一首歌進入的是同一個狀態(tài),目前是enter事件給特殊,如果還有,就思考了) //初始化菜單所處在的各個狀態(tài) Menu_table table[]= { //索引 - back - function(當前) - 子狀態(tài)基地址(固定) - 子狀態(tài)偏移地址 - 標志是否為葉子節(jié)點 { 0, 0, (*load_menu), 1, 0, 0}, //0加載界面 { 1, 1, (*main_menu), 2, 0, 0}, //1主菜單界面 { 2, 1, (*playlists), 4, 0, 0}, //歌單 { 3, 1, (*settings_list), 5, 0, 0}, //設置 //播放的子菜單 { 4, 2, (*music_play), 0, 0, 0}, //音樂播放控制:(2-1) //設置菜單的子菜單 { 5, 3, (*volume_control), 0, 1, 1}, //音量控制 { 6, 3, (*language_setting), 0, 1, 1}, //語言設置 { 7, 3, (*brightness_setting), 0, 1, 1}, //亮度設置 };
狀態(tài)轉移主要是按鍵來實現(xiàn)的,每個按鍵按下,就會觸發(fā)狀態(tài)轉移,狀態(tài)轉移的代碼如下所示:
/* 菜單界面顯示線程入口函數(shù) */ static void menu_thread_entry(void *parameter) { rt_uint32_t e; int8_t k; while(1) { if (rt_event_recv(&control_event, (UP_FLAG | ENTRY_FLAG | RETURN_FLAG | DOWN_FLAG), RT_EVENT_FLAG_OR, RT_WAITING_FOREVER, &e) == RT_EOK) { //向上 if (rt_event_recv(&control_event, UP_FLAG, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, &e) == RT_EOK) { table[func_index].sub_offset_addr -= 1; table[func_index].enter_operation(&table[func_index].sub_offset_addr); } //確定 if (rt_event_recv(&control_event, ENTRY_FLAG, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, &e) == RT_EOK) { if(table[func_index].leaf_node_flag) { func_index = table[func_index].back; //返回上一級菜單位置 table[func_index].enter_operation(&table[func_index].sub_offset_addr); } else if(func_index == 2) //音樂播放則特殊點(所有音樂進入同一個狀態(tài)) { k = table[func_index].sub_offset_addr; func_index = 4; table[func_index].sub_offset_addr = k; table[func_index].enter_operation(&table[func_index].sub_offset_addr); } else { func_index = table[func_index].sub_base_addr + table[func_index].sub_offset_addr; table[func_index].enter_operation(&table[func_index].sub_offset_addr); } } //返回 if (rt_event_recv(&control_event, RETURN_FLAG, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, &e) == RT_EOK) { func_index = table[func_index].back; table[func_index].enter_operation(&table[func_index].sub_offset_addr); } //向下 if (rt_event_recv(&control_event, DOWN_FLAG, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_NO, &e) == RT_EOK) { table[func_index].sub_offset_addr += 1; table[func_index].enter_operation(&table[func_index].sub_offset_addr); } } } }
演示效果如下:
以下是代碼的 gitee 地址:
https://gitee.com/Eureka1024/MusicPlayerBasedOnGestureRecognition