极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 110964|回复: 141

Arduino学习心得-简单制作各种歌曲

  [复制链接]
发表于 2011-12-6 18:16:17 | 显示全部楼层 |阅读模式
Arduino学习笔记—超简单制作音乐
一曲葫芦娃 带你回归美好童年
本文是个人学习心得,供新人参考,老鸟可瞬间飘过。
本文很简单,需要用到的材料:adruino uno一块(其他也可),面保线若干条,蜂鸣器或小喇叭一个(小喇叭更好蜂鸣器要接电阻不然声音有点刺耳)

连接方法如图:
QQ截图20111206173205.png

首先讲下简单的乐理知识,知道音乐是怎么演奏出来的自然就可以通过代码来进行编排了。
1.演奏单音符  一首乐曲有若干音符组成,一个音符对应一个频率。我们知道到相对应的频率 让arduino输出到蜂鸣器 蜂鸣器就会放出相应的声音,这里有个表供大家参考:
2.PNG
2.音符的演奏时间  我们知道了音符是如何演奏出来的,下一步就是控制音符的演奏时间。每个音符都会播放一定的时间,这样才能构成一首优美的曲子,而不是生硬的一个调的把所有的音符一股脑的都播放出来。如何确定每个音符演奏的单位时间呢?
我们知道,音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,所以我们可以为每个音符赋予这样的拍子播放出来,音乐就成了。
好了 我们看看如何将简谱翻译成对应频率和拍子。
以葫芦娃为例:
1.PNG

先看下左上角1=D这里,用的是D调,好那我们就看《音符频率表》中的D行(红色部分)

第一个音符是1 但上面有个点,所以对应的就是589,时间是一拍=1,
第二个音符6(没有点)就是495,时间也是一拍=1,
第三个音符5 即441,因为有下划线所以是半拍=0.5,
……以此类推
第四0这里要注意下,这里是没有声音,但是要是用频率0表示还是会有声音(这个不懂),所以我们用一个很高频率的声音,这样人耳听不到就达到了没有声音的效果,所以频率为-1。拍子=1拍
第五,再接着看到第一句歌词葫芦娃 这个娃的音是3—,这表示是两拍,后面每加一个“-”,表示拍子+1(1+1),本例中最多是加到4.
第六,第二句歌词葫芦娃这个娃,3•带个点,点的意思是去3的拍子的一半,即3•的拍子是1+0.5
第七,大家可能会问那弧线怎么表示,这在音乐中属于连音,我们要表示的话,可以稍微改下连音后面那个音的频率,比如减少或增加一些数值(需自己调试),这样表现会更流畅,但操作上更复杂了,本例没有做连音的处理,大家有兴趣可以自己调整下。
所以说了一大堆,规律就是时间上单个音符没有下划线,就是一拍(1),有下划线是半拍(0.5),两个下划线是四分之一拍(0.25),有“—”=前面音符的拍子+1;频率上就是按照音符是否带点,点在上还是在下到表中查找就可以了。
至此原理清楚,随便拿个简谱来我们都可以翻译成代码了。

