數(shù)字制造講義01-成為數(shù)字世界的建造者
數(shù)字制造講義02-Arduino入門
數(shù)字制造講義03-電路基礎
數(shù)字制造講義04-負責輸入和輸出的智能元件
數(shù)字制造講義05-軟硬件數(shù)據(jù)通信
數(shù)字制造講義06-MIDI 和 OSC 數(shù)據(jù)傳輸練習
數(shù)字制造講義07-Arduino聲音應用
(本系列為 00 在星海音樂學院的課程講義)
回顧
還記得上一周 完成的三個練習嗎:
- 讓蜂鳴器發(fā)聲
- 蜂鳴器發(fā)出交替的報警聲
- 用按鍵觸發(fā)聲音
這一周我們繼續(xù)來完善捕虽,做出一個簡單的旋律控制器。
挑戰(zhàn)4:用電位計控制音高
既然蜂鳴器可以發(fā)出不同的音高坡脐,那我們可不可以用旋鈕控制音高泄私,做一個 mini 的極簡控制器呢?
在之前第四周的課程中备闲,我們已經(jīng)建立起比較完整的輸入輸出元件的概念晌端。在項目練習時就可以慢慢養(yǎng)成習慣:在動手之前,先構想出輸入部分是什么恬砂、輸出部分是什么咧纠、從輸入到輸出要完成什么樣的轉換。
這里泻骤,輸入部分是電位計(的位置)漆羔,輸出部分是蜂鳴器(的音高)梧奢,中間的連接就是電位計的數(shù)值轉換為蜂鳴器的音高。
接線部分演痒,使用的元件包括:蜂鳴器亲轨,電位計。
當我們還是編程新手嫡霞,每次要開始自己寫代碼時瓶埋,容易兩眼一抹黑,不知道該從哪里下手诊沪。
其實养筒,每次寫代碼時,并不是直接打開 Arduino IDE 就開始噼里啪啦敲代碼了端姚。在這之前晕粪,我們需要現(xiàn)在腦子里構思這個代碼要做什么,怎么做到渐裸。
大家會想一下巫湘,怎么把大象放進冰箱里呢?
不要笑昏鹃,這就是所謂的「算法」:做一件事情的步驟尚氛。
所以在還沒有清晰思路的時候,我們可以先把程序要完成的大致步驟寫下來:
- 需要用一個模擬端口讀取電位計的數(shù)值
- 需要用一個數(shù)字(輸出)端口給蜂鳴器發(fā)出指令
- 找一個辦法讓蜂鳴器發(fā)出不同音高
- 將電位計數(shù)值控制音高
接著洞渤,我們再想辦法把每一個步驟都轉化成對應的變量阅嘶、語法、庫载迄。所以學會搜索和查看官方文檔就很重要的了讯柔。
代碼如下:
// connect a potentiometer to pin A0
int buzzerPin=8;
int potPin=A0;
void setup() {
pinMode(buzzerPin, OUTPUT);
}
void loop() {
int freq = analogread(A0);
freq = map (freq,0,1023,20,20000); //map the value read from the potentiometer into the audible range
tone (buzzerPin,freq);
}
上面的代碼中,最核心的一行护昧,是把從電位計讀取的模擬信號數(shù)值(范圍是 01023)醉蚁,映射到人耳可感知的聲音的頻率范圍(2020000):freq = map (freq,0,1023,20,20000);
其中 map() 函數(shù)的作用就是數(shù)值映射逊拍。
挑戰(zhàn)5:播放連續(xù)音高
這個挑戰(zhàn)一定會更吸引你:用蜂鳴器播放一段旋律。
這個挑戰(zhàn)的難度主要在代碼上,從這里開始蛋欣,我們會開始接觸并深入理解函數(shù)础锐、循環(huán)瞭郑、頭文件临燃、庫等概念。
比較復雜的代碼不可能一下子就能寫出來蒜田。所以我們要經(jīng)歷一個重要的練習:看懂別人的代碼稿械。
我們在官方網(wǎng)站上找到教程 Arduino - ToneMelody。仔細研讀它給出的代碼冲粤,尤其是代碼的注釋:
/*
Melody
Plays a melody
circuit:
- 8 ohm speaker on digital pin 8
created 21 Jan 2010
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Tone
*/
#include "pitches.h"
// notes in the melody:
int melody[] = {
NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4, 4, 4, 4, 4
};
void setup() {
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(8, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(8);
}
}
void loop() {
// no need to repeat the melody.
}
把注釋部分全部替換成自己的理解美莫,這個代碼看起來就不再那么復雜和難懂了页眯。但是這個過程一定要自己完成。
當在代碼里看到不熟悉的函數(shù)厢呵,例如 delay()
, noTone()
窝撵,就可以到官方文檔中搜索并閱讀,一般文檔都會給出例子襟铭,這些例子就是最好的學習材料碌奉。
最后,留給大家的作業(yè)寒砖,是用兩個壓電片觸發(fā)兩段不同的旋律赐劣,大家動手試試吧!
<iframe frameborder="0" src="https://v.qq.com/txp/iframe/player.html?vid=p08632k4vzj" allowFullScreen="true"></iframe>