综述
本文是蓝牙音箱的手册。
蓝牙音箱作为礼物,面向的是用户,但是这位用户同时又是开发者,因此音箱的设计原则是实现一定的功能,并提供足够的扩展接口、开放设计文档。
资料下载:提取码0910。
硬件
音箱由外壳、3块PCB、扬声器、面包板、若干连接线和电源适配器组成。
外壳包括亚克力材质的底板、面板和侧板。底板和面板之间用不锈钢合页连接,可调整至侧板上有缺口的角度处固定,可用的角度有60、65、70、75和90度。
3块PCB中,底板包含电源与控制部分,2块面板中下侧的一块为外设,右上的为音频。
16*8点阵屏为主要输出设备,4个按键(标号为0到3)的功能在下一节中介绍。
3个旋钮中,右上调节低频增益,左上调节低频范围,下面的调节音量,逆时针旋到底可静音。
控制板上的绿灯指示蓝牙连接,断开
J5
以禁用;音频板上的红灯指示输出开启,把R19
移到旁边的焊盘上以禁用。控制板和外设板、音频板之间分别用8、4针排线连接,标“1”的位置对应;控制板和音频板之间还需2根电源线,“+”“-”对应。
电源适配器为市售的12V/1A直流电源,5.5-2.1插头,内正外负。
控制板接12V电源,LDO降压到5V给板载设备,不分数字模拟。12V有过流保护,5V有过压保护。外设板通过排针从控制板上取5V,音频板通过端子从控制板上取12V,并用LDO降压到10V用于音频信号放大。
蓝牙模块JDY-67输出左右声道音频信号,左、右与混合为3个信号源;6.35mm辅助输入的左声道为信号源,增益可通过控制板左下方的电位器调整;另一信号源为分压后的单片机定时器输出。以上信号源经CD4051选择一路(SRC
)送到音频板上,10倍放大并调整直流电位到2.5V后送回(AUD
)。此信号通过截止频率可调的低通滤波器、放大倍数为0到大约3可调的共射放大电路(反相),进入带恒流源的、放大倍数为1的双端输入、单端输出差分放大电路,另一路为AUD
。差分放大电路输出用射极跟随器缓冲,进入D类功放芯片PAM8320,增益26dB。
AUD
在控制板上经低通滤波器进入全波整流电路,信号幅度ENV
输出给单片机ADC。AUD
串联10kΩ电阻后接ADC。ADC还接有光敏电阻和热敏电阻,后者在音频板上,靠近PAM8320底部焊盘。
单片机采用ATmega328P,频率20MHz。UART的RX直接引出,TX用CD4053复用为2路引出,TXDS
信号选择通道,可用跳线连接蓝牙模块。SPI连接LED驱动与按键扫描芯片TM1629与时钟芯片DS1302,前者在外设板上。两芯片均为半双工IO设计,用SS
信号驱动CD4053切换通道。
扩展接口共4组。控制板与外设板右侧可插MEDS模块,也可连接其他I²C设备;面包板右上方为UART区域,M
和B
分别表示单片机和蓝牙模块,ETX
为TXDS
高电平时单片机串口输出;右下方为单片机GPIO与5V电源,PC
可接ADC,PD
可接定时器0;下方为模拟区域,从左到右分别为蓝牙左、右、放大后的辅助输入、2.5V电源、CD4051通道6、7,2.5V电源在音频域中输出100mA时波纹小于50mV。
已知问题与解决方案:
面板固定不牢固,建议在插槽处安装螺丝,把面板卡在侧板的缺口处。
侧板上有45度缺口,但调整至该角度时杜邦线会受挤压,因此不可用。
SS
应连接CD4053的11号引脚,TXDS
应连接9号,PCB设计错误,已经魔改解决。蓝牙模块已改为直连5V并连接MLCC,AMS1117-5.0输出增加470Ω电阻以满足10mA最小电流要求,但仍不能彻底消除噪音。
TF卡无法使用,可能是因为
CLK
没有上拉。音频板上
L1
和L2
不焊,短接,因为贴片磁珠额定电流不够。D1
应改为1206封装,TM1629引脚超出焊盘,6.35mm插座的封装中缺口位置错误,但这些都不影响装配。
界面
可切换的有5个界面:时钟、闹钟、通道选择、频谱和动画。还有一个闹钟响起的界面。按键0用于切换至下一界面。
时钟界面
显示时间。按下按键2,依次显示年份、日期、星期几与小时。使用按键3在分秒和时分之间切换。
按下按键1后可用按键2、3调整分钟,再按按键1调整秒钟,再按保存。
闹钟界面
与上面类似,依次调整小时、分钟的十位和分钟的个位,最后按下按键1保存。
如果已经设定闹钟,会显示目标时间。按下按键1取消。
闹钟响起界面
闪烁显示时间。按任意按键返回闹钟响起前的界面。
通道选择
可选择的通道有0、1、2、3和5,分别为静音、蓝牙左、蓝牙右、蓝牙左右混合和放大后的辅助输入。按键3切换,按键1选择。
按键2可关闭点阵屏。
频谱
显示频谱。按键无用。
动画
与低频信号响度有关的动画。按键无用。
已知问题与解决方案:
点阵屏显示的内容越多噪音越大,也许和亮度也有关系,建议享受音乐时关闭点阵屏。
切换至通道0会爆音。建议用旋钮来静音。拔电源时也会爆音,建议一直插着。
软件
开发环境Atmel Studio 7.0。BluetoothSpeaker
包含driver
和program
等多个项目,driver
为各设备API,program
为可执行程序,其余都是开发单个功能时的代码。
driver
中的各API就对照着实现顾名思义吧。注意TM1629和DS1302相关的数字都是BCD表示的。除了UART以外,所有操作都是阻塞的。
程序使用一种有点像操作系统的任务管理方式。每个界面称为一个“page”(“process”或“thread”更合适),每个page包含cdtor
、listener
和thread
三个函数指针字段:
cdtor
为page的构造和析构函数,进入和退出时调用。函数switch_page
封装了这一过程。listener
为监听器,按键按下时调用。按键响应有两种方式,一种是在listener
内部处理,另一种是调用button_forward
把事件存储在flag中,在thread
中调用button_read
读取。thread
为主线程,界面控制在此执行。函数不得返回。
main
函数先初始化,然后进入第一个页面。在定时器中断中,程序读取按键,在有按键动作时调用当前页面的listener
。listener
内部调用switch_page
,其中依次关全局中断、调用dtor、配置页面、调用ctor,把栈指针SP
写为内存最高地址以防止内存溢出、开全局中断,最后调用新页面的thread
。
independent_listener
是独立于页面的监听器,负责闹钟的计时。
频谱页面使用了Arduino FHT库,规模256,计算线性幅度,取前64个分组累加,最后对数映射输出。
动画页面根据ENV
信号的电压检测峰值,按照信号是否超过最大值的3/4分两种情况。屏幕上一个点在对角线方向上移动,碰到边缘反弹,电压高时点变大且移动加快。
已知问题与解决方案:
UART接收的ISR中,如果有操作会打开中断,一定要确保
UDR
已经读取,否则会递归进ISR。ADC注意精度问题,有时8位不够。
如果SPI的
SS
为输入,低电平时MSTR
位会清零,置位前无法作为主机发起通信,所以要在初始化SPI寄存器之前开上拉电阻或配置输出。DS1302在写入RTC寄存器时会重新开始计秒。
代码第604行对
i == 15
会复位,不知道是哪里出问题了。
设计提示
硬件:
连接MEDS模块(I²C自己写哦)。
侧板上加灯条。
*改用电池供电。
魔改外设板供电。
蓝牙音频与辅助输入混合。
软件:
重构。
与蓝牙模块通信,实现暂停、下一曲等功能。
让单片机像蓝牙模块那样,允许用户通过串口控制设备。
*智能校正时间。
根据光强调整点阵屏亮度。
显示温度、过温保护。
*节奏检测。