好,下面进入代码部分,来看下这首《葫芦娃》的代码:
  1. #define NOTE_D0 -1
  2. #define NOTE_D1 294
  3. #define NOTE_D2 330
  4. #define NOTE_D3 350
  5. #define NOTE_D4 393
  6. #define NOTE_D5 441
  7. #define NOTE_D6 495
  8. #define NOTE_D7 556

  9. #define NOTE_DL1 147
  10. #define NOTE_DL2 165
  11. #define NOTE_DL3 175
  12. #define NOTE_DL4 196
  13. #define NOTE_DL5 221
  14. #define NOTE_DL6 248
  15. #define NOTE_DL7 278

  16. #define NOTE_DH1 589
  17. #define NOTE_DH2 661
  18. #define NOTE_DH3 700
  19. #define NOTE_DH4 786
  20. #define NOTE_DH5 882
  21. #define NOTE_DH6 990
  22. #define NOTE_DH7 112
  23. //以上部分是定义是把每个音符和频率值对应起来,其实不用打这么多,但是都打上了,后面可以随意编写D调的各种歌,我这里用NOTE_D+数字表示音符,NOTE_DH+数字表示上面有点的那种音符,NOTE_DL+数字表示下面有点的那种音符。这样后面写起来比较好识别。
  24. #define WHOLE 1
  25. #define HALF 0.5
  26. #define QUARTER 0.25
  27. #define EIGHTH 0.25
  28. #define SIXTEENTH 0.625
  29. //这部分是用英文对应了拍子,这样后面也比较好看
  30. int tune[] =
  31. {
  32.   NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,
  33.   NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_DH1,NOTE_D6,NOTE_D0,NOTE_D6,
  34.   NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D6,
  35.   NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_DH1,NOTE_D6,NOTE_D0,
  36.   
  37.   NOTE_D1,NOTE_D1,NOTE_D3,
  38.   NOTE_D1,NOTE_D1,NOTE_D3,NOTE_D0,
  39.   NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,
  40.   NOTE_D5,NOTE_D1,NOTE_D3,NOTE_D0,
  41.   NOTE_DH1,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,
  42.   NOTE_D5,NOTE_D1,NOTE_D2,NOTE_D0,
  43.   NOTE_D7,NOTE_D7,NOTE_D5,NOTE_D3,
  44.   NOTE_D5,
  45.   NOTE_DH1,NOTE_D0,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D5,NOTE_D6,NOTE_D6,
  46.   NOTE_D0,NOTE_D5,NOTE_D1,NOTE_D3,NOTE_D0,
  47.   NOTE_DH1,NOTE_D0,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D5,NOTE_D6,NOTE_D6,
  48.   NOTE_D0,NOTE_D5,NOTE_D1,NOTE_D2,NOTE_D0,
  49.   NOTE_D3,NOTE_D3,NOTE_D1,NOTE_DL6,
  50.   NOTE_D1,
  51.   NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,
  52.   NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,
  53.   NOTE_DH1,NOTE_D0,NOTE_D7,NOTE_D5,
  54.   NOTE_D6,
  55. };//这部分就是整首曲子的音符部分,用了一个序列定义为tune,整数

  56. float duration[]=
  57. {
  58.   1,1,0.5,0.5,1,
  59.   0.5,0.5,0.5,0.5,1,0.5,0.5,
  60.   0.5,1,0.5,1,0.5,0.5,
  61.   0.5,0.5,0.5,0.5,1,1,
  62.   
  63.   1,1,1+1,
  64.   0.5,1,1+0.5,1,
  65.   1,1,0.5,0.5,1,
  66.   0.5,1,1+0.5,1,
  67.   0.5,0.5,0.5,0.5,1+1,
  68.   0.5,1,1+0.5,1,
  69.   1+1,0.5,0.5,1,
  70.   1+1+1+1,
  71.   0.5,0.5,0.5+0.25,0.25,0.5+0.25,0.25,0.5+0.25,0.25,
  72.   0.5,1,0.5,1,1,
  73.   0.5,0.5,0.5+0.25,0.25,0.5+0.25,0.25,0.5+0.25,0.25,
  74.   0.5,1,0.5,1,1,
  75.   1+1,0.5,0.5,1,
  76.   1+1+1+1,
  77.   0.5,1,0.5,1+1,
  78.   0.5,1,0.5,1+1,
  79.   1+1,0.5,0.5,1,
  80.   1+1+1+1
  81. };//这部分是整首曲子的接拍部分,也定义个序列duration,浮点(数组的个数和前面音符的个数是一样的,一一对应么)
  82. int length;//这里定义一个变量,后面用来表示共有多少个音符
  83. int tonePin=5;//蜂鸣器的pin

  84. void setup()
  85. {
  86.   pinMode(tonePin,OUTPUT);//设置蜂鸣器的pin为输出模式
  87.   length = sizeof(tune)/sizeof(tune[0]);//这里用了一个sizeof函数,可以查出tone序列里有多少个音符
  88. }

  89. void loop()
  90. {
  91.   for(int x=0;x<length;x++)//循环音符的次数
  92.   {
  93.     tone(tonePin,tune[x]);//此函数依次播放tune序列里的数组,即每个音符
  94.     delay(400*duration[x]);//每个音符持续的时间,即节拍duration,400是调整时间的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
  95.     noTone(tonePin);//停止当前音符,进入下一音符
  96.   }
  97.   delay(5000);//等待5秒后,循环重新开始
  98. }
复制代码
上传下看看效果吧
NOTE_D3 这个音我试了好多次 没调准不知为何,按表上的貌似不太好听


本人愚钝,领悟至此,颇有感慨,与君共勉,陋文浅显,还望海涵。
回复

使用道具 举报

发表于 2013-5-10 16:23:06 | 显示全部楼层
我也上传一首我翻译的歌曲,《琵琶语》,大家可以下下来听听看,曲子有点小复杂,呵呵。
#define NOTE_D0 -1
#define NOTE_D1 330
#define NOTE_D2 350
#define NOTE_D3 393
#define NOTE_D4 441
#define NOTE_D5 495
#define NOTE_D6 556
#define NOTE_D7 624

#define NOTE_DL1 165
#define NOTE_DL2 175
#define NOTE_DL3 196
#define NOTE_DL4 221
#define NOTE_DL5 248
#define NOTE_DL6 278
#define NOTE_DL7 312

