原创 【电子DIY设计】会微笑的电子乐器

2023-12-18 23:01 949 4 4 分类: 智能硬件 文集: DIY

前言

我们生活在一个被科技和艺术深度渗透的世界,这两者之间的界限正在不断地被拓宽,创新的可能性也随之增加。在这个过程中,一种全新的概念——会微笑的电子乐器,应运而生。这是一种将科技与艺术、功能与形式、人与机器之间的交互推向全新高度的创新尝试。

会微笑的电子乐器,不仅仅是一种乐器,更是一种具有生命力和情感的互动艺术装置。它通过电子技术实现了乐器功能的人性化展现,让每一次的触碰、每一个音符都充满了温度和情感。增强用户的体验,让人们在享受音乐的同时,也能感受到科技带来的新奇和乐趣。

这个创新的想法源于对科技与艺术、人与机器之间关系的深度思考,希望通过“会微笑的电子乐器”,探索一种全新的互动方式,让科技更加贴近生活,让艺术更加深入人心。相信当科技与艺术完美结合,当功能与形式融为一体,当人与乐器无障碍交互,将开启一个全新的艺术与科技的新纪元,期待看到更多的创新和突破,看到科技与艺术的更深度的融合,看到人与机器之间更自然的交互。

 

项目概述

“会微笑的电子乐器”是一个可以展示笑脸的电子乐器,可以通过不同的输入方式来实现乐器的功能,在享受乐器的同时也能感受到乐器的光影展示。6键的基础输入以及可以扩展输入,让其具备多样性。

 

需求分析

1、播放声音:乐器的最主要的功能就是声音的播放,选用的是4Ω3W的扬声器,以确保音质清晰且音量适中,并且可调节音量;

2、输入操作:为了实现声音的有序播放,需要一定的输入介质,本次6键的基础输入选用的是触摸按键,用户可以通过它们演奏(本次初步设计电子音为架子鼓的6个音)。为了实现不同的按键输入方式,按键与主板分离;

3、光影展示:为了使乐器更具趣味性,我们选用的是8个WS2812灯珠来展示笑脸,当乐器播放音乐时,灯珠会随之变化;

4、可扩展性:暂定的基础按键是6个,可以允许搭配更多的按键。

 

功能分析

为了实现需求,我们对整体进行了一个功能划分以及基本的概要设计。

功能框图如下:

从上图可以看出,蓝色模块为基本外界器件;绿色模块为主控板主要功能模块;灰色模块为基本外接按键板。


概要设计:

1、供电部分

供电部分本次选用了两种供电方式:USB和电池,可以保证更多的场景下都可以使用,并且配备了一个充电模块;USB具有供电优先权,通过供电选择电路控制关断电池的供电;

2、开关机部分

开关机的实现是通过一个按键的输入实现的,并通过开关机自锁电路实现开关机功能;

3、DCDC部分

DCDC部分是通过一个LDO实现对主控单元的稳定供电,稳定电压确保主要电子元件的正常运行;

4、音频驱动部分

扬声器属于功率元件,不能通过主控直接驱动,需要使用专用的驱动芯片进行控制,对于变化的音乐,是通过DAC的方式将不同的声音通过电信号传输出去;

5、主控单元

主控单元室整个项目的大脑,处理核心,它需要一些基础的外围电路来保证基本运行,包括复位、晶振、供电等等;

6、WS2812灯珠控制电路

WS2812灯珠是串行接口控制的,可以将多个灯珠串联,然后通过特定时序进行编码控制,每一个灯珠会保留24位数据用于颜色的显示;

7、输入接口

为了实现组合的多样性,控制声音的按键没有放置在主控板上,是通过插座进行的连接,根据功能划分每三个按键放在一个按键板上,基础按键共六个,需要2个插座,扩展按键6个需要2个插座。

8、存储单元

存储单元作为扩展资源的备选,本次的电子乐器的实现主要还是通过单片机内部的Flash来进行存储。

9、按键板

每个按键板上放置了三个触控按键。

 

详细设计——原理图设计

详细设计这里通过农村包围城市的,先对各个功能模块进行设计,并对单片机资源需求进行分析,最后通过各个资源的汇总进行单片机的选型。

1、供电部分

先上图:

供电U口使用的是type-c口,目前这种接口相对比较流行,主要就是正反插方便,注意CC口要下拉5.1K电阻;

充电模块使用的TP4056,相关充电状态的展示都是通过硬件实现的,即对CHRG与STDBY引脚上连接LED灯。TP405 6是一款单节锂离子电池采用恒定电流/恒定电压线性充电器,带电池正负极反接保护,采用底部带有散热片的SOP-8-EP封装,充满截止电压4.2 V。包含两个漏极开路输出的状态指示输出端,充电状态指示端CHRG 和电池充电完成指示输出端STDBY。充电电流是采用一个连接在PROG 引脚与地之间的电阻器来设定的,R=1100/I,本次使用的是1.2K电阻,对应的电流约800mA。TEMP引脚是连接外部测温器件的,不用需要连接到地;

