本部落格已搬遷, 3秒後跳轉...

Arduino UNO:Coffin Dance | Laplace's Lab

Arduino UNO:Coffin Dance

其實原曲名叫Astronomia啊,只是被幾位知名舞者(?)給抬出名了。看到Arduino範例程式的toneMelody發出了一段像是gameover的音效,我就想讓蜂鳴器播放這段相當知名的迷因歌曲🤣

蜂鳴器分為有(震盪)源蜂鳴器,和無(震盪)源蜂鳴器,有源蜂鳴器就是高電位逼逼叫,低電位不叫,就這樣。而無源的蜂鳴器就好玩了,可以控制其聲音頻率而產生音調高低。

Music Scales

參考範例程式中所引入的pitches.h檔案內容:

1
2
3
4
5
6
7
8
9
10
11
12
#define NOTE_B0  31
#define NOTE_C1 33
#define NOTE_CS1 35
.
.
.
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
.
.
.

這個.h檔即是定義唱名所對應的聲音頻率(Hz),其中C4就是鋼琴琴鍵的中央C,亦即C大調的低音Do。如此一來只要有簡譜,像我這樣對樂理沒輒的人也能教Arduino怎麼演奏音樂了呢。

LCD Screen

然後我想用個LCD在旁邊顯示播放的曲名,參考GTW的教學解決了我在編譯時發生的找不到函式庫的問題。要使用HD44780U 1602 LCD須安裝LiquidCrystal library,下載後解壓縮到Arduino的libraries資料夾底下即可。但這邊又有個小問題:

1
2
3
Arduino:1.8.13 (Mac OS X), 開發板:"Arduino Uno"
/Users/nick/Documents/Arduino/libraries/LiquidCrystal/I2CIO.cpp:35:10: fatal error: ../Wire/Wire.h: No such file or directory
#include <../Wire/Wire.h>

這就要找到剛剛解壓縮的資料夾中的I2CIO.cpp,將#include <../Wire/Wire.h>改為#include <Wire.h>。

*1602 LCD的pin腳說明與像素點控制等教學:Interfacing 16×2 Character LCD Module with Arduino

Play Music!

經過強迫症似的反覆聆聽和調整節拍,我覺得很接近原曲了😆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <LiquidCrystal_I2C.h>
#include "pitches.h"

#define PIN_BUZ 8

// Ref. https://youtu.be/miwoTFkiIfQ
int melody[] = {
NOTE_AS4, NOTE_AS4, NOTE_AS4, NOTE_AS4,
NOTE_D5, NOTE_D5, NOTE_D5, NOTE_D5,
NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5,
NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5,
NOTE_G5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_G5,
NOTE_G5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_G5,
NOTE_C5, NOTE_AS4, NOTE_A4, NOTE_G4,
NOTE_G4, 0, NOTE_G4, NOTE_D5, NOTE_C5, NOTE_AS4, NOTE_A4, NOTE_A4, NOTE_A4,
NOTE_C5, NOTE_AS4, NOTE_A4, NOTE_G4, NOTE_G4, NOTE_G4,
NOTE_AS5, NOTE_A5, NOTE_AS5, NOTE_A5, NOTE_AS5, NOTE_G4,
NOTE_AS5, NOTE_A5, NOTE_AS5, NOTE_A5, NOTE_AS5, NOTE_G4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
byte noteDurations[] = {
5, 5, 5, 5,
5, 5, 5, 5,
5, 5, 5, 5,
5, 5, 5, 5,
5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5,
5, 5, 5, 5,
5, 5, 5, 5, 3, 3, 3, 5, 5,
3, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 3,
5, 5, 5, 5, 5, 3
};

// Set the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
lcd.begin(16, 2); // lcd initial
lcd.backlight(); // turn on the backlight
lcd.setCursor(0, 0);
lcd.print("Play:Astronomia");
lcd.setCursor(0, 1);
lcd.print("(Coffin Dance)");
}

void loop() {
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 59; 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(PIN_BUZ, 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(PIN_BUZ);
}
delay(3000);
}

感謝這位大叔的彈奏教學

0%