#define NOTE_DH2 661
#define NOTE_DH3 700
#define NOTE_DH4 786
#define NOTE_DH5 882
#define NOTE_DH6 990
#define NOTE_DH7 1112
#define NOTE_DH1 1248
//以上部分是定义是把E调每个音符和频率值对应起来后面可以随意编写E调的各种歌,用NOTE_D+数字表示音符,NOTE_DH+数字表示上面有点的那种音符,NOTE_DL+数字表示下面有点的那种音符。
#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
//这部分是用英文对应了拍子,这样后面也比较好看
int tune[] =
{
  NOTE_DL6,NOTE_D3,NOTE_DH1,NOTE_DL6,NOTE_D2,NOTE_D7,
  NOTE_DL6,NOTE_D3,NOTE_DH1,NOTE_DL6,NOTE_D2,NOTE_D7,
  NOTE_D1,NOTE_DL7,
  NOTE_D1,NOTE_DL7,
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_D6,NOTE_D5,//1
  
  NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D5,NOTE_D3,
  NOTE_D2,NOTE_D3,NOTE_D1,NOTE_DL7,NOTE_D1,NOTE_DL7,NOTE_DL5,
  NOTE_DL6,NOTE_D3,NOTE_D5,
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_D6,NOTE_D5,//2
  
  NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D5,NOTE_D3,
  NOTE_D2,NOTE_D3,NOTE_D1,NOTE_DL7,NOTE_D1,NOTE_DL7,NOTE_DL5,
  NOTE_DL6,
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_D6,NOTE_D5,
  NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D3,NOTE_D5,//3
  
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_DH2,NOTE_D5,
  NOTE_DH2,NOTE_DH3,NOTE_DH3,NOTE_D0,NOTE_D5,NOTE_DH1,NOTE_DH3,
  NOTE_DH2,NOTE_DH3,NOTE_D6,NOTE_DH2,NOTE_DH3,NOTE_D6,
  NOTE_D4,NOTE_D5,NOTE_D6,NOTE_DH1,NOTE_D7,NOTE_D6,NOTE_D3,NOTE_DH3,
  NOTE_DH2,NOTE_DH3,NOTE_D6,NOTE_DH2,NOTE_DH3,NOTE_D6,//4
  
  NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_DH2,NOTE_D7,NOTE_D5,NOTE_D6,
  NOTE_DL7,
  NOTE_D1,NOTE_DL7,
  NOTE_DH3,NOTE_DH3,NOTE_DH2,
  NOTE_DH3,NOTE_DH3,NOTE_DH6,
  NOTE_DH2,NOTE_DH1,NOTE_D7,NOTE_D5,
  NOTE_D6,NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_DH2,//5
  
  NOTE_DH3,NOTE_DH3,NOTE_DH2,
  NOTE_DH3,NOTE_DH3,NOTE_DH6,
  NOTE_DH2,NOTE_DH1,NOTE_D7,NOTE_D5,
  NOTE_D6,
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_D6,NOTE_D5,
  NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D3,NOTE_D5,//6
  
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_DH2,NOTE_D5,
  NOTE_DH2,NOTE_DH3,NOTE_DH3,NOTE_D0,NOTE_D5,NOTE_DH1,NOTE_DH3,
  NOTE_DH2,NOTE_DH3,NOTE_D6,NOTE_DH2,NOTE_DH3,NOTE_D6,
  NOTE_D4,NOTE_D5,NOTE_D6,NOTE_DH1,NOTE_D7,NOTE_D6,NOTE_D3,NOTE_DH3,
  NOTE_DH2,NOTE_DH3,NOTE_D6,NOTE_DH2,NOTE_DH3,NOTE_D6,//7
  
  NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_DH2,NOTE_D7,NOTE_D5,NOTE_D6,
  NOTE_DH3,NOTE_DH2,
  NOTE_DH3,NOTE_D3,NOTE_D5,
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_D6,NOTE_D5,
  NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D5,NOTE_D3,//8
  
  NOTE_D2,NOTE_D3,NOTE_D1,NOTE_DL7,NOTE_D1,NOTE_DL7,NOTE_DL5,
  NOTE_DL6,NOTE_D3,NOTE_D5,
  NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D5,NOTE_D6,NOTE_D7,NOTE_D6,NOTE_D5,
  NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D5,NOTE_D3,//9
  
  NOTE_D2,NOTE_D3,NOTE_D1,NOTE_DL7,NOTE_D1,NOTE_DL7,NOTE_DL5,
  NOTE_DL6,
  NOTE_DL6,NOTE_D3,NOTE_DH1,NOTE_DL6,NOTE_D2,NOTE_D7,NOTE_D2,NOTE_D3,NOTE_D5,NOTE_D3,
  NOTE_D2,NOTE_D3,NOTE_D1,NOTE_DL7,NOTE_D1,NOTE_DL7,NOTE_DL5,
  NOTE_DL6,//10
};//这部分就是整首曲子的音符部分,用了一个序列定义为tune,整数

float duration[]=
{
  0.125,0.125,0.75,0.125,0.125,0.75,
  0.125,0.125,0.75,0.125,0.125,0.75,
  1,1,
  1,1,
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,//1
  
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  1.5,0.25,0.25,
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,//2
  
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  2,
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.25,0.25,//3
  
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,
  0.375,0.125,0.5,0.25,0.25,0.25,0.25,
  0.375,0.125,0.5,0.375,0.125,0.5,
  0.125,0.125,0.125,0.125,0.25,0.25,0.75,0.25,
  0.375,0.125,0.5,0.375,0.125,0.5,//4
  
  0.125,0.125,0.125,0.125,0.25,0.25,1,
  2,
  1,1,
  1,0.5,0.5,
  1,0.5,0.5,
  0.5,0.5,0.5,0.5,
  1,0.25,0.25,0.25,0.25,//5
  
  1,0.5,0.5,
  1,0.5,0.5,
  0.5,0.5,0.5,0.5,
  2,
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.25,0.25,//6
  
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,
  0.375,0.125,0.5,0.25,0.25,0.25,0.25,
  0.375,0.125,0.5,0.375,0.125,0.5,
  0.125,0.125,0.125,0.125,0.25,0.25,0.75,0.25,
  0.375,0.125,0.5,0.375,0.125,0.5,//7
  
  0.125,0.125,0.125,0.125,0.25,0.25,1,
  1,1,
  1.5,0.25,0.25,
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.125,0.125,0.125,0.125,//8
  
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  1.5,0.25,0.25,
  0.375,0.125,0.75,0.125,0.125,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.125,0.125,0.125,0.125,//9
  
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  2,
  0.125,0.125,0.75,0.125,0.125,0.25,0.125,0.125,0.125,0.125,
  0.375,0.125,1,0.125,0.125,0.125,0.125,
  2,//10
};//这部分是整首曲子的接拍部分,也定义个序列duration,浮点(数组的个数和前面音符的个数是一样的,一一对应么)

