【项目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

这段代码的精彩之处就在于可以直观快捷的控制曲目的节拍和节奏,并且可以直接对音调发出的顺序进行编排。中间通过自定义了两个函数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。

大家可以尝试制作一下~

你可能感兴趣的:(【项目6-任务7-小组14】蜂鸣器演奏简单乐曲及简易电子琴制作)