专栏名称: 安信可科技
全球领先的联网模组、智能家居等物联网硬件方案提供商。
目录
相关文章推荐
51好读  ›  专栏  ›  安信可科技

Ai-M61系列模组实现蓝牙歌词播放功能

安信可科技  · 公众号  ·  · 2025-02-24 18:22

正文


图片


以下作品由安信可社区用户

sujingliang 制作





Ai-M61 系列模组是由安信可科技开发的 Wi-Fi6 & 蓝牙双模模组,搭载BL618芯片作为处理器,支持Wi-Fi 802.11b/g/n/ax协议和BLE 5.3协议。BL618芯片内置低功耗的32位RISC-V CPU,最高主频可达320M. 丰富的外围接口,包括DVP、MJPEG、Dispaly、Audio Codec、USB2.0、SDU、以太网(EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP和GPIO等。可广泛应用于音视频多媒体、物联网(IoT)、移动设备、可穿戴电子设备、智能家居等领域。


Ai-M61系列模块的核心BL618确实支持传统蓝牙功能,然而,由于博流官方(BL618芯片制造商)尚未正式发布针对这一功能的SDK,开发者在使用M61进行传统蓝牙开发时面临诸多挑战。


GitHub上虽然可以找到博流官方的SDK,但其中关于传统蓝牙的代码非常有限,且基于Zephyr蓝牙栈的官方代码缺乏具体的例程,这无疑增加了开发的难度。


1
论坛里有大佬实现了BTstack port

使用BTstack测试M61
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=44962&fromuid=14007
(出处: 物联网开发者社区-安信可论坛)

也就是说可以用BTstack开源协议栈来开发 M61模块 传统蓝牙功能。


2
本文想实现的蓝牙歌词播放功能

看到有蓝牙歌词播放器在卖,感觉很神奇,用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编程)



3
关于LCD驱动和字库驱动(不是本重点)

【外设移植】+LCD_ST7735+M61开发板+GB2312字库
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=44421&fromuid=14007
(出处: 物联网开发者社区-安信可论坛)

4
关于UTF转GBK的函数

UTF汉字不能直接转换为GBK,需要先将UTF转换为unicode,再将unicode通过查表法转换为GBK。

这部分不用自己实现,网上有现成的。
https://gitee.com/zhangkt1995/my ... /utf8_gb2312_switch

5
btstack编程

可参考前面大佬提供的btstack_test工程。
git clone https://github.com/bouffalolab/bouffalo_sdk.git




    
cd ./bouffalo_sdk/examplesgit clone https://github.com/O2C14/btstack_test.gitcd ./btstack_testrm -rf ./btstackgit clone https://github.com/bluekitchen/btstack.git -b v1.6.1

在CMakeLists.txt中设置使用a2dp_sink_demo.c这个例子。
set(EXAMPLE "a2dp_sink_demo")

a2dp_sink_demo.c中在 case
AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO 增加如下内容

 case AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO:            if (avrcp_subevent_now_playing_title_info_get_value_len(packet) > 0){                memcpy(avrcp_subevent_value, avrcp_subevent_now_playing_title_info_get_value(packet), avrcp_subevent_now_playing_title_info_get_value_len(packet));                printf("AVRCP Controller: Title %s\n", avrcp_subevent_value);
memset(gb2312Data,'\0',sizeof(gb2312Data)); size_t gb2312DataLen = utf8_to_gb2312((uint8_t *)avrcp_subevent_value, strlen(avrcp_subevent_value), (uint8_t *)gb2312Data, sizeof(gb2312Data));

if(gb2312DataLen>0){ if(gb2312DataLen<256)gb2312Data[gb2312DataLen]='\0'; gb2312Data[64]='\0'; printf("%s,len:%d\r\n",gb2312Data,strlen(gb2312Data)); GUI_Write16CnCharMatrix(10,10,gb2312Data,LCD_COLOR_RGB565(255,255,255),LCD_COLOR_RGB565(255,0,0)); }
} 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。


6
使用效果

●手机打开蓝牙,和M61配对连接,然后可以断开连接


●在手机蓝牙断开连接的情况下,通过串口工具发出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会自动连接上。



●打开手机上的音乐播放软件



手机上的歌词变化,LCD上也会相应变化



7
总结


使用了BTstack下的a2dp_sink_demo例程,这个例程好像是mcu这边连接手机发送A2DP、AVRCP连接和订阅才能获取歌词信息,而通过手机连接MCU就不能。尝试改成手机端主动连接实现相同功能,但没有成功,还是对btstack了解太少。而且从MCU端连接需要提供手机蓝牙的MAC地址,这个比较头晕了,打个比方:想用蓝牙耳机连接手机听歌需要先知道手机蓝牙MAC,这完全不具有操作性。



类似下面的报错时不时就发生,然后程序就挂了,非常不稳定。
exception_entry
mcause=38000007
mepc:a0004732
mtval:00000000
Store/AMO access fault



不是每个手机都可以建立AVRCP连接,手头2个手机,1个可以,1个不行。


归根到底利用AVRCP协议获取歌词信息,实现的方案还是存在不少问题。主要是因为接触传统蓝牙时间比较短,而且蓝牙协议栈还是太复杂,好多东西都不懂,慢慢学习。



8
原贴地址

Ai-M61实现蓝牙歌词播放功能



图片

微信改版,容易错过最新资讯和福利?







请到「今天看啥」查看全文