int length;//这里定义一个变量,后面用来表示共有多少个音符
int tonePin=5;//蜂鸣器的pin

void setup()
{
  pinMode(tonePin,OUTPUT);//设置蜂鸣器的pin为输出模式
  length = sizeof(tune)/sizeof(tune[0]);//这里用了一个sizeof函数,可以查出tone序列里有多少个音符
}

void loop()
{
  for(int x=0;x<length;x++)//循环音符的次数
  {
    tone(tonePin,tune[x]);//此函数依次播放tune序列里的数组,即每个音符
    delay(1150*duration[x]);//每个音符持续的时间,即节拍duration,1150是调整时间的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
    noTone(tonePin);//停止当前音符,进入下一音符
  }
  delay(5000);//等待5秒后,循环重新开始
}
回复 支持 4 反对 0

使用道具 举报

发表于 2015-8-29 14:11:59 | 显示全部楼层
最近在做语音控制的   想要把蜂鸣器鸣响加入到语音控制中   如下代码,我想知道如何将蜂鸣器播放音乐的程序嵌入到我原本的程序中  下面的是我自己嵌入的   报错了很多   希望有哪位大侠可以帮忙解决一下   万分感谢


/*
识别关键词的个数为SUM;
n为数组中对应关键词的序列号,例如数组sRecog中的第一个关键词为“kai deng”则对应的序列号为0;
Voice.Initialise();初始化设置输入方式MIC/MONO。
数字口0,1,2,4,7,9,10,11,12,13已被占用,继电器可用的有3,5,6,8.
*/
//#include <TimerOne.h>  //定时器
#include <avr/wdt.h>  //包含看门狗头文件
#include <Voice.h>    //申明语音识别库文件
//#include <Syn6288.h>  //语音合成库文件
#include <dht11.h>    //温湿度传感器库

dht11 DHT;
Syn6288 syn;
uint8  nAsrStatus=0;  //申明语音模块工作状态
#define SUM 13

#define DHT11_PIN A0  //定义温湿度传感器模拟口A0
#define light_sensor_pin A2//定义光线传感器模拟口A2
#define light_threshold 200//定义光照度阈值200
#define gas_sensor_pin A1   //定义气体传感器模拟口A1
#define gas_threshold 700   //气体传感器阈值700
#define relay_1 8    //定义继电器数字口8
#define relay_2 3
#define state_led 7 //状态指示灯数字口7

#define tonePin 6
#define NOTE_G0 -1
#define NOTE_G1 393
#define NOTE_G2 441
#define NOTE_G3 495
#define NOTE_G4 556
#define NOTE_G5 624
#define NOTE_G6 661
#define NOTE_G7 742

#define NOTE_GL1 196
#define NOTE_GL2 221
#define NOTE_GL3 234
#define NOTE_GL4 262
#define NOTE_GL5 294
#define NOTE_GL6 330
#define NOTE_GL7 371

#define NOTE_GH1 786
#define NOTE_GH2 882
#define NOTE_GH3 990
#define NOTE_GH4 1049
#define NOTE_GH5 1178
#define NOTE_GH6 1322
#define NOTE_GH7 1484
//以上部分是定义是把每个音符和频率值对应起来,其实不用打这么多,但是都打上了,后面可以随意编写D调的各种歌,我这里用NOTE_D+数字表示音符,NOTE_DH+数字表示上面有点的那种音符,NOTE_DL+数字表示下面有点的那种音符。这样后面写起来比较好识别。
#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
//这部分是用英文对应了拍子,这样后面也比较好看



int tune[]=
{
  NOTE_G6,NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G5,NOTE_G6,
  NOTE_G3,NOTE_G6,NOTE_G5,
  NOTE_G6,NOTE_GH1,NOTE_G7,NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G7,
  NOTE_GH1,NOTE_GH1,NOTE_GH2,
  NOTE_GH3,NOTE_GH3,NOTE_GH3,NOTE_GH3,NOTE_GH2,
  NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G7,NOTE_G5,
  NOTE_G6,NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G5,
  NOTE_G6,NOTE_G0,
  NOTE_G0,NOTE_G0,NOTE_G0,NOTE_G0,

};//这部分就是整首曲子的音符部分,用了一个序列定义为tune,整数
float duration[]=
{
  1+0.5,0.5+0.5,0.5,0.5,0.5,0.5,
  1+1+1,0.5,0.5,
  1+0.5,0.5,0.5,0.25,0.25,0.5,0.5,
  1+1+1,0.5,0.5,
  0.5,0.5,0.5,0.5,1+1,
  0.5,0.5,0.5,0.5,1+1,
  1,1,1,0.5,0.5,
  1+1+1,1,
  1,1,1,1,

};//这部分是整首曲子的接拍部分,也定义个序列duration,浮点(数组的个数和前面音符的个数是一样的,一一对应么)
int length;//这里定义一个变量,后面用来表示共有多少个音符
int tonePin=6;//蜂鸣器的pin


