Arduino 習作工坊 - Lesson 3 電音之夜

37
#3 聲聲聲聲聲聲聲

description

Learn how to produce various sound via Arduino, and retrieve sond file from SD card module.

Transcript of Arduino 習作工坊 - Lesson 3 電音之夜

Page 1: Arduino 習作工坊 -  Lesson 3 電音之夜

#3 聲音與檔案存取

Page 2: Arduino 習作工坊 -  Lesson 3 電音之夜

聲音• 聲音是通過物體振動產生的聲波。是通過

介質(空氣或固體、液體)傳播並能被人或動物聽覺器官所感知的波動現象。

• 聲音的頻率一般會以赫茲表示,記為 Hz ,指每秒鐘周期性變化的次數。而分貝是用來表示聲音強度的單位,記為 dB 。

資料來源:維基百科

Page 3: Arduino 習作工坊 -  Lesson 3 電音之夜

聲音波形

Page 4: Arduino 習作工坊 -  Lesson 3 電音之夜

模擬波形

Page 5: Arduino 習作工坊 -  Lesson 3 電音之夜

聲音頻率頻率 , 單位為赫茲 ( 括號內為半音距離 ,"(0)" 為中央 C)

八度 0 1 2 3 4 5 6 7 8 9

C16.352 (−48)

32.703 (−36)

65.406 (−24)

130.81 (−12)

261.63 (0)

523.25 (+12)

1046.5 (+24)

2093.0 (+36)

4186.0 (+48)

8372.0 (+60)

D18.354 (−46)

36.708 (−34)

73.416 (−22)

146.83 (−10)

293.66 (+2)

587.33 (+14)

1174.7 (+26)

2349.3 (+38)

4698.6 (+50)

9397.3 (+62)

E20.602 (−44)

41.203 (−32)

82.407 (−20)

164.81 (−8)

329.63 (+4)

659.26 (+16)

1318.5 (+28)

2637.0 (+40)

5274.0 (+52)

10548 (+64)

F21.827 (−43)

43.654 (−31)

87.307 (−19)

174.61 (−7)

349.23 (+5)

698.46 (+17)

1396.9 (+29)

2793.8 (+41)

5587.7 (+53)

11175 (+65)

G24.500 (−41)

48.999 (−29)

97.999 (−17)

196.00 (−5)

392.00 (+7)

783.99 (+19)

1568.0 (+31)

3136.0 (+43)

6271.9 (+55)

12544 (+67)

A27.500 (−39)

55.000 (−27)

110.00 (−15)

220.00 (−3)

440.00 (+9)

880.00 (+21)

1760.0 (+33)

3520.0 (+45)

7040.0 (+57)

14080 (+69)

B30.868 (−37)

61.735 (−25)

123.47 (−13)

246.94 (−1)

493.88 (+11)

987.77 (+23)

1975.5 (+35)

3951.1 (+47)

7902.1 (+59)

15804 (+71)

Page 6: Arduino 習作工坊 -  Lesson 3 電音之夜

MIDI樂器數位介面

Page 7: Arduino 習作工坊 -  Lesson 3 電音之夜

MIDI

• 樂器數位介面( Musical Instrument Digital Interface ,簡稱 MIDI )是一個工業標準的電子通訊協定,為電子樂器等演奏裝置(如合成器)定義各種音符或彈奏碼,容許電子樂器、電腦、手機或其它的舞台演出配備彼此連接,調整和同步,得以即時交換演奏資料。

• MIDI 不傳送聲音,只傳送像是音調和音樂強度的資料,音量,顫音和相位等參數的控制訊號,還有設定節奏的時鐘信號。在不同的電腦上,輸出的聲音也因音源器不同而有差異。

Page 8: Arduino 習作工坊 -  Lesson 3 電音之夜

MIDI 範例EX1

Page 9: Arduino 習作工坊 -  Lesson 3 電音之夜

電路圖

Page 10: Arduino 習作工坊 -  Lesson 3 電音之夜

程式 EX1

void setup() {

}

void loop() { tone(6, 440, 200); delay(200);

noTone(6);}

Pin6 播放「 A 」 midi 音,持續 0.2 秒

Page 11: Arduino 習作工坊 -  Lesson 3 電音之夜

#include ”pitches.h”void setup() {

}

新增

tone(6, NOTE_A4, 200); delay(200);

更改

Page 12: Arduino 習作工坊 -  Lesson 3 電音之夜

MIDI 範例EX2

Page 13: Arduino 習作工坊 -  Lesson 3 電音之夜

電路圖

Page 14: Arduino 習作工坊 -  Lesson 3 電音之夜

程式 EX2

void setup(){ }

void loop() { int sensor = analogRead(A0); if(sensor > 500) { tone(6, 440, 200); delay(200); noTone(6); }

else if (sensor < 200){ tone(6, 660, 200); delay(200); noTone(6); } else{ tone(6, 880, 200); delay(200); noTone(6); }}//end loop

Page 15: Arduino 習作工坊 -  Lesson 3 電音之夜

Quiz

• Input A0 電位器: 0 ~ 1023• Output 頻率: 100 ~ 2000

• int x = map(analogRead(A0), 0, 1023, 100, 2000);

• tone(6, x , 200);

