thunder5178のアイコン画像
thunder5178 2020年06月10日作成 (2020年06月24日更新)
セットアップや使用方法 セットアップや使用方法 閲覧数 2497
thunder5178 2020年06月10日作成 (2020年06月24日更新) セットアップや使用方法 セットアップや使用方法 閲覧数 2497

【IoT電子工作】obnizで圧電スピーカーを鳴らそう!

obnizを使った電子工作の第5回として、圧電スピーカーを鳴らしたいと思います。
今回はこれまでのようにブラウザからの操作だけではなく、パソコンのキーボードを入力として使用します。

この記事でできること
obnizで圧電スピーカーを鳴らす

これまでの記事は下記をご覧ください。

  1. サーボモーターを動かそう
  2. 測距センサーを使おう【前編:LED調光】
  3. 測距センサーを使おう【後編:サーボモーター】
  4. DCモーター制御&ラジコンを作ろう

用意するもの

部材一式

  1. obniz
  2. USB A - USB micro Bケーブル
  3. 圧電スピーカー(SPT15)
  4. クリップ付ワイヤーコード
  5. ジャンパーワイヤー(オス-オス)
用意する部材 購入先の例
obniz obniz公式ストアなど
USB A - micro Bケーブル 家電量販店など
圧電スピーカー(SPT15) 秋月電子通商など
クリップ付コード 秋月電子通商など

開発ボードのobnizです。
obniz

圧電スピーカーの「PT15-350912SAWR」です。
通常、この圧電スピーカーで音を鳴らす場合は発振回路が必要です。
obnizなら指定した周波数の矩形波を出力できるので、そのまま音を鳴らすことができます。

圧電スピーカー

クリップ付コードは圧電スピーカーのリード線とジャンパーワイヤーをつなぎます。
クリップ付きコード

ジャンパーワイヤーは片側をobnizの端子に、反対側はクリップ付コードを経由して圧電スピーカーに接続します。
ジャンパーワイヤー(オス-オス)

obnizに圧電スピーカーを接続する

obnizに圧電スピーカーを接続する
obnizに圧電スピーカーを接続します。
圧電スピーカーは「SPT15」を使用します。

圧電スピーカー「SPT15」のリード線をobnizの端子に直接挿そうとすると芯線が細く、接続が不安定になります。
そのため、クリップ付コードとジャンパーワイヤーを経由してobnizに接続します。

まずは圧電スピーカーのリード線にクリップ付コードを接続、クリップ付コードの反対側はジャンパーワイヤーを接続します。

そして、ジャンパーワイヤーをobnizの端子に接続してください。

圧電スピーカーとobnizの接続

obnizの端子への接続は下記の通りです。信号線である赤い線をobnizの0番ポートに、GND線の黒い線を1番ポートへつなぎます。

圧電スピーカー obniz
赤い線 (信号線) 0番ポート
黒い線 (GND線) 1番ポート

サンプルプログラム

obnizに接続した圧電スピーカーから音を鳴らすサンプルプログラムを紹介します。
今回はパソコンのキーボードが押されたら、押されたキーに対応した周波数を鳴らすことでドレミの音階を再現します。