//void loop()
//{
//  for(int x=0;x<length;x++)//循环音符的次数
//  {
//    tone(tonePin,tune[x]);//此函数依次播放tune序列里的数组,即每个音符
//    delay(800*duration[x]);//每个音符持续的时间,即节拍duration,400是调整时间的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
//    noTone(tonePin);//停止当前音符,进入下一音符
//  }
//  delay(5000);//等待5秒后,循环重新开始
//}
char sRecog[SUM][30] = {"xiao hei","xian zai wen du zen me yang","kai deng","guan deng","xu yao kai deng ma","da kai feng shan","guan bi feng shan","wo xiang ting ge""xiao","hei","wen du","kai","guan"};
//小hei,现在温度怎么样,开灯,关灯,需要开灯吗

uint8_t text1[]={0xC1,0xE3,0xD2,0xBB,0xB6,0xFE,0xC8,0xFD,0xCB,0xC4,0xCE,0xE5,0xC1,0xF9,0xC6,0xDF,0xB0,0xCB,0xBE,0xC5,0xCA,0xAE};//零一二三四五六七八九十
uint8_t text2[]={0xD4,0xDA };// zai!
uint8_t text3[]={0xB5,0xB1,0xC7,0xB0,0xCE,0xC2,0xB6,0xC8,0xCE,0xAA};//当前温度为
uint8_t text4[]={0xCA,0xAA,0xB6,0xC8,0xCE,0xAA,0xB0,0xD9,0xB7,0xD6,0xD6,0xAE};//湿度为百分之
uint8_t text5[]={0xC9,0xE3,0xCA,0xCF,0xB6,0xC8};//摄氏度
uint8_t text6[]="soundn";//报警音
uint8_t text7[]={0xC7,0xEB,0xD7,0xA2,0xD2,0xE2,0xA3,0xAC,0xD3,0xD0,0xCE,0xA3,0xCF,0xD5,0xC6,0xF8,0xCC,0xE5,0xD0,0xB9,0xC2,0xA9};//请注意,有危险气体泄漏
uint8_t text8[]={0xD5,0xFD,0xD4,0xDA,0xBF,0xAA,0xB5,0xC6};//正在开灯
uint8_t text9[]={0xD5,0xFD,0xD4,0xDA,0xB9,0xD8,0xB5,0xC6};//正在关灯
uint8_t text10[]={0xCE,0xD2,0xC3,0xBB, 0xCC, 0xFD, 0xC7, 0xE5, 0xA3, 0xAC, 0xD4, 0xD9, 0xCB, 0xB5,0xD2, 0xBB, 0xB1, 0xE9, 0xBF, 0xC9, 0xD2, 0xD4, 0xC2, 0xEF, 0xA3, 0xBF };//womeitingqing
uint8_t text11[]={0xB9,0xE2,0xCF,0xDF,0xB2,0xBB,0xD7,0xE3,0x20,0xA3,0xAC,0xD5,0xFD,0xD4,0xDA,0xBF,0xAA,0xB5,0xC6};//光线不足,正在开灯
uint8_t text12[]={0xCF,0xD6,0xD4,0xDA,0xB9,0xE2,0xCF,0xDF,0xC3,0xF7,0xC1,0xC1,0xA3,0xAC,0xB2,0xBB,0xD0,0xE8,0xD2,0xAA,0xBF,0xAA,0xB5,0xC6};//光线明亮,不需要开灯
uint8_t text13[]={0xB7,0xE7,0xC9,0xC8,0xB4,0xF2,0xBF,0xAA};// 风扇打开!
uint8_t text14[]={0xB7,0xE7,0xC9,0xC8,0xB9,0xD8,0xB1,0xD5};//风扇关闭!
uint8_t text15[]={0xD2,0xF4,0xC0,0xD6,0xB4,0xF2,0xBF,0xAA};
uint8_t text[2];
uint8_t flag;        //标志位,收到小口令后将置为1,动作执行完后清零