• 相同概念也可再用一個電位器來控制時間

Page 16: Arduino 習作工坊 -  Lesson 3 電音之夜

新增函式: play()void setup(){}

void loop() { int sensor = analogRead(A0); if(sensor > 500) { play(); } else if (sensor < 200){ tone(6, 660, 200); delay(200); noTone(6); }

else{ tone(6, 880, 200); delay(200); noTone(6); }}//end loop

void play(){ tone(6, 200, 200); delay(200); noTone(6);}

Page 17: Arduino 習作工坊 -  Lesson 3 電音之夜

新增函式: play(int freq)

void setup(){}

void loop() { int sensor = analogRead(A0); if(sensor > 500) { play(440); } else if (sensor < 200){ play(660); }

else{ play(880); }}//end loop

void play(int freq){ tone(6, freq, 200); delay(200); noTone(6);}

Page 18: Arduino 習作工坊 -  Lesson 3 電音之夜

再開一個參數 duration

void play(int freq, int duration){ tone(6, freq, duration); delay(200); noTone(6);}

play(440, 200);play(392, 500);

Page 19: Arduino 習作工坊 -  Lesson 3 電音之夜

音樂Music

Page 20: Arduino 習作工坊 -  Lesson 3 電音之夜

SD Shield

Page 21: Arduino 習作工坊 -  Lesson 3 電音之夜

SPI?

串列外設介面( Serial Peripheral Interface Bus , SPI ),類似 I²C ,是一種 4 線同步序列資料協定,適用於可攜式裝置平台系統,但使用率較I²C 少。串列外設介面一般是 4 線,有時亦可為 3線,有別於 I²C 的 2 線,以及 1-Wire 。

Page 22: Arduino 習作工坊 -  Lesson 3 電音之夜
Page 23: Arduino 習作工坊 -  Lesson 3 電音之夜

新增函式庫• 將「 SimpleSDAudio 」移至 \arduino\libraries 裡

Page 24: Arduino 習作工坊 -  Lesson 3 電音之夜

音樂轉檔 (WAV→AFM)

Page 25: Arduino 習作工坊 -  Lesson 3 電音之夜
Page 26: Arduino 習作工坊 -  Lesson 3 電音之夜

\SimpleSDAudio\tools\Arduino with 16 MHz\converted

Page 27: Arduino 習作工坊 -  Lesson 3 電音之夜

撥放音樂EX3

Page 28: Arduino 習作工坊 -  Lesson 3 電音之夜

電路圖

SD 卡的電源與接地

Page 29: Arduino 習作工坊 -  Lesson 3 電音之夜

程式解說 EX3 : setup()#include <SimpleSDAudio.h>

void setup(){ Serial.begin(9600); SdPlay.setSDCSPin(10); // 如 CS 腳位接在 #10 ,則需要本行,反之如接在 #4 則請刪除 SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_STEREO | SSDA_MODE_AUTOWORKER); if(!SdPlay.setFile(“MIKU.AFM”)) // 如果指定檔案不存在 { Serial.println(F(" not found on card! Error code: ")); Serial.println(SdPlay.getLastError()); // 取得錯誤碼 while(1); } }

Page 30: Arduino 習作工坊 -  Lesson 3 電音之夜

程式解說 EX3 : loop()

void loop() { Serial.println(F("found.")); SdPlay.worker(); SdPlay.play(); // 播放檔案 //delay(104*1000); while(1);}

Page 31: Arduino 習作工坊 -  Lesson 3 電音之夜

音樂撥放器,可選歌EX4

Page 32: Arduino 習作工坊 -  Lesson 3 電音之夜

電路圖:同 EX3

Page 33: Arduino 習作工坊 -  Lesson 3 電音之夜

確認 SD 卡if (!SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_MONO | SSDA_MODE_AUTOWORKER)) { Serial.println(F("initialization failed. Things to check:")); Serial.println(F("* is a card is inserted?")); Serial.println(F("* Is your wiring correct?")); Serial.println(F("* maybe you need to change the chipSelect pin to match your shield or module?")); Serial.print(F("Error code: ")); Serial.println(SdPlay.getLastError()); while(1); }

Page 34: Arduino 習作工坊 -  Lesson 3 電音之夜

讀取 SD 卡內部資料 Serial.println(F("Files on card:")); SdPlay.dir(&DirCallback);

Page 35: Arduino 習作工坊 -  Lesson 3 電音之夜

選擇檔案ReEnter: count = 0; Serial.println(F("\r\nEnter filename (send newline after input):")); do { while(!Serial.available()) ; c = Serial.read();…….

if(!SdPlay.setFile(AudioFileName)) { Serial.println(F(" not found on card! Error code: "));……

Page 36: Arduino 習作工坊 -  Lesson 3 電音之夜

選擇狀態:透過 serial monitor 來控制

Serial.println(F("Press s for stop, p for play, h for pause, f to select new file, d for deinit, v to view status.")); flag = 1; while(flag) { SdPlay.worker(); // You can remove this line if you like - worker is not necessary if(Serial.available()) { c = Serial.read();

……

Page 37: Arduino 習作工坊 -  Lesson 3 電音之夜

接下來可以做什麼 ?

• 音頻放大器• 逛逛電子商場• 找尋有趣的專題