差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
arduino:出力基礎:音を鳴らす [2019/06/17 16:15] – baba | arduino:出力基礎:音を鳴らす [2019/06/17 23:36] (現在) – [音階で音を鳴らしてみる] baba | ||
---|---|---|---|
行 1: | 行 1: | ||
====== 音を鳴らす ====== | ====== 音を鳴らす ====== | ||
- | このページではArduinoで音を鳴らす最もシンプルな方法を紹介します。もう少し複雑なことをしたい場合は、下記ページを | + | このページではArduinoで音を鳴らす最もシンプルな方法を紹介します。楽器を作ってみたい、という場合は下記ページを参考にしてみてください。 |
- | 参照してください。 | + | |
- | * {{indexmenu>: | + | |
+ | {{indexmenu>: | ||
+ | |||
+ | ===== 最初の一歩 ===== | ||
+ | Arduinoにスピーカーをつないで、音を鳴らしてみましょう。スピーカーに流す電流のオンオフを高速に繰り返すことで、永久磁石と電磁石によって高速なオンオフがスピーカーコーンの振動になります。詳しくは下記のページを読んでみてください。 | ||
+ | * https:// | ||
+ | |||
+ | ArduinoのDigital Outピンをスピーカの片方につなぎ、スピーカーのもう一方をArduino のGNDに接続します。今回はDigital OutピンをD6ピンとします。下図を参照してください。 | ||
+ | {{ : | ||
+ | |||
+ | では実際にスピーカーのコイルにON/ | ||
+ | <code .c tone500Hz.pde> | ||
+ | void setup() | ||
+ | { | ||
+ | pinMode(6, OUTPUT); | ||
+ | } | ||
+ | void loop() | ||
+ | { | ||
+ | digitalWrite(6, | ||
+ | delay(20); | ||
+ | digitalWrite(6, | ||
+ | delay(20); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <WRAP center round todo 60%> | ||
+ | 上のプログラムを参考に、440Hzの音を鳴らしてみましょう。 | ||
+ | </ | ||
+ | |||
+ | ===== tone関数を使う ===== | ||
+ | delay()のパラメータを変更することで任意の周波数の波形を出力することができました。ただし、決められた周波数を鳴らすために上記のようなコードを使っていると、たくさんの音を鳴らす場合少し面倒になります。そのため、Arduinoにはtone()関数が用意されています。 | ||
+ | * https:// | ||
+ | |||
+ | tone(pin, frequency) | ||
+ | tone(pin, frequency, duration) | ||
+ | | ||
+ | 1つ目の引数にはスピーカーにつながっている制御ピン番号を。2つ目の引数には鳴らしたい周波数を指定します。もし鳴らす音の長さ(音長)を指定したい場合、3番目の引数にmilli second単位で値を指定します。例えば次のようなコードで二種類の異なる周波数を順番に鳴らすことが簡単にできます。 | ||
+ | <WRAP center round help 60%> | ||
+ | これは有名なドラマで使われていた効果音になります.なんだか分かる人はどのくらいいるでしょうか? | ||
+ | </ | ||
+ | |||
+ | <code .c countdown.pde> | ||
+ | void setup() | ||
+ | { | ||
+ | pinMode(6, OUTPUT); | ||
+ | } | ||
+ | void loop() { | ||
+ | tone(6, 2217, 70); | ||
+ | delay(1000); | ||
+ | tone(6, 1991, 70); | ||
+ | delay(1000); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code .c ring.pde> | ||
+ | // Reference: http:// | ||
+ | void setup() | ||
+ | { | ||
+ | pinMode(6, OUTPUT); | ||
+ | } | ||
+ | void loop(void) | ||
+ | { | ||
+ | tone(6, | ||
+ | delay(50); | ||
+ | |||
+ | tone(6, | ||
+ | delay(168); | ||
+ | |||
+ | tone(6, | ||
+ | delay(48); | ||
+ | |||
+ | tone(6, | ||
+ | delay(360); | ||
+ | |||
+ | |||
+ | tone(6, | ||
+ | delay(50); | ||
+ | |||
+ | tone(6, | ||
+ | delay(50); | ||
+ | |||
+ | tone(6, | ||
+ | delay(50); | ||
+ | |||
+ | tone(6, | ||
+ | delay(50); | ||
+ | |||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | tone(6, | ||
+ | delay(55); | ||
+ | |||
+ | delay(1500); | ||
+ | } | ||
+ | </ | ||
+ | ===== 音階で音を鳴らしてみる ===== | ||
+ | ON/ | ||
+ | |||
+ | まず最初の周波数と音高の関係ですが、ピアノの真ん中辺りの「ド」の音を鳴らし、一オクターブ上の「ド」を鳴らした場合を考えます。 | ||
+ | 最初に鳴らしたドの周波数を $f_1$とした場合、一オクターブ上のドは $f_2 = 2f_1$として表されます。つまり一オクターブ上の音は下の音の倍の周波数になっているわけです。このような関係をより数学的に表現したものが、十二平均律になります。オクターブ間に12の音程を均等に配置するものです。 | ||
+ | |||
+ | ベースやギターの開放弦を利用した調律では440Hzを利用しますが、この音を基準(ピアノのラ)として、次の式で表すことで、440Hzのオクターブ上(12音上)は $ 440 \times 2^{\frac{12}{12}} = 880 $となります。 | ||
+ | |||
+ | \[ | ||
+ | f = 440 \times 2^{(n/12)} | ||
+ | \] | ||
+ | |||
+ | ただし基準となる440Hzのラはノート番号では69番としているので、nが69のときに440Hzになるように式を下記のようにしておきます。 | ||
+ | \[ | ||
+ | f = 440 \times 2^{\frac{n-69}{12}} | ||
+ | \] | ||
+ | |||
+ | ではここまでの準備を利用して、有名なNokia Tuneを鳴らしてみましょう。下記サイトを参考にします。 | ||
+ | * https:// | ||
+ | |||
+ | <code .c nokiatune.pde> | ||
+ | float getFreq(int n) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | void setup() | ||
+ | { | ||
+ | pinMode(6, OUTPUT); | ||
+ | } | ||
+ | int interval = 250; | ||
+ | void loop() { | ||
+ | tone(6, getFreq(76), | ||
+ | delay(interval/ | ||
+ | tone(6, getFreq(74), | ||
+ | delay(interval/ | ||
+ | tone(6, getFreq(66), | ||
+ | delay(interval); | ||
+ | tone(6, getFreq(68), | ||
+ | delay(interval); | ||
+ | tone(6, | ||
+ | delay(interval/ | ||
+ | tone(6, getFreq(71), | ||
+ | delay(interval/ | ||
+ | tone(6, getFreq(62), | ||
+ | delay(interval); | ||
+ | tone(6, getFreq(64), | ||
+ | delay(interval); | ||
+ | tone(6, getFreq(71), | ||
+ | delay(interval/ | ||
+ | tone(6, getFreq(69), | ||
+ | delay(interval/ | ||
+ | tone(6, getFreq(61), | ||
+ | delay(interval); | ||
+ | tone(6, getFreq(64), | ||
+ | delay(interval); | ||
+ | tone(6, getFreq(69), | ||
+ | delay(interval*4); | ||
+ | delay(interval*4); | ||
+ | } | ||
+ | </ | ||
+ | ===== 余談 ===== | ||
+ | 鳴らしたいノート番号を指定することでその周波数を計算することができますが、その逆である「鳴らしたい周波数が決まっている場合、それはピアノの鍵盤でいうところのどの位置になるのか?」を計算するには、方程式をnについてとけば良いです。 | ||
+ | |||
+ | 上記式を両辺に自然対数とることで簡単にnについて解くことができます。みなさんも実際に計算して確かめてみましょう。 | ||
+ | \[ | ||
+ | n = \frac{12 \times log_e(\frac{f}{440})}{log_e(2)} + 69 | ||
+ | \] | ||