void finally(uint8_t n)        //n为sRecog数组中对应关键词的序列号
{
        switch(n)
        {
        case 0: syn.play(text2,sizeof(text2),0);flag=1;break;        // 在!
        case 1:                                //现在温度怎么样
             if(flag==1)        //收到小米渣的出发命令后
             {
                                        flag=0;
                                        DHT.read(DHT11_PIN);        //读取温度
                                        /*Serial.print("Temperature:");
                                        Serial.print(DHT.temperature);
                                        Serial.print("   humidity:");
                                        Serial.println(DHT.humidity);*/
                                        uint8_t pig1 = DHT.temperature/10;        //温度数值十位
                                        uint8_t pig2 = DHT.temperature%10;        //温度数值个位
                                        uint8_t pig3 = DHT.humidity/10;                //湿度数值十位
                                        uint8_t pig4 = DHT.humidity%10;                //湿度数值个位
                                        syn.play(text3,sizeof(text3),0);         //当前温度为                 
                                        if(pig1>0){
                                        text[0]=text1[pig1*2];
                                        text[1]=text1[pig1*2+1];
                                        syn.play(text,sizeof(text),0);                 //播放温度数值十位
                                        text[0]=text1[20];
                                        text[1]=text1[21];
                                        syn.play(text,sizeof(text),0);                 //播放语音十
                                        }
                                        if(pig2>0){
                                        text[0]=text1[pig2*2];
                                        text[1]=text1[pig2*2+1];
                                        syn.play(text,sizeof(text),0);                 //播放温度数值个位       
                                        }                                       
                                        syn.play(text5,sizeof(text5),0);         //播放摄氏度
                                        syn.play(text4,sizeof(text4),0);         //播放湿度为百分之
                                       
                                        if(pig3>0){
                                        text[0]=text1[pig3*2];
                                        text[1]=text1[pig3*2+1];
                                        syn.play(text,sizeof(text),0);         //播放湿度数值十位
                                        text[0]=text1[20];
                                        text[1]=text1[21];
                                        syn.play(text,sizeof(text),0); //播放语音十
                                        }
                                        if(pig4>0){
                                        text[0]=text1[pig4*2];
                                        text[1]=text1[pig4*2+1];
                                        syn.play(text,sizeof(text),0);         //播放湿度数值个位       
                                        }                                       
             }
                        break;
        case 2:        //开灯
             if(flag==1)
             {
               syn.play(text8,sizeof(text8),0); //播放正在开灯
               digitalWrite(relay_1,HIGH);        //高电平驱动
               flag=0;  
             }
                        break;       
        case 3:        //关灯
                   if(flag==1)
                   {
                                syn.play(text9,sizeof(text9),0); //播放正在关灯
                                digitalWrite(relay_1,LOW);
                                flag=0;
                        }
                        break;
        case 4:        //需要开灯吗?
                        if(flag==1)
                         {
                                int shine=analogRead(light_sensor_pin);        //读取光照度模拟量
                                //Serial.print("Light:");
                                //Serial.println(shine);
                                if(shine < light_threshold)        //小于光照度阀值时
                                {
                                        syn.play(text11,sizeof(text11),0); //光线不足,正在开灯
                                        digitalWrite(relay_1,HIGH);
                                }
                                else
                                {
                                        syn.play(text12,sizeof(text12),0); //光线明亮,不需要开灯
                                        digitalWrite(relay_1,LOW);
                                }
                                flag=0;
                         }
            break;
        case 5://开风扇
                    if(flag==1)
                     {
                                syn.play(text13,sizeof(text13),0); //播放风扇打开
                                digitalWrite(relay_2,HIGH);
                                flag=0;
                        }
                        break;
         case 6://关闭风扇
                    if(flag==1)
                     {
                               syn.play(text14,sizeof(text14),0);//播放风扇关闭
                                digitalWrite(relay_2,LOW);
                                flag=0;
                        }
                        break;
         case 7://音乐打开
                     if(flag==1)
                     {
                               syn.play(text15,sizeof(text15),0);//播放音乐打开
                                digitalWrite(tonePin,HIGH);
                                flag=0;
                        }
                        break;
                default:syn.play(text10,sizeof(text10),0);break;  //非正常命令   
        }
}

void ExtInt0Handler ()
{
  Voice.ProcessInt0();        //芯片送出中断信号
                               
}
void timerIsr()
{
  wdt_reset();
}
void setup()
{
  Serial.begin(9600);
  Voice.Initialise(MIC,VoiceRecognitionV1);//Initialise mode MIC or MONO,default is MIC
                                           //VoiceRecognitionV1 is VoiceRecognitionV1.0 shield
                                           //VoiceRecognitionV2 is VoiceRecognitionV2.1 module  
  attachInterrupt(0,ExtInt0Handler,LOW);

  pinMode(relay_1,OUTPUT);
  digitalWrite(relay_1,LOW);
  pinMode(state_led,OUTPUT);
  digitalWrite(state_led,LOW);
  Timer1.initialize(90000);      //z每隔0.09s执行一次此函数
  Timer1.attachInterrupt(timerIsr); //执行中断服务程序
  wdt_enable(WDTO_120MS);//WatchDog使能
  
  pinMode(tonePin,OUTPUT);//设置蜂鸣器的pin为输出模式
  length = sizeof(tune)/sizeof(tune[0]);//这里用了一个sizeof函数,可以查出tone序列里有多少个音符
}
void loop()
{  
    static uint8_t nAsrRes=0;//声明语音模块工作状态
    static unsigned long time = millis();
        if(millis()-time>100)
        {  
       int gas=analogRead(gas_sensor_pin);
       if(gas > gas_threshold)
       {
                        syn.play(text6,sizeof(text6),0);
                        syn.play(text7,sizeof(text7),0);
       }
                switch(nAsrStatus)
                {
                        case LD_ASR_RUNING:
                        case LD_ASR_ERROR:break;
                        case LD_ASR_NONE:
                        {
                                nAsrStatus=LD_ASR_RUNING;
                if (Voice.RunASR(SUM,30,sRecog)==0) //识别不正确
                                {
                                        nAsrStatus= LD_ASR_ERROR;
                    Serial.println( "ASR_ERROR");
                                }

                Serial.println( "ASR_RUNING.....");
                                digitalWrite(state_led,HIGH);
                                break;
                        }
                        case LD_ASR_FOUNDOK:
                        {
                                digitalWrite(state_led,LOW);
                                nAsrRes =Voice. LD_GetResult();//        一次ASR识别流程结束,去取ASR识别结果                   
                finally(nAsrRes);
                                nAsrStatus = LD_ASR_NONE;
                                break;
                        }
                        case LD_ASR_FOUNDZERO:
                        default:
                        {       
                                digitalWrite(state_led,LOW);
                                nAsrStatus = LD_ASR_NONE;
                                break;
                        }
            }// switch

        }//if
}
回复 支持 2 反对 0

使用道具 举报

发表于 2013-4-24 16:44:18 | 显示全部楼层
#define NOTE_B0 -1
#define NOTE_B1 495
#define NOTE_B2 556
#define NOTE_B3 624
#define NOTE_B4 661
#define NOTE_B5 742
#define NOTE_B6 833
#define NOTE_B7 935

