M61实现蓝牙歌词播放功能

[复制链接]
查看1044 | 回复11 | 2024-11-23 21:34:21 | 显示全部楼层 |阅读模式
本帖最后由 sujingliang 于 2024-11-24 19:15 编辑

M61模块的核心BL618确实支持传统蓝牙功能,然而,由于博流官方(BL618芯片制造商)尚未正式发布针对这一功能的SDK,开发者在使用M61进行传统蓝牙开发时面临诸多挑战。GitHub上虽然可以找到博流官方的SDK,但其中关于传统蓝牙的代码非常有限,且基于Zephyr蓝牙栈的官方代码缺乏具体的例程,这无疑增加了开发的难度。

一、论坛里有大佬实现了BTstack port,参见:
使用BTstack测试M61
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=44962&fromuid=14007
(出处: 物联网开发者社区-安信可论坛)
也就是说可以用BTstack开源协议栈来开发M61模块传统蓝牙功能。

二、本文想实现的蓝牙歌词播放功能可参见:
看到有蓝牙歌词播放器在卖,感觉很神奇,用ESP32实现一下
https://bbs.21ic.com/icview-3414880-1-1.html?fromuser=sujingliang
(出处: 21ic电子技术开发论坛)

为了达到目标,需要完成以下工作:
1、驱动一个屏幕,可以是LED、LCD,这个决定最终的显示效果。
2、需要一个GBK汉字字模库,用来获取显示汉字。
3、需要一个UTF转GBK的函数,因为AVRCP是UTF-8格式的,需要转换成GBK格式才能通过GBK汉字字模库获取字模。
4、读懂A2DP例程,加入适当的功能。(btstack编程)


三、关于LCD驱动和字库驱动,不是本重点,请参见:
【外设移植】+LCD_ST7735+M61开发板+GB2312字库
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=44421&fromuid=14007
(出处: 物联网开发者社区-安信可论坛)

四、关于UTF转GBK的函数
UTF汉字不能直接转换为GBK,需要先将UTF转换为unicode,再将unicode通过查表法转换为GBK。
这部分不用自己实现,网上有现成的。https://gitee.com/zhangkt1995/my ... /utf8_gb2312_switch

五、btstack编程
可参考前面大佬提供的btstack_test工程:

  1. git clone https://github.com/bouffalolab/bouffalo_sdk.git
  2. cd ./bouffalo_sdk/examples
  3. git clone https://github.com/O2C14/btstack_test.git
  4. cd ./btstack_test
  5. rm -rf ./btstack
  6. git clone https://github.com/bluekitchen/btstack.git -b v1.6.1
复制代码
在CMakeLists.txt中设置使用a2dp_sink_demo.c这个例子
  1. set(EXAMPLE "a2dp_sink_demo")
复制代码
a2dp_sink_demo.c中在 case AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO:增加如下内容
  1. case AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO:
  2.             if (avrcp_subevent_now_playing_title_info_get_value_len(packet) > 0){
  3.                 memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_title_info_get_value(packet), avrcp_subevent_now_playing_title_info_get_value_len(packet));
  4.                 printf("AVRCP Controller: Title %s\n", avrcp_subevent_value);
  5.                                 
  6.         memset(gb2312Data,'\0',sizeof(gb2312Data));
  7.         size_t gb2312DataLen = utf8_to_gb2312((uint8_t *)avrcp_subevent_value, strlen(avrcp_subevent_value), (uint8_t *)gb2312Data, sizeof(gb2312Data));
  8.                                 
  9.         
  10.         if(gb2312DataLen>0){
  11.                 if(gb2312DataLen<256)gb2312Data[gb2312DataLen]='\0';
  12.                 gb2312Data[64]='\0';
  13.                 printf("%s,len:%d\r\n",gb2312Data,strlen(gb2312Data));
  14.                 GUI_Write16CnCharMatrix(10,10,gb2312Data,LCD_COLOR_RGB565(255,255,255),LCD_COLOR_RGB565(255,0,0));
  15.         }
  16.                
  17.             }
  18.             break;
复制代码
大概意思就在AVRCP收到TITLE事件后,获取title(歌词)信息avrcp_subevent_value;通过utf8_to_gb2312将utf8格式转为GB2312格式;然后在LCD上显示出来。

AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED中增加对avrcp_controller_get_now_playing_info的调用,就是在TRACK发生改变时调用获取playing_info函数,进而触发AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO。
  1. case AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED:
  2.             printf("AVRCP Controller: Track changed\n");
  3.             //Track changed
  4.             avrcp_controller_get_now_playing_info(a2dp_sink_demo_avrcp_connection.avrcp_cid);
  5.             break;
复制代码

六、使用
1、手机打开蓝牙,和M61配对连接,然后可以断开连接
2.jpg

2、在手机蓝牙断开连接的情况下,
通过串口工具发出btstack c命令使M61发送AVRCP连接命令,缺省会触发订阅AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED
avrcp_controller_enable_notification(a2dp_sink_demo_avrcp_connection.avrcp_cid, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED);
这时手机和M61会自动连接上。
1.png
3、打开手机上的音乐播放软件
3.jpg
手机上的歌词变化,LCD上也会相应变化:
tutieshi_320x180_19s.gif


七、总结
1、使用了BTstack下的a2dp_sink_demo例程,这个例程好像是mcu这边连接手机发送A2DP、AVRCP连接和订阅才能获取歌词信息,而通过手机连接MCU就不能。尝试改成手机端主动连接实现相同功能,但没有成功,还是对btstack了解太少。而且从MCU端连接需要提供手机蓝牙的MAC地址,这个比较头晕了,打个比方:想用蓝牙耳机连接手机听歌需要先知道手机蓝牙MAC,这完全不具有操作性。
2、类似下面的报错时不时就发生,然后程序就挂了,非常不稳定。
exception_entry
mcause=38000007
mepc:a0004732
mtval:00000000
Store/AMO access fault
3、不是每个手机都可以建立AVRCP连接,手头2个手机,1个可以,1个不行。
4、归根到底利用AVRCP协议获取歌词信息,实现的方案还是存在不少问题。主要是因为接触传统蓝牙时间比较短,而且蓝牙协议栈还是太复杂,好多东西都不懂。没有好办法,慢慢看吧,说不定哪天就看懂了。



回复

使用道具 举报

O2C14 | 2024-11-23 22:14:50 | 显示全部楼层
a0004732是个程序段的地址,打开build目录下的.asm文件看看这个地址附近是什么
回复 支持 反对

使用道具 举报

qhsj | 2024-11-23 22:27:06 | 显示全部楼层
太牛辣!!
回复

使用道具 举报

大猫的鱼 | 2024-11-23 23:56:06 | 显示全部楼层
回复

使用道具 举报

sujingliang | 2024-11-24 07:36:10 | 显示全部楼层
O2C14 发表于 2024-11-23 22:14
a0004732是个程序段的地址,打开build目录下的.asm文件看看这个地址附近是什么

感谢大佬
回复 支持 反对

使用道具 举报

lovzx | 2024-11-24 09:53:03 | 显示全部楼层
学习
回复

使用道具 举报

bzhou830 | 2024-11-25 08:40:02 | 显示全部楼层
太牛辣!!
选择去发光,而不是被照亮
回复

使用道具 举报

干簧管 | 2024-11-25 13:50:34 | 显示全部楼层
玩的厉害
回复

使用道具 举报

lazy | 2024-11-28 08:56:14 | 显示全部楼层
回复

使用道具 举报

这原理是啥,播放器会自动蓝牙发送歌词还是需要设置?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则