押されたキーに対応した周波数を圧電ブザーから鳴らす

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <script src="https://unpkg.com/obniz@3.5.0/obniz.js" crossorigin="anonymous"></script> <title>圧電ブザーで演奏</title> <style> button::after{ content: "(" attr(id) ")"; } </style> </head> <body> <div class="container"> <!-- ボタングループ --> <div class="row d-flex justify-content-around m-3"> <button type = "button" id = "a" class = "btn btn-light col-1"></button> <button type = "button" id = "s" class = "btn btn-danger col-1"></button> <button type = "button" id = "d" class = "btn btn-warning col-1"></button> <button type = "button" id = "f" class = "btn btn-success col-1"> ファ</button> <button type = "button" id = "g" class = "btn btn-info col-1"></button> <button type = "button" id = "h" class = "btn btn-primary col-1"></button> <button type = "button" id = "j" class = "btn btn-secondary col-1"></button> <button type = "button" id = "k" class = "btn btn-dark col-1"></button> </div> <!-- obnizデバッグ表示 --> <div id="obniz-debug"></div> </div> <script> 'use strict'; const obniz = new Obniz("OBNIZ_ID_HERE"); obniz.onconnect = async function() { const speaker = obniz.wired("Speaker", { signal:0, gnd:1 }); // キーボードのオブジェクト const key_object = { 'a' : 261.626, // ド(C4)の周波数 's' : 293.665, // レ 〃 'd' : 329.628, // ミ 〃 'f' : 349.228, // ファ〃 'g' : 391.995, // ソ 〃 'h' : 440.000, // ラ 〃 'j' : 493.883, // シ 〃 'k' : 523.251 // 高いド(C5) } // キーが押下された時の処理 window.addEventListener('keydown', (event) => { // 押下されたキーがkey_objectに存在するかどうかチェック const is_exist_in_key_object = Object.keys(key_object).indexOf(event.key); // 押下されたキーがkey_objectに存在すれば0以上、存在しない場合は-1 if(is_exist_in_key_object >= 0) { // 押下されたキーの周波数を鳴らす speaker.play(key_object[event.key]); // 押下されたキーに対応するボタンにactiveクラスを適用 document.getElementById(event.key).classList.add("active"); } }); // キーが離された時の処理 window.addEventListener('keyup',(event) => { const is_exist_in_key_object = Object.keys(key_object).indexOf(event.key); if(is_exist_in_key_object >= 0) { // スピーカーを止める speaker.stop(); // 離されたキーに対応するボタンからactiveクラスを除去 document.getElementById(event.key).classList.remove("active"); } }); }; </script> </body> </html>

プログラムの説明

プログラムの説明をします。
今回のプログラムでは、下記に記載したキーボードのキーが押下されると、対応したドレミの音階を圧電スピーカーから鳴らします。
ドレミの音階は圧電スピーカーへ送る信号の周波数を変更することで実現しています。

キーボード 音階 鳴らす周波数(Hz)
a 低いド 261.626
s 293.665
d 329.628
f ファ 349.228
g 391.995
h 440.000
j 493.883
k 高いド 523.251

ボタンの見た目をBootstrapで変更
作成したボタンの見た目を変更するため、前回記事の「obnizでDCモーター制御&ラジコンを作ろう!」に引き続き、Bootstrapを使用しました。

Bootstrapの詳しい説明について今回は割愛させていただきますが、簡単に説明すると、ボタンなどのHTMLタグに指定のclass名を適用するだけで、キレイな見た目に変更できます。

サンプルプログラムでは、ドレミのボタンに関して、下記のclassを適用して見た目を変更しています。
下記表のように、指定されたclass名を適用するとボタンの見た目と色の変更が可能です。

音階 Bootstrapのclass名 ボタンの色
低いド btn btn-light
btn btn-danger
btn btn-warning
ファ btn btn-success
btn btn-info 青緑
btn btn-primary
btn btn-secondary 灰色
高いド btn btn-dark

各ボタンのIDにはキーボードで割り当てるキー名を設定しています。
例えば、高い「ド」ならば「a」、「レ」なら「s」といった具合です。

JavaScriptで押されたキーの値を取得し、「a」が押されたら高いドの周波数を鳴らします。

<style></style>部分の説明
こちらはスタイルシートを適用しています。
ドレミのボタンに関して、どのキーが対応しているのかを表示するため、疑似要素と呼ばれる「::after」を使って表現しました。

疑似要素(after)で音階の後に(キー名)を付与

button::after{ content: "("attr(id)")"; }

content: には適用する本文を記述します。
"(" + ボタンのID名[attr(id)] + ")" ;
とすることで、全てのボタンに「ド(a)」のように対応するキーを表示させています。

buttonの後に(ID値)を追記

const speaker = obniz.wired("Speaker",{}の説明
obnizで圧電スピーカーを使用するための設定をしています。

obnizと圧電スピーカーの接続図

使用する圧電スピーカー「PT15-350912SAWR」には極性(プラスとマイナス)はなく、どちらにつないでも音はなりますが、赤い線をSignal線、黒い線をGND線と定義しました。

スピーカー線色 obnizのアサイン obnizのポート番号
signal(信号線) 0番
gnd(GND線) 1番

const key_object = {} の説明
こちらは、キーボードのキー値と、スピーカーから鳴らす周波数を対にしています。
例えば、「a」なら低い「ド」の周波数である261.626Hzです。

キーボードの「a」から右へ移動し、「k」までのキーにドレミファソラシドに対応した周波数を割り当てます。

下記で指定したキーが押された場合のみ音を鳴らすため、連想配列に格納しています。

キーボード 音階 鳴らす周波数(Hz)
a 低いド 261.626
s 293.665
d 329.628
f ファ 349.228
g 391.995
h 440.000
j 493.883
k 高いド 523.251

window.addEventListener('keydown', (event) => {});、window.addEventListener('keyup',(event) => {});の説明

window.addEventListenerにて、ウィンドウ上で何かアクションがあった時のイベント処理を記述しています。

'keydown'と'keyup'はそれぞれ下記のイベントが実行されたときに処理されます。

イベント イベントの説明 実行する動作
keydown キーを押し込んだとき キーに対応した周波数を出力する
keyup キーを離したとき スピーカーの出力を止める

const is_exist_in_key_object = (略)の説明

最初に右辺のObject.keys(key_object).indexOf(event.key);を説明します。
冒頭で設定したkey_object('a'なら261.626と設定)の中に押されたキーが存在するかどうかを判別します。

存在していればkey_objectの順番を返します。(押されたキーが'a'なら0、's'なら1)

押されたキー is_exist_key_objectの値
a 0
s 1
k 7
上記(a~k)以外 -1

押されたキーが「key_object」に存在しなければ、「-1」を返します。
この値を「is_exist_key_object」という変数に代入しています。
0以上ならばkey_objectの中に存在するので処理を実行、-1ならば存在しないので処理を実行しません。

speaker.play(key_object[event.key]);
obnizに接続したスピーカーから指定の周波数を鳴らします。

spaker.playの丸カッコの中には周波数を代入します。

先に設定したkey_objectにて、押されたキーが'a'なら「低いド」の周波数である261.626Hz、's'なら「レ」の周波数293.665Hzを設定しました。

このように対応した周波数をkey_objectから取得して代入しています。

document.getElementById(event.key).classList.add("active");の説明
これはキーが押されたときに対応するボタンの見た目を変更する処理で、重要ではないので、簡単に説明します。

対応したキーが押下されたらactiveクラスを適用

キーに対応したボタンが押されたとき、Bootstrapの「active」をクラスに付与しています。
また、キーが離されたときにはクラスから「active」を除去することで、キーが押されたときは暗めの色、離されたらデフォルトの色となります。

speaker.stop();の説明
キーが離されたとき、つまりkeyupのイベント処理ではobnizに接続した圧電スピーカーの音を止めています。
これは「obniz.js」が持つ機能です。

まとめ

今回の記事では、キーボードのキーが押されたら、obnizに接続した圧電スピーカーから指定の周波数を鳴らすことでドレミの音階を再現しました。

以前書いた記事の「測距センサーを使おう」の記事と合わせれば、対象物との距離が近づいたら音を鳴らすといった組み合わせができるかと思います。

ぜひチャレンジしてみてください。

thunder5178のアイコン画像
はじめまして。プロフィールをご覧いただき、ありがとうございます。 本業はメーカーの電気・システム設計をしており、趣味で電子工作やプログラミングをしています。 ご覧いただいた皆様の参考になれば幸いです。 また、個人では電子工作や電気関連のブログを運営しております。 ご一読いただけると嬉しいです。 https://thunderblog.org/
ログインしてコメントを投稿する