#define NOTE_BL1 248
#define NOTE_BL2 278
#define NOTE_BL3 294
#define NOTE_BL4 330
#define NOTE_BL5 371
#define NOTE_BL6 416
#define NOTE_BL7 467


//以上部分是定义是把每个音符和频率值对应起来,其实不用打这么多,但是都打上了,后面可以随意编写D调的各种歌,我这里用NOTE_D+数字表示音符,NOTE_DH+数字表示上面有点的那种音符,NOTE_DL+数字表示下面有点的那种音符。这样后面写起来比较好识别。
#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
//这部分是用英文对应了拍子,这样后面也比较好看
int tune[] =
{
  NOTE_B5,NOTE_B4,NOTE_B3,NOTE_B3,NOTE_B5,
  NOTE_B5,NOTE_BL6,NOTE_BL6,
  NOTE_B5,NOTE_B4,NOTE_B3,NOTE_B3,NOTE_B5,
  NOTE_B5, NOTE_BL5, NOTE_BL5,
  NOTE_B5,NOTE_B4,NOTE_B3,NOTE_B3,NOTE_B5,
  NOTE_B0,NOTE_BL6,NOTE_BL7,NOTE_B1,
  NOTE_B1,NOTE_B1,NOTE_B2,NOTE_B2,NOTE_B1,
  NOTE_B2,NOTE_B3,NOTE_B3,NOTE_B3,
  NOTE_B5,NOTE_B4,NOTE_B3,NOTE_B3,NOTE_B5,
  NOTE_B5,NOTE_BL6,NOTE_BL6,
  NOTE_B5,NOTE_B4,NOTE_B3,NOTE_B3,NOTE_B5,
  NOTE_B7,NOTE_B5,NOTE_B5,NOTE_B5,NOTE_B2,NOTE_B1,
  NOTE_B1,NOTE_B3,NOTE_B4,
  NOTE_B5,NOTE_B4,NOTE_B3,NOTE_B2,NOTE_B1,
  NOTE_B1,NOTE_BL7,NOTE_B1,



};//这部分就是整首曲子的音符部分,用了一个序列定义为tune,整数

float duration[]=
{
  0.5,0.25,0.25,0.5,0.5,
  0.25,0.5,1,
  0.5,0.25,0.25,0.5,0.5,
  0.25,0.5,1,


  0.5,0.25,0.25,0.5,0.5,
  0.5,0.5,0.5,0.5,
  0.5,0.25,0.25,0.5,0.5,
  0.5,0.25,0.25,1,

  0.5,0.25,0.25,0.5,0.5,
  0.25,0.5,1,
  0.5,0.25,0.25,0.5,0.5,
  0.5,0.25,0.25,0.25,0.5,0.25,

  1,0.5,0.5,0.5,0.5,0.5,0.25,0.25,
  1,1,0.5
};//这部分是整首曲子的接拍部分,也定义个序列duration,浮点(数组的个数和前面音符的个数是一样的,一一对应么)
int length;//这里定义一个变量,后面用来表示共有多少个音符
int tonePin=5;//蜂鸣器的pin

void setup()
{
  pinMode(tonePin,OUTPUT);//设置蜂鸣器的pin为输出模式
  length = sizeof(tune)/sizeof(tune[0]);//这里用了一个sizeof函数,可以查出tone序列里有多少个音符
}

void loop()
{
  for(int x=0;x<length;x++)//循环音符的次数
  {
    tone(tonePin,tune[x]);//此函数依次播放tune序列里的数组,即每个音符
    delay(1000*duration[x]);//每个音符持续的时间,即节拍duration,400是调整时间的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
    noTone(tonePin);//停止当前音符,进入下一音符
  }
  delay(5000);//等待5秒后,循环重新开始
}


林宥嘉的说谎片段
回复 支持 1 反对 0

使用道具 举报

发表于 2011-12-6 21:51:31 | 显示全部楼层
{:soso_e129:}很少有arduino音乐制作这么详细的帖子,果断加精
回复 支持 反对

使用道具 举报

发表于 2011-12-7 04:50:01 | 显示全部楼层
新手~那个连接线路图貌似有问题~~程序里面定义输出端口为5哈~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-12-7 08:38:26 | 显示全部楼层
弘毅 发表于 2011-12-6 21:51
很少有arduino音乐制作这么详细的帖子,果断加精

认识有限 还望查缺补漏
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-12-7 08:39:08 | 显示全部楼层
lomter 发表于 2011-12-7 04:50
新手~那个连接线路图貌似有问题~~程序里面定义输出端口为5哈~

。。这个。。就是个意思,pin就随便设置喽
回复 支持 反对

使用道具 举报

发表于 2011-12-7 22:53:23 | 显示全部楼层
不顶不行啊,,,找个喇叭试试去
回复 支持 反对

使用道具 举报

