×

生日蛋糕自动木琴(钟琴)开源分享

消耗积分:0 | 格式:zip | 大小:0.67 MB | 2022-11-07

王尚岱

分享资料个

描述

让我们从一些动态图片开始:

介绍

该项目的目的是制作个人生日礼物。在这样做的同时享受电子、软件和 3D 打印的乐趣!

草莓奶油蛋糕有 4 种操作模式,通过旋转草莓编码器进行设置。

默认模式只有led效果,没有声音。然后你有生日模式,蛋糕播放生日快乐,直到你再也不想庆祝生日。它还具有“随机播放”模式。它在这里播放随机歌曲。最后还有一个惊喜模式,在这种模式下,灯熄灭,没有音乐播放,如果灯亮了,它会突然播放一首歌。

Part1 :木琴

多少个键和什么频率?

经过几次迭代后,我接受了这个折衷方案:

  • 12键,铜制,外径10mm,内径8mm。
  • 支持音符 C6、D6、D#6、E6、F6、F#6、G6、A6、A#6、B6、C7、D7。

我从 http://users.df.uba.ar/sgil/physics_paper_doc/papers_phys/lapp.pdf获得的密钥长度公式

pYYBAGNkeeqAIczEAACjyMswXq8278.png
长度计算器电子表格,见附件部分
 

