Obnizテルミン制作の道【超音波距離センサー編】

<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2775528/d0673be3-4049-f97c-89b8-72cd45f9d9e0.png">

## 楽器を自分の手で作ってみたい！
MakerFairなどで様々な楽器や音楽の制作について見ることが多く、「どうやってこんな音が鳴ってるんだろう」「自分もこんな面白そうなものが作ってみたいな」と思うものの、どうやったらいいんだろう、と思っていました。

そんな中Obnizを学ぶ機会があり、スピーカーがあったり各種センサーが存在していることがわかったので「自分もObnizを使ったら何かしら演奏ができるものが作れるんじゃないだろうか」と思い制作に着手しました。以下は影響を受けた発明を紹介しているツイートです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これMaker Faireで見たやつで一番驚いたものだ！<br>バーコードの間隔と近づき具合で音が決まってたはず。<br>楽器に不慣れな人でも音楽が楽しめる、という意味でも素敵だし、ジャンク品を再利用しようとする発想もあってダブルで素敵！<a href="https://t.co/Pc7Zntr5b6">https://t.co/Pc7Zntr5b6</a><a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/MFTokyo2022?src=hash&amp;ref_src=twsrc%5Etfw">#MFTokyo2022</a></p>&mdash; あべれん (@rencoln1229) <a href="https://twitter.com/rencoln1229/status/1579493264650276866?ref_src=twsrc%5Etfw">October 10, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やみくもに回線をつないで予想できない挙動を起こして音楽を作るって発想がとても面白いな～と感じました。<br>そして聞いているうちにどんどん不安な気持ちになっていく魔性感ある。。。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/%E3%82%B5%E3%83%BC%E3%82%AD%E3%83%83%E3%83%88%E3%83%99%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#サーキットベンディング</a><a href="https://t.co/RjSjdgMvT4">https://t.co/RjSjdgMvT4</a></p>&mdash; あべれん (@rencoln1229) <a href="https://twitter.com/rencoln1229/status/1578697529918529536?ref_src=twsrc%5Etfw">October 8, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## テルミンという楽器をご存じですか？
テルミンは世界初の電子楽器と呼ばれるロシアの楽器です。
手を楽器に触れずに演奏する姿や鳴らされる音の幻想的な様子がとても印象的な楽器です。演奏された動画もYoutubeにあるので紹介させてください。
<iframe width="560" height="315" src="https://www.youtube.com/embed/K6KbEnGnymk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
構造としては高周波を発信する装置が中に組み込まれており、それを用いて音程とボリュームを調整して演奏する楽器のようです。
Obnizには距離センサーとスピーカーが存在するので、自分でも簡易的なObnizテルミンみたいな物を作れるんじゃないかと想像しました。

## 制作にあたって意識した点
「手を触れずに」というのがテルミンの魅力の1つと感じたので、距離センサーを用いて物体とセンサーの距離によって音程が変わるように周波数を調整すると実際のテルミンみたいな演奏が可能になると考えました。
また、テルミン独特の滑らかな音(個人的な擬音だと「フォンフォン」とかがイメージ近いです)となるように意識して制作を行いたいと思います。

## 完成した様子
こちらが完成した様子です。距離感によって音色が変わる様子は再現することができました。(これだと「フォンフォン」よりかは「ピロピロ」みたいな感じですが。)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">音階が出るようになりました！<br>もっとピロピロとして音の切り替わりを早くしたい！<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/kKwpGAQ2XD">pic.twitter.com/kKwpGAQ2XD</a></p>&mdash; あべれん (@rencoln1229) <a href="https://twitter.com/rencoln1229/status/1579301519576686592?ref_src=twsrc%5Etfw">October 10, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Obniz側の設定・利用した機材
制作にあたり用意した機材はこちらです。
<img width="" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2775528/530fedf0-28a4-7b21-92fd-651480127e61.png">

- obniz Board 1Y
- 圧電スピーカー（圧電サウンダ）（13mm）PKM13EPYH4000－A0
- 超音波距離センサー　HC－SR04[101-60-142 / 20-019-100-A]
- ミニブレッドボード　BB－601（白）
- ジャンパワイヤ　6本

事前設定や接続は、[obniz公式ドキュメント（起動とWi-Fi設定）](https://obniz.com/ja/doc/reference/board-1y/quick-start/)を参考にしました。

## 環境・ソースコード
- node v18.8.0
- Visual Studio Code v1.71.0

ソースコード全量はこちらです。
音階を指定する個所は同じ処理が続くので省略をしています。
どの周波数がどの音にあたるのかは以下のサイトを参考にしています。
[音階周波数](https://tomari.org/main/java/oto.html)

```Javascript:Theremin
const Obniz = require('obniz');
const obniz = new Obniz('*******'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサとスピーカーを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    const speaker = obniz.wired('Speaker', { signal: 4, gnd: 5 });

    // ディスプレイ
    obniz.display.clear(); // クリア
    obniz.display.print('Hello obniz!');
    // Hello obniz! と表示

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();

        //下のドを鳴らす
        if (1 <= distance && distance < 50) {
            speaker.play(261.626);

        //距離と周波数を調べて並べて音階を設定する箇所なので省略

        //上のドを鳴らす
        } else if (350 <= distance && distance < 400) {
            speaker.play(523.251);
        //近すぎると休符
        } else if (distance < 1) {
            speaker.stop();
        //遠すぎても休符
        } else if (400 <= distance) {
            speaker.stop();
        }

        // 距離(mm)をターミナルに表示
        console.log(distance + ' mm');
        // obnizディスプレイに表示
        // 一度消してから距離+mmの単位を表示
        obniz.display.clear();
        obniz.display.print(distance + ' mm');

    }, 200); // 200ミリ秒 = 0.2秒おきに実行
}
```

## つまづいた点・工夫した点
最初は音階を設定し、手を高速に動かせば滑らかな音が鳴るのでは、と考えていましたがどうやらそういう訳でもなくsetIntervalの実行間隔を短時間にすることでできるだけ滑らかな音変化ができるようにしました。
とは言っても、Obnizの処理速度には限界がありそうでsetIntervalの実行間隔が200mm秒を下回ると、多少イメージに近い音が出せるようにはなりましたが、一度に処理する情報が多すぎるのか途中で音が途切れてしまいました。

大きな課題として、より音の滑らかな変化を追求したいと思っていますが、距離センサーの仕様が「超音波を飛ばしてその跳ね返りから距離を計測する」というもので、多少のタイムラグの発生が前提のため難しさも感じています。距離以外のセンサーを使用してみることも検討に入れたいなと思います。(けれどテルミンっぽさは距離センサーが一番なので諦めたくない…)

## まとめ

Obnizでテルミンを実装というのは、先駆者の方も取り組まれており勉強になったと共にそのバトンを受け継いで自分はどこをより良くしていくか考えるような実装となりました。
これから私自身もObnizテルミンがもっと良くならないか検討を進めますが、また新たなObnizテルミンを制作しようと思っている方の一助になれば幸いです。

**先駆者の皆さんのQiita記事**
[obnizと友だちになりたい　①光センサーで貧者のテルミン](https://qiita.com/yoshio333333/items/47974407e3116362ec13)
[obnizでテルミンもどき🎶](https://qiita.com/kohbis/items/67e7c68b7a997b9e6398)
[Line Things + テルミンでFlappy UFO](https://qiita.com/karu/items/5455cdef54364f633ca9)