而对于供电优先权是通过一个MOS控制的,如果USB存在,MOS将关闭。

单片机资源需求:1个adc采集机(电池电量采集)。

2、开关机电路

上图:

开关机是通过一个轻触按键实现的,按键按下后供电实现下一层,然后单片机的程序开始运转,通过自锁引脚的控制实现三极管加MOS管的持续打开,关机是通过按键状态的采集然后关系自锁实现。注意三极管或者MOS管需要初始化的状态,按键的采集可能会超过单片机IO口的上限,通过电阻分压的方式避免损坏。

单片机资源需求:一个IO输出或外部中断输入,一个IO输出控制。

3、DCDC电路

上图:

根据供电电路的线条终于来到了最后一个环节,通常的单片机系统有2.8V、3.3V、5V等,本次选用单片机处于3.3V供电系统的,所以在这里选择SGM2019-3.3这一款LDO来保证供电的稳定性。

单片机资源需求:无。

4、音频驱动部分

上图:

本次使用的是一个闲置的扬声器(4Ω3W),驱动使用的是PAM8403,一款音频放大器,用于将弱信号转换为强信号的设备。声音的播放是一种高耗能器件,所以不用用LDO进行供电(输出不够),直接使用电池或者USB进行供电。它是一个 2 通道放大器,不过咱们只有其中一个就可以了。PAM8403 的优势之一是它不需要额外的低通输出滤波器。这意味着它可以直接驱动扬声器而无需额外的组件,与其他放大器类型相比效率更高。为了实现声音音量的控制,这里选择了一个10K的可调电阻器进行音量调节。

单片机资源需求:DAC输出。

5、WS2812灯珠控制电路

上图:

WS2812B是一种常见的RGB LED灯带,每个灯珠内部都有一个芯片控制,通过发送特定的时序数据来控制其亮灭。发送数据时,需要按照一定的时序发送24位RGB数据,其中高位在前低位在后,格式为GRB。发送数据时,需要注意不仅仅是发送高电平或低电平,而是要发送占空比不同波,比如给予一定的高电平和低电平时间。重置码是发送一个持续280us的低电平信号。可以先发送一组24位的数据,然后接一个重置信号表示一组结束。数据采用单总线,归零码的通讯方式, 每个像素点接收24bit数据,溢出的数据传输给下一个像素点。重点要注意的就是时序。

单片机资源需求:一个IO口输出。

6、输入接口

上图

本次的转接板接口选取的是贴片的PH2.0的座,为的是好走线,其中CN1和CN2为基础功能连接,CN3和CN4为扩展接口。

单片机资源需求:6个IO口输入或者外部中断。

7、按键板

上图:

每个按键板上是3个按键,结构上最好是设计上对称的,避免多打样;触摸按键采集用的是TTP223,TTP223是单通道电容触摸芯片,SOT-23-6L封装。工作电压2.0~5.5V,有点动及锁存两种输出模式,由TOG引脚控制;上电默认输出电平由AHLB引脚控制。芯片默认工作于低功耗模式(1.5uA),当检测到有触摸时会进入正常工作模式,当触摸释放大约12秒后,芯片转回低功耗模式。本设计中TOG = 0 为直接输出模式,AHLB = 0 为默认输出0。

注意在PCB设计的时候,触摸板到IC的线越短越好,并且不要与其他线平行或交叉,使用较大的电极尺寸可以提高灵敏度,使用更薄的面板可以提高灵敏度。

8、预留的存储单元

上图:

存储单元用的是W25Q32,使用SPI通信,不过尽量还是考虑直接存储在单片机的FLASH里面,毕竟个人玩烧录比较麻烦。

单片机资源需求:1个SPI接口。

9、主控单元

通过对外部的所有模块的详细设计,对相应的资源都有了一定的连接,根据覆盖程度,本次暂定的STM32F103RET6.

上图:

主控单元包括单片机以及最小系统(复位、晶振、调试等等),本次使用的晶振为3225封装的8M晶振,复位电路使用的RC电路。

根据需求分配资源,先进行最重要的DAC输出,然后是SPI接口,之后是外部中断-ADC采集,最后进行IO口的分配;有一些固定引脚是不变的,例如晶振,SWD调试接口,供电,BOOT0选择等等。


详细设计——结构设计

不建议直接在EDA软件中直接画版型结构,但凡是复杂一点的结构还是建议使用专业软件(例如CAD)进行设计,生成的结构文件可以直接导入到EDA中。

本次的小玩具中有笑脸的呈现效果,一般是弧形或者半圆,所以这里就已一个圆形作为基础,已飞碟(有两个重要控制输入)作为创意设计如下结构:

