arduino:出力基礎:音を鳴らす

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
arduino:出力基礎:音を鳴らす [2019/06/17 16:17] babaarduino:出力基礎:音を鳴らす [2019/06/17 23:36] (現在) – [音階で音を鳴らしてみる] baba
行 1: 行 1:
 ====== 音を鳴らす ====== ====== 音を鳴らす ======
 このページではArduinoで音を鳴らす最もシンプルな方法を紹介します。楽器を作ってみたい、という場合は下記ページを参考にしてみてください。 このページではArduinoで音を鳴らす最もシンプルな方法を紹介します。楽器を作ってみたい、という場合は下記ページを参考にしてみてください。
-  * {{indexmenu>:楽器をつくる#1|js#simple}} 
  
 +{{indexmenu>:楽器をつくる#1|js#simple}}
 +
 +===== 最初の一歩 =====
 +Arduinoにスピーカーをつないで、音を鳴らしてみましょう。スピーカーに流す電流のオンオフを高速に繰り返すことで、永久磁石と電磁石によって高速なオンオフがスピーカーコーンの振動になります。詳しくは下記のページを読んでみてください。 
 +  * https://jp.pioneer-audiovisual.com/homeav/knowledge/detail_5_15.html
 +
 +ArduinoのDigital Outピンをスピーカの片方につなぎ、スピーカーのもう一方をArduino のGNDに接続します。今回はDigital OutピンをD6ピンとします。下図を参照してください。
 +{{ :arduino:出力基礎:スクリーンショット_2019-06-17_16.26.06.png?direct&400 |}}
 +
 +では実際にスピーカーのコイルにON/OFFの電流を高速に流してみます。
 +<code .c tone500Hz.pde>
 +void setup()
 +{
 +  pinMode(6, OUTPUT);
 +}
 +void loop()
 +{
 +  digitalWrite(6, HIGH);
 +  delay(20);
 +  digitalWrite(6, LOW);
 +  delay(20);
 +}
 +</code>
 +
 +<WRAP center round todo 60%>
 +上のプログラムを参考に、440Hzの音を鳴らしてみましょう。
 +</WRAP>
 +
 +===== tone関数を使う =====
 +delay()のパラメータを変更することで任意の周波数の波形を出力することができました。ただし、決められた周波数を鳴らすために上記のようなコードを使っていると、たくさんの音を鳴らす場合少し面倒になります。そのため、Arduinoにはtone()関数が用意されています。
 +  * https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
 +
 +  tone(pin, frequency)
 +  tone(pin, frequency, duration)
 +  
 +1つ目の引数にはスピーカーにつながっている制御ピン番号を。2つ目の引数には鳴らしたい周波数を指定します。もし鳴らす音の長さ(音長)を指定したい場合、3番目の引数にmilli second単位で値を指定します。例えば次のようなコードで二種類の異なる周波数を順番に鳴らすことが簡単にできます。
 +<WRAP center round help 60%>
 +これは有名なドラマで使われていた効果音になります.なんだか分かる人はどのくらいいるでしょうか?
 +</WRAP>
 +
 +<code .c countdown.pde>
 +void setup()
 +{
 +  pinMode(6, OUTPUT);
 +}
 +void loop() {
 +  tone(6, 2217, 70);
 +  delay(1000);
 +  tone(6, 1991, 70);
 +  delay(1000);
 +}
 +</code>
 +
 +<code .c ring.pde>
 +// Reference: http://arms22.blog91.fc2.com/blog-entry-276.html
 +void setup()
 +{
 +  pinMode(6, OUTPUT);
 +}
 +void loop(void)
 +{
 +  tone(6,690,25);
 +  delay(50);
 +
 +  tone(6,690,30);
 +  delay(168);
 +
 +  tone(6,690,23);
 +  delay(48);
 +
 +  tone(6,690,30);
 +  delay(360);
 +
 +
 +  tone(6,970,25);
 +  delay(50);
 +
 +  tone(6,970,30);
 +  delay(50);
 +
 +  tone(6,970,30);
 +  delay(50);
 +
 +  tone(6,970,30);
 +  delay(50);
 +
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  tone(6,487,30);
 +  delay(55);
 +
 +  delay(1500);
 +}
 +</code>
 +===== 音階で音を鳴らしてみる =====
 +ON/OFFの感覚を狭くすることで、高い音が、広くすることで低い音がなることが確認できました。また、任意の周波数であればtone()関数を利用して簡単に音を鳴らすことができるのも確認できました。ではこれをもう少しわかりやすく、所謂ドレミファソラシド...といった音程にて再現できるようにしてみましょう。
 +
 +まず最初の周波数と音高の関係ですが、ピアノの真ん中辺りの「ド」の音を鳴らし、一オクターブ上の「ド」を鳴らした場合を考えます。
 +最初に鳴らしたドの周波数を $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://musescore.com/user/29944637/scores/5266155
 +
 +<code .c nokiatune.pde>
 +float getFreq(int n)
 +{
 + return 440.0*pow(2, (n-69)/12.0);
 +}
 +void setup()
 +{
 +  pinMode(6, OUTPUT);
 +}
 +int interval = 250;
 +void loop() {
 +  tone(6, getFreq(76), interval/2);
 +  delay(interval/2);
 +  tone(6, getFreq(74), interval/2);
 +  delay(interval/2);
 +  tone(6, getFreq(66), interval);
 +  delay(interval);
 +  tone(6, getFreq(68), interval);
 +  delay(interval);
 +  tone(6,getFreq(73), interval/2);
 +  delay(interval/2);
 +  tone(6, getFreq(71), interval/2);
 +  delay(interval/2);
 +  tone(6, getFreq(62), interval);
 +  delay(interval);
 +  tone(6, getFreq(64), interval);
 +  delay(interval);
 +  tone(6, getFreq(71), interval/2);
 +  delay(interval/2);
 +  tone(6, getFreq(69), interval/2);
 +  delay(interval/2);
 +  tone(6, getFreq(61), interval);
 +  delay(interval);
 +  tone(6, getFreq(64), interval);
 +  delay(interval);
 +  tone(6, getFreq(69), interval*2);
 +  delay(interval*4);
 +  delay(interval*4);
 +}
 +</code>
 +===== 余談 =====
 +鳴らしたいノート番号を指定することでその周波数を計算することができますが、その逆である「鳴らしたい周波数が決まっている場合、それはピアノの鍵盤でいうところのどの位置になるのか?」を計算するには、方程式をnについてとけば良いです。
 +
 +上記式を両辺に自然対数とることで簡単にnについて解くことができます。みなさんも実際に計算して確かめてみましょう。
 +\[
 + n = \frac{12 \times log_e(\frac{f}{440})}{log_e(2)} + 69
 +\]
  
  • /home/users/2/lolipop.jp-4404d470cd64c603/web/ws/data/attic/arduino/出力基礎/音を鳴らす.1560755870.txt.gz
  • 最終更新: 2019/06/17 16:17
  • by baba