女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

聚豐項目 > 基于手勢識別控制的音樂播放器

基于手勢識別控制的音樂播放器

中科藍訊公司推出的 AB32VG1 開發(fā)板,這個開發(fā)板自帶 按鍵模塊、audio 模塊和 TF card 模塊,基于該開發(fā)板結合 OLED12864 模塊作為顯示屏幕,加上 PAJ7620U2 手勢識別模塊,制作了一款基于手勢識別的音樂播放器,這樣就可以實現(xiàn)非接觸式控制音樂播放,這個模塊作為一個基礎,之后也能構造出更炫酷的作品 該音樂播放器目前實現(xiàn)了如下功能: 1、可以通過 OLED12864 模塊顯示播放器信息。 2、可以通過按鍵控制音樂播放和設置一些信息。 3、讀取 SD 卡的音樂文件并播放。 4、通過手勢識別模塊控制播放器

Eureka1024 Eureka1024

分享
0 喜歡這個項目
團隊介紹

Eureka1024 Eureka1024

團隊成員

Eureka1024 軟件開發(fā)

分享
項目簡介
中科藍訊公司推出的 AB32VG1 開發(fā)板,這個開發(fā)板自帶 按鍵模塊、audio 模塊和 TF card 模塊,基于該開發(fā)板結合 OLED12864 模塊作為顯示屏幕,加上 PAJ7620U2 手勢識別模塊,制作了一款基于手勢識別的音樂播放器,這樣就可以實現(xiàn)非接觸式控制音樂播放,這個模塊作為一個基礎,之后也能構造出更炫酷的作品 該音樂播放器目前實現(xiàn)了如下功能: 1、可以通過 OLED12864 模塊顯示播放器信息。 2、可以通過按鍵控制音樂播放和設置一些信息。 3、讀取 SD 卡的音樂文件并播放。 4、通過手勢識別模塊控制播放器
硬件說明

使用到的模塊如下:


2.1、按鍵模塊(GPIO)

按鍵模塊使用如下 GPIO 引腳:

  • S2 -- PF1 (單擊為向下選擇)

  • S3 -- PF0(單擊為確定,雙擊為返回)

  • S4 -- PA2(單擊為向上選擇)

使用按鍵軟件包:multibutton

2.2、OLED12864 模塊(IIC 協(xié)議)

使用的引腳如下:

  • SDA --  PA6

  • SCL --  PA0

沒有使用 u8g2 的驅動軟件包,因為內(nèi)存不夠。使用了網(wǎng)上的軟件 IIC 實現(xiàn),做了一些修改。


2.3、SD 卡模塊(SDIO協(xié)議)

使用的 SDIO 協(xié)議對應的引腳如下:

  • SD_CMD -- PB0

  • SD_CLK -- PB1

  • SD_DAT -- PB2

  • SD_DET -- PE5

使用到 RT-Thread 提供的 SDIO 驅動,使用到的組件和服務層有 DFS、Fatfs 和 POSIX。


2.4、AUDIO 模塊

  • VOUTRP -- DACR

  • VOUTLP -- DACL

  • FMANT -- FM_ANT

  • MICIN -- MICL/PF2

使用到的驅動 audio device, 軟件包為 wavplayer(需要optparse軟件包),可以用來播放 wav 格式的音樂文件。


2.5、手勢識別模塊(PAJ7620模塊)-- IIC協(xié)議

  • 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)間的轉移關系。


image.png


網(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

評論區(qū)(0 )