为了实现按键按键板的高度利用,设计如下:

一定要对称,安装固定孔要对上,这次并没有做出来外壳,就用这些板子自己固定一下。


详细设计——PCB设计

PCB的设计遵循先固定结构件位置,再分配功能模块的位置,按键上的触点不要太大,手指大小最好,因为按键之间也需要保持一定距离。效果如下:

 


焊接调试

等待了一周左右时间终于打样回来了,这次是通过LCEDA进行的设计,有一些地方是还存在了一些差异,一个是SK34的封装太大了,直接搜的型号结果选了一个错误的封装,一个是手里的晶振居然是16M的晶振。不过影响不大,封装不对就飞线,晶振不对可以在程序初始化里面改,实物图如下:


软件设计

本次的创意是会微笑的电子乐器,微笑的表情是通过多个RGB等的排布进行展示的,通过同步呼吸实现展示效果,然后就是电子乐器的功能实现,其音频是通过下载都内置的FLASH的点位进行存储,我们也知道这种文件都是比较到的,所以在主控的选择上选的也是大存储的微控制器,不间断的通过DAC向音频功放送数据,这里需要注意,实现呼吸灯的多个WS2812控制对时序的需求也是很严格的,这里就需要处理不同功能之间的冲突,避免干扰。最好的方法就是引入DMA,这样就可以执行两个互相不干扰的线路。

整理下具体的软件需求,先看一看硬件资源的整理,并根据原理图将相关引脚的各个功能进行连接,后续根据各功能模块进行分布初始化

根据整理好的功能划分,按照功能模块排序,按步进行初始化。


得益于STM32的优秀生态,可以进行可视化的配置:

1、首先进行时钟的配置:

输入外部时钟数值,然后根据时钟树一步一步进行配置,注意系统时钟最大72MHZ;

2、接下来进行普通IO口的设置,由于普通IO口的设置是相对简单的,可以在单片机的引脚上直接配置,这里包括自锁、LED控制、RGB等口直,没错WS2812灯珠直接通过一个IO口就可以实现联级控制;

3、外部中断采集(触摸按键采集)

对于本次的基础配置,外部中断的采集主要是6个触摸按键和1个开关机按键,引脚配置如下:

引脚设置:选择触发方式

其他引脚设置同上,然后打开中断使能:

4、接下来就是定时器的配置,我们通过前面的软件需求分析了解到,其定时器资源主要包括对WS2812灯珠的呼吸灯控制,以及基于定时器-DMA-DAC的音频播放,对于普通定时器主要就是要求能覆盖对WS2812灯珠的一次全面控制,这个可以通过后续的调试进行修改,定时器配置如下:

呼吸灯的控制使用了定时器3:

这里使用的定时器3的频率是100Hz,注意这里对于后续的处理有影响,为什么选择100Hz?主要还是WS2812在中断中能够完全刷新一次。

在定时器3的回调函数中进行WS2812操作.

5、定时器+DMA+DAC配置

音频的播放控制使用的是外部中断启动,然后在定时器中将所用的点播放完成。

初始化配置方面:定时器2:

DAC配置:

加入一个DMA:

 

接下来就是具体的程序了:

外部中断回调函数:

  1. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  2. {
  3. if(GPIO_Pin == GPIO_PIN_3 || GPIO_Pin == GPIO_PIN_4 || GPIO_Pin == GPIO_PIN_5 ||
  4. GPIO_Pin == GPIO_PIN_13 || GPIO_Pin == GPIO_PIN_14 || GPIO_Pin == GPIO_PIN_15 )
  5. {
  6. HAL_TIM_Base_Stop(&htim2);
  7. HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
  8. HAL_TIM_Base_Stop(&htim3);
  9. memset(WS2812_Buff, 0x03, sizeof(WS2812_Buff));
  10. WS2812_Buff[0][0] = (uint8_t)(RGBColor[7]>>16);
  11. WS2812_Buff[0][1] = (uint8_t)(RGBColor[7]>>8);
  12. WS2812_Buff[0][2] = (uint8_t)RGBColor[7];
  13. WS2812_Buff[1][0] = (uint8_t)(RGBColor[7]>>16);
  14. WS2812_Buff[1][1] = (uint8_t)(RGBColor[7]>>8);
  15. WS2812_Buff[1][2] = (uint8_t)RGBColor[7];
  16. WS2812_Refresh();
  17. Drum.StopCnt = 0;
  18. Drum.SingleCnt = 0;
  19. Drum.RGBUpCnt = 0;
  20. switch(GPIO_Pin)
  21. {
  22. case GPIO_PIN_5:
  23. Drum.DrumCnt = 5;
  24. curr_play = (int16_t*)Drum_Wave_6;
  25. break;
  26. case GPIO_PIN_13:
  27. Drum.DrumCnt = 0;
  28. curr_play = (int16_t*)Drum_Wave_1;
  29. break;
  30. case GPIO_PIN_4:
  31. Drum.DrumCnt = 4;
  32. curr_play = (int16_t*)Drum_Wave_5;
  33. break;
  34. case GPIO_PIN_14:
  35. Drum.DrumCnt = 1;
  36. curr_play = (int16_t*)Drum_Wave_2;
  37. break;
  38. case GPIO_PIN_15:
  39. Drum.DrumCnt = 2;
  40. curr_play = (int16_t*)Drum_Wave_3;
  41. break;
  42. case GPIO_PIN_3:
  43. Drum.DrumCnt = 3;
  44. curr_play = (int16_t*)Drum_Wave_4;
  45. break;
  46. }
  47. Drum.StopCnt = Drum_Wave_Size[Drum.DrumCnt];
  48. RGBCntMAX = Drum.StopCnt/240;
  49. Drum.Drumingflag = 1;
  50. HAL_TIM_Base_Start(&htim2);
  51. HAL_TIM_Base_Start_IT(&htim3);
  52. HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,(uint32_t*)curr_play,Drum_Wave_Size[Drum.DrumCnt],DAC_ALIGN_12B_R);
  53. }
  54. }


