【项目6-任务7-小组14】蜂鸣器演奏简单乐曲及简易电子琴制作

乐谱转化为播放程序的基本方法

我们先来回顾一下七音依次播放的教程,通过设置频率和持续时长来控制蜂鸣器的播放。

//定义音阶常量
      #define Do 262
      #define Re 294
      #define Mi 330
      #define Fa 349
      #define Sol 392
      #define La 440
      #define Si 494
      int buzzerPin=8;      //定义蜂鸣器针脚
      int scale[]={Do,Re,Mi,Fa,Sol,La,Si};  //定义音阶数组

       void setup() {
      pinMode(buzzerPin,OUTPUT);// 设置数字引脚为输出
      }
       void loop() {
      for(int i=0;i<7;i++){// 使用for循环依次播放音阶数组中的元素
      tone(buzzerPin,scale[i],1000);//依次读取音阶数组中的音阶频率,并且每个音阶持续1秒钟
      delay(1000); //等待1000毫秒
      noTone(buzzerPin);  //停止发声
      delay(1000);  //等待1000毫秒
      }

      }

既然我们知道了控制音阶播放的原理,那我们是不是可以尝试用这种原理去进行作曲呢?

//定义音阶常量
      #define Do 262
      #define Re 294
      #define Mi 330
      #define Fa 349
      #define Sol 392
      #define La 440
      #define Si 494
      int buzzerPin=4;      //定义蜂鸣器针脚
      int scale[]={Do,Re,Mi,Do,Do,Re,Mi,Do,Mi,Fa,Sol,Mi,Fa,Sol};  //定义音阶数组

       void setup() {
      pinMode(buzzerPin,OUTPUT);// 设置数字引脚为输出
      }
       void loop() {
      for(int i=0;i<14;i++){// 使用for循环依次播放音阶数组中的元素
      tone(buzzerPin,scale[1],1000);//依次读取音阶数组中的音阶频率,并且每个音阶持续1秒钟
      delay(500); //等待1000毫秒
      tone(buzzerPin,scale[2],1000);
      delay(500); 
      tone(buzzerPin,scale[3],1000);
      delay(500);
      tone(buzzerPin,scale[4],1000);
      delay(500);
      tone(buzzerPin,scale[5],1000);
      delay(500);
      tone(buzzerPin,scale[6],1000);
      delay(500);
      tone(buzzerPin,scale[7],1000);
      delay(500);
      tone(buzzerPin,scale[8],1000);
      delay(500);
      tone(buzzerPin,scale[9],1000);
      delay(500);
      tone(buzzerPin,scale[10],1000);
      delay(500);
      tone(buzzerPin,scale[11],1000);
      delay(500);
      tone(buzzerPin,scale[12],1000);
      delay(500);
      tone(buzzerPin,scale[13],1000);
      delay(500);
      tone(buzzerPin,scale[14],1000);
      delay(500);
      }

      }

通过控制引脚发出的频率和持续长度来转换成音调和节拍,逐个音拼凑成一段乐曲,仅仅两句乐曲就占了如此大的篇幅,这就暴露出了几个问题:

优点:简单易懂

缺点:1.音符间节奏难控制
2.程序冗长编写费力

那我们有什么好的方法来解决呢?

以下代码可以完美的解决这个问题:

int speakerPin = 9;                             //蜂鸣器引脚定义

int length = 15;                                  //曲目长度

char notes[] = "ccggaagffeeddc "; //曲目音阶,最后空格表示结束

int beats[] ={1,1,1,1,1,1,2,1,1,1,1,1,1,2,4 }; //节拍
int tempo = 300;                                              //节奏 
void playTone(int tone ,int duration)
{
  for (long i= 0;i<duration*1000L;i+=tone*2)
  {
    digitalWrite(speakerPin,HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin,LOW);
    delayMicroseconds(tone);
  }
 }

 void playNote(char note,int duration)
 {
  char names[] ={'c','d','e','f','g','a','b','C'};
  int tones[]={1915,1700,1519,1432,1275,1136,1010,956};
  //利用对比位的方式来播放某一个音阶
  for(int i = 0;i<8;i++)
  {
    //将对比得到的音阶高电位时间长度传送给playTone函数播放 
    if(names[i]==note)
    playTone(tones[i],duration);
   }
  }
void setup()
{
  pinMode(speakerPin,OUTPUT); //引脚设定为输出
  }
void loop()
{for (int i =0;i<length;i++)
{
  if(notes[i] == ' ')
   delay (beats[i]*tempo); //rest
   else
   playNote(notes[i],beats[i]*tempo);
   //pause between notes
   delay (tempo/2);
   }
 }      

这段代码的精彩之处就在于可以直观快捷的控制曲目的节拍和节奏,并且可以直接对音调发出的顺序进行编排。中间通过自定义了两个函数playTone()和playNote()对音调和节拍进行了定义,使得后期播放效果非常完美。

1.关于按钮

按钮实体
按钮实体

按钮分为四脚和两脚按钮两种,两脚按钮可以当开关使用,而四脚按钮则是对脚相断,邻脚相通。在制作蜂鸣器电子琴时我们将其作为琴键。

2.蜂鸣器电子琴的制作

fritzing连线图

通过图示我们可以看到,其实蜂鸣器电子琴就是通过七个按钮控制七个引脚的电平变化,使蜂鸣器发声,产生七音。

#include "pitches.h"

void setup(){
  //初始化按钮连接引脚
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  pinMode(6,INPUT);
  pinMode(7,INPUT);
  pinMode(8,INPUT);
  }
void loop (){
  //依次读出各个按钮的状态
  //如果按钮按下,则发出相应的音调
  if(digitalRead(2)) tone(10,NOTE_C5,10); //DO 523Hz
  if(digitalRead(3)) tone(10,NOTE_D5,10);
  if(digitalRead(4)) tone(10,NOTE_E5,10);
  if(digitalRead(5)) tone(10,NOTE_F5,10);
  if(digitalRead(6)) tone(10,NOTE_G5,10);
  if(digitalRead(7)) tone(10,NOTE_A5,10);
  if(digitalRead(8)) tone(10,NOTE_B5,10);
  }

通过代码我们就可以很直观的了解电子琴的工作原理了,本代码引用了pitches.h。

大家可以尝试制作一下~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • 推荐学习资料: 官网参考资料 https://www.arduino.cc/reference/en/ Ardui...
    SunShineJia阅读 4,663评论 0 11
  • 一、背景 智能家居行业经过了十几年的发展,就现在而言,还称得上是方兴未艾。在互联网巨头的介入下后得到快速提升,智能...
    破碎的時光阅读 4,259评论 5 34
  • 本篇介绍电子产品中的发声器件—蜂鸣器,通过控制蜂鸣器播放「葫芦娃」,带你回归美好童年。 1. 了解蜂鸣器 蜂鸣器是...
    TonyCode阅读 7,053评论 4 11
  • 早,牛奶一杯,鲜虾两枚,蛋蛋一个,面包两小片,青瓜小番茄搭配 减肥餐第四天,逐渐得心应手,喜欢各式水果、蔬菜搭配出...
    静鱼阅读 209评论 0 0
  • 今天是日更签到的第八十二天的日更签到。无奈的日更签到,没有了啦?我得睡了,哦!你好!我也是醉了!你是谁的说说?好吧...
    大自然无语阅读 409评论 0 0