发表于 2011-12-8 12:05:08 | 显示全部楼层
照葫芦画瓢画了一个~大家可以听听~一首老歌,不要说你听不出来是哪首歌···
  1. #define NOTE_G0 -1
  2. #define NOTE_G1 393
  3. #define NOTE_G2 441
  4. #define NOTE_G3 495
  5. #define NOTE_G4 556
  6. #define NOTE_G5 624
  7. #define NOTE_G6 661
  8. #define NOTE_G7 742

  9. #define NOTE_GL1 196
  10. #define NOTE_GL2 221
  11. #define NOTE_GL3 234
  12. #define NOTE_GL4 262
  13. #define NOTE_GL5 294
  14. #define NOTE_GL6 330
  15. #define NOTE_GL7 371

  16. #define NOTE_GH1 786
  17. #define NOTE_GH2 882
  18. #define NOTE_GH3 990
  19. #define NOTE_GH4 1049
  20. #define NOTE_GH5 1178
  21. #define NOTE_GH6 1322
  22. #define NOTE_GH7 1484
  23. //以上部分是定义是把每个音符和频率值对应起来,其实不用打这么多,但是都打上了,后面可以随意编写D调的各种歌,我这里用NOTE_D+数字表示音符,NOTE_DH+数字表示上面有点的那种音符,NOTE_DL+数字表示下面有点的那种音符。这样后面写起来比较好识别。
  24. #define WHOLE 1
  25. #define HALF 0.5
  26. #define QUARTER 0.25
  27. #define EIGHTH 0.25
  28. #define SIXTEENTH 0.625
  29. //这部分是用英文对应了拍子,这样后面也比较好看



  30. int tune[]=
  31. {
  32.   NOTE_G6,NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G5,NOTE_G6,
  33.   NOTE_G3,NOTE_G6,NOTE_G5,
  34.   NOTE_G6,NOTE_GH1,NOTE_G7,NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G7,
  35.   NOTE_GH1,NOTE_GH1,NOTE_GH2,
  36.   NOTE_GH3,NOTE_GH3,NOTE_GH3,NOTE_GH3,NOTE_GH2,
  37.   NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G7,NOTE_G5,
  38.   NOTE_G6,NOTE_GH1,NOTE_G7,NOTE_G6,NOTE_G5,
  39.   NOTE_G6,NOTE_G0,
  40.   NOTE_G0,NOTE_G0,NOTE_G0,NOTE_G0,

  41. };//这部分就是整首曲子的音符部分,用了一个序列定义为tune,整数
  42. float duration[]=
  43. {
  44.   1+0.5,0.5+0.5,0.5,0.5,0.5,0.5,
  45.   1+1+1,0.5,0.5,
  46.   1+0.5,0.5,0.5,0.25,0.25,0.5,0.5,
  47.   1+1+1,0.5,0.5,
  48.   0.5,0.5,0.5,0.5,1+1,
  49.   0.5,0.5,0.5,0.5,1+1,
  50.   1,1,1,0.5,0.5,
  51.   1+1+1,1,
  52.   1,1,1,1,

  53. };//这部分是整首曲子的接拍部分,也定义个序列duration,浮点(数组的个数和前面音符的个数是一样的,一一对应么)
  54. int length;//这里定义一个变量,后面用来表示共有多少个音符
  55. int tonePin=5;//蜂鸣器的pin

  56. void setup()
  57. {
  58.   pinMode(tonePin,OUTPUT);//设置蜂鸣器的pin为输出模式
  59.   length = sizeof(tune)/sizeof(tune[0]);//这里用了一个sizeof函数,可以查出tone序列里有多少个音符
  60. }

  61. void loop()
  62. {
  63.   for(int x=0;x<length;x++)//循环音符的次数
  64.   {
  65.     tone(tonePin,tune[x]);//此函数依次播放tune序列里的数组,即每个音符
  66.     delay(800*duration[x]);//每个音符持续的时间,即节拍duration,400是调整时间的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
  67.     noTone(tonePin);//停止当前音符,进入下一音符
  68.   }
  69.   delay(5000);//等待5秒后,循环重新开始
  70. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2011-12-8 12:20:16 | 显示全部楼层
强大呀 改天试一下
回复 支持 反对

使用道具 举报

发表于 2011-12-10 22:28:53 | 显示全部楼层
  不错 不错····
回复 支持 反对

使用道具 举报

发表于 2011-12-10 22:39:21 | 显示全部楼层
{:soso_e179:}

点评

说的太对了  发表于 2015-4-22 08:53
++++++++++  发表于 2015-4-22 08:50
回复 支持 反对

使用道具 举报

发表于 2011-12-10 22:42:16 | 显示全部楼层
请问管理员有什么方法让论坛里回复过的帖子可以下次方便地找到吗?不然我发了回复以后下次找不到了,像这样的好贴我希望我回复以后,下次可以很方便地找到。比如国内一些论坛只要你回复了,下次可以在我的回帖里找到帖子。
回复 支持 反对

使用道具 举报

发表于 2011-12-10 22:44:09 | 显示全部楼层
不然我好杯具呀。现在收藏夹里到处都是我们这个论坛的帖子{:soso_e149:}搞得其它收藏都快被覆盖完了。{:soso_e154:}
回复 支持 反对

使用道具 举报

发表于 2011-12-15 23:34:11 | 显示全部楼层
真是好贴,先学习一下
回复 支持 反对

使用道具 举报

发表于 2011-12-15 23:38:26 | 显示全部楼层
プ汏坏疍 发表于 2011-12-10 22:42
请问管理员有什么方法让论坛里回复过的帖子可以下次方便地找到吗?不然我发了回复以后下次找不到了,像这 ...

介个介个。。。在右上角有一个快捷导航,然后里面有意向“帖子”,点击后。。。里面自己回复过的帖子就都能看到了。
回复 支持 反对

使用道具 举报

发表于 2011-12-15 23:39:02 | 显示全部楼层
把原#define NOTE_D3 350      改为370音准就OK了。
听听看
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2018-12-11 15:47 , Processed in 0.053294 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表