定时器回调函数:

  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  2. {
  3. if(htim->Instance == TIM3)
  4. {
  5. Drum.RGBUpCnt++;
  6. if(Drum.Drumingflag == 1 && Drum.RGBUpCnt>=5 && Drum.RGBUpCnt<=(RGBCntMAX-5))
  7. {
  8. uint8_t RGB_R,RGB_G,RGB_B;
  9. if(Drum.RGBUpCnt<rgbcntmax 2) {
  10. cnt = Drum.RGBUpCnt;
  11. }
  12. else
  13. {
  14. cnt = RGBCntMAX - Drum.RGBUpCnt;
  15. }
  16. if(cnt <= 5)
  17. {
  18. cnt = 5;
  19. }
  20. RGB_R = (uint8_t)(RGBColor[Drum.DrumCnt]>>16)*cnt/RGBCntMAX;
  21. RGB_G = (uint8_t)(RGBColor[Drum.DrumCnt]>>8)*cnt/RGBCntMAX;
  22. RGB_B = (uint8_t)(RGBColor[Drum.DrumCnt])*cnt/RGBCntMAX;
  23. for(uint8_t i=0;i<6;i++)
  24. {
  25. WS2812_Buff[i+2][0] = RGB_R;
  26. WS2812_Buff[i+2][1] = RGB_G;
  27. WS2812_Buff[i+2][2] = RGB_B;
  28. }
  29. WS2812_Refresh();
  30. }
  31. }
  32. }

这里就需要注意了,在改变定时器3的时间时,需要修改对应的RGBCntMAX,以达到最佳的呼吸灯效果。


DMA传输完成回调函数:

  1. void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
  2. {
  3. Drum.SingleCnt = 0;
  4. Drum.Drumingflag = 0;
  5. Drum.RGBUpCnt = 0;
  6. HAL_TIM_Base_Stop(&htim2);
  7. HAL_TIM_Base_Stop(&htim3);
  8. memset(WS2812_Buff, 0x03, sizeof(WS2812_Buff));
  9. WS2812_Buff[0][0] = (uint8_t)(RGBColor[7]>>16);
  10. WS2812_Buff[0][1] = (uint8_t)(RGBColor[7]>>8);
  11. WS2812_Buff[0][2] = (uint8_t)RGBColor[7];
  12. WS2812_Buff[1][0] = (uint8_t)(RGBColor[7]>>16);
  13. WS2812_Buff[1][1] = (uint8_t)(RGBColor[7]>>8);
  14. WS2812_Buff[1][2] = (uint8_t)RGBColor[7];
  15. WS2812_Refresh();
  16. }

DAC传输完成后就需要关闭相应的显示和输出,等待下一次开启。

到这里会微笑的电子乐器就设计完成了,效果视频如下:

作者: 金玉其中, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-4029900.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论2条评论)

登录后参与讨论

开发工匠 2023-12-28 09:17

写的好,学习和参考,大师之作

Orima 2023-12-22 21:47

牛!有实物成品吗?看看咋用?
相关推荐阅读
金玉其中 2023-12-06 09:45
【电子工程师故事】后疫情时代医疗电子行业的苦乐交响曲,从业人员的挣扎 开始
在疫情之后的2023年,医疗器械家族中的血氧仪可是彻底火了一把!这就像一个突然爆红的明星,让大家都疯狂追求。血氧仪就像一个可爱的家庭医生,方便又贴心,可以随时监测你的血氧饱和度。在疫情期间,大家可是对...
我要评论
2
4
关闭 站长推荐上一条 /2 下一条