2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AKBONE2020 で音を鳴らそう

Last updated at Posted at 2021-07-26

(夏休み企画 1/20)

AKBONE2020 は圧電スピーカを搭載していて、音を鳴らすことができます。
今回はこれを利用して音の実験をしましょう。

AKBONE2020 は Arduino 互換機として使うことができますが、以下の実験は一般的な Arduino などでも外部に圧電スピーカを取り付ければ同様に実験ができます。

AKBONE 2020 と Arduino について

今回の実験では LED と、サウンドデバイスとして圧電スピーカを使います。

LED 圧電スピーカ
A1(D15) LED_BUILTIN(D13)

AKBONE2020の割当は上のようになっています。

cf., 「はんだ付けトレーニングキット AKBONE2020」
https://qiita.com/nanbuwks/items/8ff1b2c711d58fc6f85a

一般的なArduinoも、A1(D15)ポートに圧電スピーカをつなげることで同様に実験ができます。

LEDを点滅

まず、LEDに電気を流したり止めたりしてチカチカ点滅させてみましょう。


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

LEDと共に圧電スピーカも動かしてみる

以下のようにすると、LEDと同時に圧電スピーカにも電気を流したり止めたりできます。


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(D15, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(D15, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(D15, LOW);
  delay(1000);
}

プチプチ音が出ています。この 1000 を、 50に替えてみましょう。
プチプチが早くなりましたね。
50 ということは、ONにして0.05秒、OFFにして0.05秒ということで0.1秒おきにON/OFF
しているということです。

ここから先は、ON/OFF を1秒間で何回行っているかを表す Hz (ヘルツ)という単位で説明していきましょう。

Hz で今の説明をやり直すと、 1秒間/0.1秒おき = 10回 で、1秒間に10回の波ということです。

可聴域にしてみる

プチプチは音で聞こえますが、普通の音にしてみましょう。人間の耳は20Hz
ぐらいから連続した音に聞こえます。

50 を 5 にすると、5+5で10ミリ秒→0.01秒 なので、1秒間/0.01秒おき =100回で 100Hz
となります。

ブーという音が鳴るようになりましたね。

音の高さを変える

周波数を変えると、音の高さが変わります。

5 を 1 にすると、1+1で2ミリ秒→0.002秒 なので、1秒間/0.002秒おき =500回で 500Hz
となります。

先程の音に比べて、音が高くなったでしょうか? 低くなったでしょうか?

ブーを1秒だけ鳴らす

millis() は、AKBONE2020(Arduino)が起動してからの時間を千分の1秒単位で表します。
音を鳴らしはじめる時間を記録し、今の時間との差が1000になるまでブーという音を鳴らし続けます。

void setup() {
//  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(D15, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // 1秒鳴らす
  long starttime = millis();
  starttime = millis();
  while ( 1000 > millis() - starttime ) {
//    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(5);
//    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(5);
  }
  // 1秒空ける
  delay(1000);
}

音階を鳴らす

では、先のプログラムを変更して、いろんな音の高さを1秒間ずつ鳴らしてみましょう。


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(D15, OUTPUT);
}

void loop() {
  // 1秒鳴らす
  long starttime = millis();
  // 100Hz
  starttime = millis();
  while ( 1000 > millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(5);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(5);
  }
  // 125Hz
  starttime = millis();
  while ( 1000 > millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(4);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(4);
  }
  // 167Hz
  starttime = millis();
  while ( 1000 > millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(3);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(3);
  }
  // 250Hz
  starttime = millis();
  while ( 1000 > millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(2);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(2);
  }
  // 500Hz
  starttime = millis();
  while ( 1000 > millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(1);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(1);
  }
  // 1秒空ける
  delay(1000);
}

できましたか? でも、なんだか、調子ハズレですね!

ちゃんとドレミファソを鳴らす

今までの実験では次のようになりました。

Delay ミリ秒 Hz
50 100 10 プチプチ音
5 10 100 ブー
4 8 125 ビー
3 6 167 ポー
2 4 250 ピー
1 2 500 パー

なんだか、全然ドレミに聞こえないですね。
それに、これ以上delay で数字を小さくするのは無理があります。

ちゃんとドレミに聞こえるようにするには以下のような周波数に合わせる必要があります。

周波数 ミリ秒 ミリ秒の半分 マイクロ秒の半分
C4 261.626 3.82 1.91 1911
D4 293.665 3.40 1.70 1702
E4 329.628 3.03 1.51 1516
ファ F4 349.228 2.86 1.43 1431
G4 391.995 2.55 1.27 1275
A5 440 2.27 1.13 1136
B5 493.883 2.02 1.01 1012
C5 523.251 1.91 0.95 955.5

では、 delaymicroseconds を使ってみましょう。
delay では千分の1秒単位でしか指定できないので、 1.91 ミリ秒という指定はできなかったのですが、
delaymicroseconds だと 100万分の1秒単位で指定できるので、delaymicroseconds(191) とすると「ド」が出るようになります。


  // 261Hzできない!
  if ( 1000 < millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delay(2);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delay(2);
  }


  // 261Hzできた!
  if ( 1000 < millis() - starttime ) {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(D15, HIGH);
    delaymicroseonds(191);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(D15, LOW);
    delaymicroseconds(191);
  }

先のプログラムを書き換えて「ドレミファソ」となるようにしてみましょう。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?