果你和老周一样,小时候特别喜欢搞破坏(什么电器都敢拆),那下面这样小喇叭你一定见过。
这种喇叭其实以前很多录音机都用,包括上小学时买来做英语听力的便携录音机。嗯,就是放录音带的那种,录音带也叫磁带或卡带,有两个轮子,录音机的动力转轴会带动轮子转动,然后就能听到声音了。
小时候,放学从学校走回家,途中就能看到不少于十处卖录音带的,有文具店的,有蹲路边卖的,甚至连一些卖早餐的店也卖。至于是否正版,这个你懂的。反正 1.5 元到 2 元一盒,零花钱省点用的话,一个星期能买到两三盒,然后回到家里又可以嗨了。也不用担心被长辈们发现,因为他们也喜欢听,被发现了他们会和你一起分享。
玩具用的喇叭会稍微比这个小一点,有正圆形的,也有椭圆形的;老周曾经在一个电子琴里拆出有正方形的喇叭,以老周幼年的拆机经验,方形是极罕见的,正圆形居多。
网上购买,一般会买到有焊接杜邦线的,以及无焊接线的。
有焊接杜邦线的就爽了,直接上线;至于无线的,如果你焊接技术好的话,也可以自己焊,如果没电烙铁没焊锡丝也不要紧,可以用带杜邦头的鳄鱼夹,直接夹住接线孔就行了。毕竟两边的线离得比较远,两个鳄鱼夹不会碰到一起,就不必担心短路了。
除了上面介绍的喇叭,还有一种模块也能播放音乐,那就是蜂鸣器。
注意蜂鸣分为无源和有源,上图中,左边的是无源蜂鸣器,右边的是有源蜂鸣器。
有源蜂鸣器,只要电平信号就能发声,而且只能产生固定音高的声音,所以,想让它播放音乐是没门的。从图中你会看到,有源蜂鸣器上那块黑色的圆柱体(像牛粪的那个)上贴着纸签,如果不撕掉,发出的声音刺耳但音量很小;如果把纸签撕掉,音量变大但没那么刺耳。我们这个让喇叭播放音乐的实验必须使用无源蜂鸣器,所以买的时候要看清楚是有源的还是无源的。
好了,上面介绍的是完成实验的器件,至于是选小喇叭还是蜂鸣器,你看着办,因为两者原理一样——我们物理课上学过,音高是由频率决定的。
上一篇烂文中,老周扯了 PWM 调光的实验,由于 PWM 能以不同的频率输出电平信号,所以设置不同的频率,再发送PWM方波,就能让喇叭发出不同音高的声音了。喇叭不能直接上电源,那样是不能放音乐的,只能听见地雷爆炸的声音。再次强调一下,是改变 PWM 的频率,不是占空比,改变占空比只能控制声音强度。
下面开始实验,此次实验老周选了一首很简单的歌,大家都听过的,《世上只有妈妈好》。简谱如下:
速度是每分钟 80 拍,所以每一拍(四分音符)的时长为 60/80 = 750 毫秒。接下来咱们确定一下曲中各音符的时值。
1、带附点的四分音符,时值为 750 + 750/2 = 1125 ms。附点就是延长当前音符时值的一半,所以四分音符加附点就是加上半拍的时值。
2、四分音符:750ms。
3、八分音符:750 / 2 = 375ms。
4、二分音符,后面有一横线的,就是两拍,750 * 2= 1500 ms。
至于每个音符的频率,可以直接网上查。
此处老周选用国际标准 A(中音 La)的频率(440 Hz)作为中音音域的参考点,于是得到各音阶的频率。
音阶频率最终取值低音部分低音 5195.998196 Hz低音 6220.0220 Hz低音 7246.942247 Hz中音部分中音 1261.626262 Hz中音 2293.665294 Hz中音 3329.628330 Hz中音 4 349.228 349 Hz 中音 5 391.995 392 Hz 中音 6440.0440 Hz 中音 7 493.883 494 Hz 高音部分 高音 1 523.251 523 Hz
封装一个类,名为 NotePlayer,调用 PlayNote 方法播放指定频率的声音,持续 X 毫秒。
class NotePlayer : IDisposable
{
private PwmChannel _pwmch = null;
// 构造函数
public NotePlayer() => _pwmch = PwmChannel.Create(0, 0);
public void Dispose()
{
_pwmch?.Dispose();
}
/// <summary>
/// 播放指定频率的声音
/// </summary>
/// <param name="freq">声音频率</param>
/// <param name="duration">持续时间(毫秒)</param>
public void PlayNote(int freq, int duration)
{
_pwmch.Frequency = freq;
_pwmch.Start(); // 开始播放
DelayHelper.DelayMillis(duration);
_pwmch.Stop(); // 停止播放
}
}
核心部分是 PlayNote 方法,首先设置频率,然后调用 PwmChannel 的Start方法开始发送脉冲,随后持续一段时间(这段时间就是音符的时值,请看上文),播放完后,调用 Stop方法停止脉冲,喇叭不发声。
这里面有个辅助方法 DelayMillis,用来暂停 X 毫秒,你完全可以用 Thread.Sleep 方法,这里老周写这个方法,用的是另一种思路——这是参考微软的写法。
class DelayHelper
{
public static void DelayMillis(int ms)
{
long ticks = ms * Stopwatch.Frequency / 1000;
long targetTicks = Stopwatch.GetTimestamp() + ticks;
do
{
Thread.SpinWait(1);
}
while (Stopwatch.GetTimestamp() < targetTicks);
}
}
原理是运用了 Stopwatch 类的计时器,GetTimestamp 方法总能返回计时器最新的 Tick,接着进入循环,每轮循环中调用 Thread.SpinWait(1) 只等待一个代码周期,这个时间很短,微秒级别的。循环退出条件是 GetTimestamp 方法返回的 Tick 达到我们预定好的时间。
这种方案适合对时间精度高的等待方案,比如等待几十微秒的。
这里要思考一件事:我们如果把每首曲子的音符都写进代码中,如果要播放其他曲子就得改一大遍代码,很不灵活。当然像 Arduino 那样没有操作系统且内部存储空间很小的板子,要么把代码写死,要么加个外部的 SD 卡模块,把音符信息放SD卡上,然后在代码中读。对于树莓派来说,这事情好办得要命。树莓派带操作系统,而且自身有 micro SD 卡接口,读写文件相当方便。
因此,老周把《世上只有妈妈好》的音符频率和时值输入到一个文本文件中,要换曲子直接换个文件就完事。格式很简单,每行一个音符,包括频率和时值,用空格分开。于是,《世上只有妈妈好》的文件如下:
440 1125
392 375
330 750
392 750
523 750
440 375
392 375
440 1500
0 750
330 750
392 375
440 375
392 750
330 375
294 375
262 375
220 375
392 375
330 375
294 1500
0 750
294 1125
330 375
392 750
392 375
440 375
330 1125
294 375
262 1500
0 750
392 1125
330 375
294 375
262 375
220 375
262 375
196 1500
0 750
其中,你会看到有几行,音符频率是 0,这个是为了让喇叭有停顿。
再写一个 MusicPlayer 类,可以控制播放整首曲子,并可以指定循环次数。
public class MusicPlayer : IDisposable
{
private bool _playing = false; // 表示是否正在播放
NotePlayer _noteplayer = null;
Stream _stream = null;// 文件流
#region 构造函数
public MusicPlayer(string noteFilepath)
{
_noteplayer = new NotePlayer();
_stream = File.OpenRead(noteFilepath);
}
#endregion
/// <summary>
/// 播放音乐
/// </summary>
/// <param name="count">重复次数,-1表示无限循环</param>
public void Start(int count = 1)
{
_playing = true;
if(count == -1) // 无限循环
{
while(_playing)
{
PlaySong();
}
}
else
{
while (_playing && count > 0)
{
PlaySong();
count--;
}
}
}
/// <summary>
/// 停止播放
/// </summary>
public void Stop() => _playing = false;
public void Dispose()
{
_stream?.Close();
_stream?.Dispose();
_noteplayer?.Dispose();
}
#region 私有方法
private void PlaySong()
{
string line = null;
_stream.Seek(0L, SeekOrigin.Begin);
// 这里一定要让 leaveOpen 参数为 true
// 不然 reader 关闭时会直接把文件给释放
// 后面就不能播放第二遍了
using StreamReader _noteReader = new(_stream, leaveOpen: true);
line = _noteReader.ReadLine();
int freq, dura;
while (_playing && (line is not null))
{
string[] _s = line.Split(' ');
if (!int.TryParse(_s[0].Trim(), out freq))
{
continue;
}
if (!int.TryParse(_s[1].Trim(), out dura))
{
continue;
}
if (freq < 0 || dura < 0)
{
continue;
}
// 播放音符
_noteplayer.PlayNote(freq, dura);
// 播放完读下一个音符
line = _noteReader.ReadLine();
}
}
#endregion
}
打开包含音符频率和时值的文件,一行一行地读。每读出一行,以空格作分隔符拆开字符串——可拆成两个元素的字符串数组。第一个元素为频率,第二个元素为时值,随后用前面封装的 PlayNote 播放。
注意实例化 StreamReader 时,一定要保证它被释放时不要关闭文件,不然打开文件后只能播放一次了,后续的重复播放就会报错。
回到程序的 Main 方法。
class Program
{
// 声明字段
static MusicPlayer ply = null;
static void Main(string[] args)
{
// 当按取消键时清理资源
Console.CancelKeyPress += (_,_) =>
{
ply?.Stop();
ply?.Dispose();
};
ply = new("./test01.txt");
// 尝试通过命令行参数获取播放次数
int count = -1;
if(args is { Length: > 0})
{
string s = args[0];
if(!int.TryParse(s,out count))
{
count = -1;
}
}
Console.WriteLine($"播放{count}次……");
ply.Start(count);
ply.Dispose();
}
}
这里还实现了通过命令行参数来设定循环播放次数,-1为单曲循环。
最后是发布,上传到树莓派。
下面看怎么接线。
一、如果用小喇叭,注意正负极。如下图,左边是负极(接线孔右侧有“-”),右边是正极(接线孔左侧有“+”)。负极接树莓派的 GND(有多个,随便挑一个),正极串联一个大于 100 Ω 的电阻(电阻一定要接,不然会有破音,而且时间长了会烧掉喇叭,阻值 100 - 200 均可,电阻大了声音小一点)后接 GPIO 18,这个你看过上一篇文章就知道了,4B 只有这个引脚能产生第一路 PWM,其他树莓派你可以自己试。
二、使用无源蜂鸣器。这个得看你买的模块是什么样子的,老周买的这个是三个引脚的。
VCC 接树莓派供电脚,3.3V 和 5V 均可,都兼容,放心烧不了,上面有100欧的电阻。
GND 接树莓派 GND。
IO 接树莓派的 GPIO 18。
执行程序,就可以欣赏音乐了。
示例源代码,请点击这里
可以试听一下效果
=====================================================================
补充一下,开发板只能产生方波,不能产生正弦(含余弦)波,更不能产生叠加的交流声波。所以,它只能依据频率来产生不同的音高,你不能控制其音色,更别指望变成自制 Midi。树莓派主板上是有 3.5 mm 音频接口的,要看电影要听歌,跟电脑一样,插个耳机或有源音箱(如低音炮)即可。也可以去买一块专门的功放模块(针对像 Arduino 那样没有音频接口的板子),不用写代码驱动,插上音响就能嗨。当然也有蓝牙功放模块,网购无极限,啥都有可能买到。所以这年头想DIY还是比较容易的。
原文地址:https://www.cnblogs.com/tcjiaan/p/14395271.html
文首发于『阿里云 IoT 开发者社区』,更多精彩物联网内容欢迎前往浏览。
智能家居可谓是今年物联网的热门领域,通过智能单品和智能音箱,人们已然把『智能』两个字变成了生活的理所应当。搭建云上之家除了买买买,还能 DIY。依托阿里云物联网平台,我们用 30 行代码来搞定一套智能家居解决方案。
常见的智能家居解决方案包括了设备端、上云、应用端三大部分,更广的还涉及大数据及人工智能。传统的物联网开发非常强调流程性,即设备端、云、应用端三个步骤需要依次进行。而今天,依托于阿里云物联网平台的『物模型』基础,物联网开发的两端可以齐头并进,节省大量的人力物力成本。
齐头并进显然很诱人,但是能否再更进一步,一人 Handle 全部开发呢?答案是 YES!
目前,有大量互联网开发者由于缺乏嵌入式开发能力,如C/C++语言基础,止步于物联网蓝海的大门。通过阿里云 IoT 提供的 TinyEngine 引擎,可以快速使用 Javascript 进行设备端开发,完美解决这部分开发者的心头大患。而针对不熟悉前后端开发的嵌入式开发者,阿里云物联网平台一样提供了『可视化搭建应用』等快速上手的功能,零代码实现应用开发,大大减轻学习负担。
下面我们就使用阿里云物联网开发平台的 TinyEngine 引擎和可视化搭建功能,30 行代码快速开发一个由灯和温湿度计组成的智能家居系统。
首先,申请阿里云账号,并开通登陆 Link Develop 一站式开发平台:https://linkdevelop.aliyun.com。
之后,新建项目(项目名任意)—— 设备开发 —— 新增产品 —— 所属分类按需选择『灯』或『温湿度计』,通讯方式选择 WiFi ,数据格式选择Alink —— 完成。
完成后选择『设备开发』标签页 —— 新增调试设备,记录下设备三元组。
打开嵌入式 Javascript 在线工作台(没错,开发环境都不用搭建),创建新项目。替换 index.js代码:
1. 灯
var deviceShadow = require('deviceShadow'); var ledHandle = GPIO.open("led1"); deviceShadow.bindDevID({ productKey: "", deviceName: "", deviceSecret: "" }); function main(err){ if(err){ console.log("连接平台失败"); }else{ console.log("主程序开始"); deviceShadow.addDevSetPropertyNotify("LightSwitch", function (lightStatus) { GPIO.write(ledHandle, 1-lightStatus); }); var mainLoop = setInterval(function () { var ledStatus = GPIO.read(ledHandle); deviceShadow.postProperty("LightSwitch", 1-ledStatus); }, 2000); } } deviceShadow.start(main);
2. 温湿度计
var deviceShadow = require('deviceShadow'); var shtc1 = require('shtc1'); var handle = new shtc1('shtc1'); var ledHandle = GPIO.open("led"); deviceShadow.bindDevID({ productKey: "a17vi82MmxP", deviceName: "0001", deviceSecret: "tYUngSMqYeDxODgtX3DNKkQ7920I3t4T" }); function main(err) { if (err) { console.log("连接平台失败"); } else { console.log("主程序开始"); var mainLoop = setInterval(function () { var val = handle.getTempHumi(); console.log('shtc1:temp=' + val[0] + ' humi:' + val[1]); deviceShadow.postProperty("CurrentTemperature", val[0]); deviceShadow.postProperty("RelativeHumidity", val[1]); }, 2000); } } deviceShadow.start(main);
将设备连接至电脑,点击『连接』并『运行』,设备启动后会自动加载并运行index.js这个文件,同时上报数据至阿里云物联网平台。
既然是系统,没有应用可不行,我们利用可视化搭建功能 0 代码快速完成一个应用,只需依次拖入仪表盘和开关组件,替换图片,绑定设备即可完成全部操作。
齐活,短短 30 行代码搭建出的端到端智能家居系统就完成了,保存发布后就可以分享给他人访问了。
配合的 TinyEngine 引擎和可视化搭建,开发者无需学习新的编程语言,即可无缝快速切入物联网开发,也彰显了阿里云物联网平台的包容性和独创性。各位开发者,赶紧丢掉犹豫,上手试试吧!https://linkdevelop.aliyun.com
作者:cxlwill
在的消费市场的在营销的时候都喜欢加上轻度两个字,例如轻度奢华。
其实背后逻辑主要还是,高端奢侈品从火爆到下滑,间接带动更多了更多年轻消费阶层对高品质产品的追求。然而他们手上的钱又买不起高端奢侈品,所以轻度奢侈的概念就是为了契合他们而诞生了。
在电子消费领域同样如此,例如式微已久的家庭影院产品,高端家庭影院因为价格和安装问题没办法刺激年轻群体消费,同时网络下载等渠道又满足了很多低端用户的需要。不过总会有一些人,希望有好一点影音设备,又没办法承担高昂的产品或者有精力去重新布线装修。我将这样的人定义为轻度发烧玩家,因为我就是这类人。
传统意义上,一套家庭影院多则五六千、少则几万几十万都可以,但都有一个问题是安装时难于布线。幸好今年2.4Ghz技术发展得很好,所以无线家庭影院已经不需要上万的价格也能买到。这正好也是我们这种人可负担得起的区间。
使用简介:
而今天有机会提前体验到飞利浦这套CSS5530家庭影院,简直就是为了我们这类年轻用户而推出。在香港官网看到这套设备属于ZENIT的系列,这套音响不再是传统的黝黑的外形,而是改用灰色加上浅色实木装饰的造型,官方称为禅学美感,为的是更好地融合到现代年轻人的家居风格中。
飞利浦CSS5530是一套的5.1声道的家庭影院系统,即包含了四个环绕声道卫星音箱、一个中置音箱以及一个低音炮。在传统的5.1声道家庭影院中,上述几个音箱都需要通过线材直接AV功放连接。而目前主流的无线家庭影院则实现去AV功放化,将解码和功放集成在了中置音箱内。
正如CS5530的中置音箱,除了担当音箱的作用还要承担信号输入和左右卫星音箱输出,以及无线信号传输的作用,可以说是系统核心所在。这个中置音箱背部除了电源、卫星音箱的接线口以外,还有光纤、HDMI输入/输出各一个、以及一个USB接口。另外CSS5530的HDMI接口支持4K信号输出,所以不用担心你的新电视和高清播放器没办法兼容。
中置音箱负责左前右前两个声道的输出,而后方的两个卫星音箱则需要另外一个接线器连接,这个后置接收器大小和机顶盒接近,接上电源和音箱就可以自行配对成功。
卫星音箱底部有一个绕线柱,线缆长度有五米之长,基本满足大多数空间的需要。接上线后,大概就是这个样子了。
CSS5530的低音炮将一颗6.5英寸的喇叭做成下射式,并有一个挡板反射低频,这样能保证在不同的地板材质上都能获得同样的低频扩散效果,避免放在例如地毯上会出现吸音的问题。它的背部没有什么多余接口仅有一个电源插孔,所以只要接上电源就能用,并可以随意摆放在屋内不同的空间。一般我们会放在墙角,或者放在沙发旁边也行。
也就是说,要完成这套家庭影院的安装,你只需要保证在沙发后方有一个插座,以及电视机附近有2个空余的插座就可以了。
影音体验:
CSS5530所附赠的遥控器上布满了按钮,可调节的功能很多,除了切换音源,还可以调节音效模式、高频低频调节、夜间模式以及设置声音延时功能等等。
飞利浦CSS5530支持多个信号源输入,除了通过遥控器,在中置音箱的控制面板也可以切花,在音箱前方会有一组LED显示当前输入状态。
安装完毕我们来试试实际的效果,我们选了一套蓝光光盘作为片源进行测试。包括《谍影重重3》《星球大战外传 侠盗一号》等。
测试时的听感以机器默认状态为准,有额外设置低频和高频的增益的话会另外说明。
我们之前曾经体验过好几款同样使用了无线传输技术的飞利浦家庭影院,包括高端旗舰的Fidelio系列。
而CSS530给我的感受是——作为家庭影院的核心,CSS5530在低频上的表现相当不错,与高端的Fidelio系列相差甚至不会有太大的差异。即便在40平方的客厅,也能塑造不俗的氛围感。低频在爆炸场景或者营造气氛情境中都非常重要。另外,在《谍影重重3》里,被封为经典的打斗镜头中,每一拳都需要低频的衬托才显得到位,这一点CS5530是能做到的。当然我个人是对过量低频比较方案,默的低频量我觉得刚刚够了,如果你客厅隔音不错,又追求更好的效果的话,可以适当把低频增益增加1或者2级。
中置喇叭的人声也是另一个关键,CSS5530的中置喇叭声音以偏薄而亮丽的中频为主,这样才比较好地突出电影中的对白。
而CSS5530的环绕卫星音箱表现中规中矩,他能很好地做好环绕声以及背景声播放的职责。
另外,CS5530支持蓝牙、USB等功能,我们用一台支持APTX的手机连接CSS5530的蓝牙,播放音乐时,CSS5530会变成一个2.1的音响套装。整体上CSS5530的音质让人惊喜,他的中频非常宽松,但又有一定的线条感,听交响乐时,管弦乐声部的分离是不会拥挤在一块的。而听流行乐又有6.5寸低音炮能够满足歌曲节奏的需求。
值得一提的是,如果你家客厅足够大,那么也可以尝试按下遥控器上的Sound按键开启Party模式,该模式下,所有喇叭都会以立体声工作,等于提高了整个空间的聆听体验,保证在个个角落都同样能听到高品质的立体声音乐。
另外,如果你所看的电影或者玩的游戏只支持立体声输出,那么也可以通过开启Movie模式开启CSS530所内置的Dolby Pro Logic II功能,将立体声音源强化为5.1声道输出。
小结:
飞利浦CSS5530的表现实在让人惊喜,毕竟它的官方售价一点都不昂贵,但实际体验中给我带来的感受却可直逼旗舰Fidelio系列。
而它和旗舰之间的差距,更多地体现在功能上例如不支持随需环绕技术和输入接口的减少,以及易用性方面。这也是CSS5530唯一的一个小缺点——后置环绕音响仍然需要一个比较平稳的摆放空间。毕竟卫星音箱体积不算小,我建议还是最好买一个小型的支架来摆放它,才能享受最好的环绕声效果。
*请认真填写需求信息,我们会在24小时内与您取得联系。