我切了一块比计算值大几毫米的铜片,然后轻轻地锉掉边缘。我定期使用应用程序(检查频率注意:在管子上钻孔或打磨管子会稍微改变频率。

poYBAGNkeeyATxkBAAAwLOIIvho000.png
用于检查按键频率的 Stonekick 调谐器应用程序
 

几个学习者:

  • 你真的需要更多的键来播放大多数音乐。我猜至少有 18 个或 24 个。使用 12 个键,该设备只能播放部分歌曲或带有简单旋律的歌曲。
  • 虽然木琴是和弦的(可以同时敲击所有 12 个键),但实际上大多数可播放的歌曲并不使用它。
  • 管子用砂纸抛光,然后涂上清漆。如果您将钥匙放入无绳电钻中,通过旋转钥匙并用 600 号砂纸固定它很容易使其变得非常光滑。

第 2部分电磁铁和撞针

pYYBAGNkefCAfGFjAAEvhx7XzAQ880.png
12 个带毡织物的前锋,以减少噪音
 
pYYBAGNkefOAHFw8AAEABsj2MPs500.png
前锋由三部分组成
 

这比我预想的要困难得多。

我从一个电磁铁开始,如果有电流流过它,它就会把铁芯拉到它的中心。事实证明这不是一个好主意,因为它需要电磁铁中的大量电流,并且您只能将某些东西拉入核心,而无法排斥它,这使得击键更加困难。

然后我读到了关于使用钕磁铁作为磁芯的信息。这显着降低了所需的电流,现在可以通过将磁铁与电磁铁相斥来敲击琴键。

但是 - 没有什么是免费的 - 另一个问题出现了:前锋中的磁铁相互影响。必须进行大量调整(曾在线圈底部添加铁环以引导磁场),但最终找到了一个解决方案,即每个撞针只使用一个磁铁,并保持足够多的撞针分开。

最终撞针由三部分组成:铁制家具螺丝的空心部分、塑料支架和钕磁铁。无需胶水,磁铁将其固定在一起。

我制作了电子设备,以便可以通过软件控制电磁铁电流。虽然改变打击力对于播放歌曲并不是绝对必要的,但它使调试和调音变得容易。

最终的电磁铁有 570 匝 0.2mm 直径的漆包线。电阻约为5.5Ohm。

为了减少撞针回落到核心中产生的声音,在关键部位使用了毡织物,并且电磁铁的内部和撞针的外部都经过了平滑处理。

不过,我对音质并不是 100% 满意,敲击琴键的声音对我来说有点突出......

Part3 :电子产品

pYYBAGNkefaAcCT8AAFA6QA_qlI017.png
请参阅附件部分中的原理图和 pcb
 

原理图

原理图没什么特别的。Atmega328PB 微控制器与 12 通道 DAC 进行串行通信。每个 DAC 输出后接一个功率双极晶体管,布置为射极跟随器。

二极管 D3..D14 保护晶体管免受感应反冲能量的影响。

我添加了一些基本的过电压、ESD 和错误极化保护。通过添加这些,测试期间破坏组件的变化大大减少。

印刷威廉希尔官方网站 板

PCB就是我所说的1.5层PCB。底部是完整的接地层,因此无需蚀刻。所有轨道都在顶层运行,要访问 GND,您只需添加一个过孔。

在我的下一个项目中,我将在线订购 pcb,但现在我自己蚀刻它,如果原型制作要快得多。

如果您使用镊子和双目显微镜,安装相对较小的组件是最容易的。

物料清单

所有组件均在mouser.com购买

LED环和79

pYYBAGNkefmAF_RoAAGN7_18s3E577.png
看看里面的七。0.6 毫米薄的前部咔哒一声。
 
poYBAGNkefyAI1eXAACjsWEYXFI771.png
戒指的 LED 灯带隐藏在蛋糕内
 

使用好旧的WS2812智能LED。18 为“79”,35 为环,全部串联。

电源

任何 5V/2A 稳压电源都可以工作。我拿了一根 USB A 到 USB B 电缆并切断了 USB B 连接器。我将红/黑线焊接到 PCB 上的 5V/GND。USB A 连接器可插入 USB 充电器或移动电源。

Part3 :机械零件

poYBAGNkef-AIkLyAABXITWVs-U183.png
Fusion360项目
 

大约 8 个月前,我们购买了我们的 Prusa mk3s 打印机,它确实达到了预期。它提供了漂亮的结果并且可以毫无问题地工作。带纹理的钢板提供了非常好的表面。

我儿子是 3D 设计师,他像专业人士一样使用 fusion-360(供个人使用)。

第三部分软件

Excelmacro将midi转换为“arduino”数组

pYYBAGNkegKAN53sAAGHdpHrAPQ674.png
见附件部分的excel文件
 

使用 SD 卡可以直接在 arduino 软件中读取 MIDI 文件。没有一个,下一个最好的事情是将 midi 文件转换为更紧凑的数组格式。后者是我所做的。

step1:选择一个midi文件并对其进行预处理。例如,剪掉一块或只保留 1 个“轨道”。我使用 MuseScore3(免费)来做到这一点。

step2 : 使用 midicsv 工具 将 midi 文件转换为 csv 文件。

step3:我做了一个excel宏:

  • 打开 csv 文件。
  • 移调音符,使最低音符对应于蛋糕上可用的最低音符 (C6)。
  • 允许您检查是否可以在蛋糕上播放歌曲中的所有音符。如果没有回到绘图板(Musescore 或只是找到另一个 midi 文件)。
  • 生成一个可以粘贴到 arduino 源代码中的数组。

为 Atmega328PB 控制器设置 arduino。

在使用 arduino IDE 之前,必须在处理器中加载引导加载程序。由于我忘记在 MISO/MOSI/SCK 引脚上添加排针,我必须先将小电线焊接到这些引脚上。

Atmega328PB 的额外功能默认情况下不可用,因此我必须在 IDE 中安装 Watterott 软件包 ( https://github.com/watterott/Arduino-Boards)才能正常工作。

经过很多问题我发现boards.txt中的波特率需要从57600更改为115200。

c++软件

poYBAGNkegSAPRPbAACfhsP4nok493.png
见附件部分的代码
 

事件驱动的应用程序可能更简洁,但我决定采用同步解决方案。主循环以固定的 300Hz 运行,每个对象或状态机在每个周期都更新。

高级概览应用程序

DacBH2221FV.h 允许您将值写入任何 dac 通道。

Key 类包含驱动单个键所需的所有内容。键由它们的 midi 编号标识。

MusicPlayer 类拥有 12 个键并且知道如何播放歌曲。歌曲存储为结构紧凑的数组(请参阅 SongData.h )

ControlLights 类提供简单的函数来控制 79 和环形 LED。

RotarySwitch 和 SwitchAndLDR 类允许访问旋转开关和光传感器。

最后,Controller 类使所有这些都可以协同工作。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'生日蛋糕自动木琴(钟琴)开源分享',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);