LoginSignup
9
4

More than 1 year has passed since last update.

心が疲れたので、可愛いものをBGM付きで右往左往させた

Last updated at Posted at 2021-10-28

とにもかくにも癒されたい

お仕事に、お勉強に、みなさん本当にお疲れ様です。2021年も残すところあと2ヶ月。
とにかく可愛いものを見て癒されたい。
そう思って手を動かした結果、とても可愛いものが出来たので報告させていただく。
我々が右往左往しても全く可愛くないが、可愛いものが右往左往する姿はとても可愛い。

材料

Visual Studio Code 1.61.0
Node.js 7.24.0

  • obniz Board 1Y
  • 超音波測距センサ
  • サーボモータ
  • スピーカー
  • 右往左往させたいもの(今回の主役)

各パーツ
image_50434049.JPG

右往左往させたいもの。(可愛い)
シルバニアの赤ちゃんたち。(可愛い)
image_50431489.JPG

準備

右往左往させやすいように、準備をする。
①まずは、赤ちゃんの足を固定する。それなりの勢いで動くので、足をフェルトに縫い付けている。
image_50737409.JPG

②サーボモータのプロペラを、厚紙に張り付ける。
image_50426625.JPG

③①と②で作ったものを両面テープで貼り付け、サーボモータに装着する。
心なしか、赤ちゃんの顔が哀愁を帯びているような・・・
image_50743297.JPG

その他、必要なパーツを設置する。
image_50398209.JPG

 準備完了!!

ソースコード

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

// 任意の秒数待つことができる関数
const sleep = (msec) => new Promise(res => setTimeout(res, msec));

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

        //音符設定
       const sp1 = 3600                    //全音符・全休符
       const sp2 = sp1 / 2                 //2分音符・2分休符
       const sp4 = sp1 / 4                 //4分音符・4分休符
       const sp8 = sp1 / 8                 //8分音符・8分休符
       const sp16 = sp1 / 16               //16分音符・16分休符

        //音設定
        const c = 261.626 //ド
        const d = 293.665 //レ
        const e = 329.628 //ミ
        const f = 349.228 //ファ
        const g = 391.995 //ソ
        const a = 440.000 //ラ
        const b = 466.164 //シ♭
        const c1 = 523.251 //ド

    // ディスプレイ
    obniz.display.clear();  // クリア
    obniz.display.print('Ready');

    // setIntervalで一定間隔で処理
    setInterval(async function () {        
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // 小数点以下の桁数が多いのでここでは整数にする
        distance = Math.floor(distance);

        // 距離をターミナルに表示
        console.log(distance + ' mm');
        // obnizディスプレイに表示
        obniz.display.clear();
        obniz.display.print(distance + ' mm');

        // 距離によって判定
        if (distance < 100.0) {
            // 100mm = 10cm 未満の場合 obnizディスプレイに表示
            obniz.display.clear();
            obniz.display.print('aka-chan,panic!!');

            // サーボモータ起動
            var angle = 0;
            setInterval(async function() {
                servo.angle(angle);
                if (angle == 0) {
                    angle = 180;

                    // オラはにんきもの
                    speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
                    speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
                    speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
                    speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
                    speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
                    speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
                    speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
                    speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
                    speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
                    speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
                    speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
                    speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
                    speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
                    speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
                    speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
                    speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ

                    // Ctrl+C を打たなくても自動で終了
                    exit();

                 } else {
                    angle = 0;
                 }
            }, 1000);
        } 

    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}

曲はパニックといったらお馴染みの「オラはにんきもの」。
楽譜は分からないので、YoutTube動画から参考にさせていただいた。
【参考動画】1本指ピアノ【オラはにんきもの】 クレヨンしんちゃん 簡単ドレミ楽譜 超初心者向け

超音波測距センサの10㎝以内に近づいたら、サーボモータが起動して、スピーカーから音楽を鳴らす、という仕様にした。

超音波測距センサ

   // 距離を取得
   let distance = await hcsr04.measureWait();
   // 小数点以下の桁数が多いのでここでは整数にする
   distance = Math.floor(distance);

   // 距離をターミナルに表示
   console.log(distance + ' mm');
   // obnizディスプレイに表示
   obniz.display.clear();
   obniz.display.print(distance + ' mm');

   // 距離によって判定
   if (distance < 100.0) {
       // 100mm = 10cm 未満の場合 obnizディスプレイに表示
       obniz.display.clear();
       obniz.display.print('aka-chan,panic!!');

超音波測距センサの10㎝以内に近づいたらアクションをする設定。
他の機能と併用するにあたって、後々設定がイケてないことが判明したので、問題点を以下に記載する。

問題点

  • 超音波測距センサに近づいたらサーバモータが動く仕様にしたが、センサに近づけたままの場合にモータ起動、音楽の両方が処理の頭の部分でループしてしまうので、センサが反応したらすぐにセンサ前から外れる必要がある。

サーボモータ

  // サーボモータ起動
  var angle = 0;
  setInterval(async function() {
  servo.angle(angle);
    if (angle == 0) {
        angle = 180;
    } else {
        angle = 0;
    }
 }, 1000);

サーボモータのプロペラ部分が、0度と180度で動きループするように設定。
動く角度を90度にしたい場合は、angle = 180; の箇所を angle = 90; に設定する。

ループについては、こちらのコードを参考にさせていただいた。
【参考】【obniz入門】RC サーボモーターで同じ処理を繰り返す(ループ)

問題点

  • 動く幅を0度から180度にした、かつ左右に動くようにプロペラを設置しているので、動きが終わったときに赤ちゃんが真横を向いてしまう。 90度で止まるように、else{ angle = 90;} にすればいいが、音楽が終わるタイミングも微妙なのでちょっと気持ち悪い。。

音楽を鳴らす

   // スピーカーを利用する
   const speaker = obniz.wired('Speaker', { signal: 5, gnd: 6 });

   //音符設定
   const sp1 = 3600                    //全音符・全休符
   const sp2 = sp1 / 2                 //2分音符・2分休符
   const sp4 = sp1 / 4                 //4分音符・4分休符
   const sp8 = sp1 / 8                 //8分音符・8分休符
   const sp16 = sp1 / 16               //16分音符・16分休符

   //音設定
   const c = 261.626 //ド
   const d = 293.665 //レ
   const e = 329.628 //ミ
   const f = 349.228 //ファ
   const g = 391.995 //ソ
   const a = 440.000 //ラ
   const b = 466.164 //シ♭
   const c1 = 523.251 //ド

   // オラはにんきもの
   speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
   speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
   speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
   speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
   speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
   speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
   speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
   speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
   speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
   speaker.play(c1); await sleep(sp16); speaker.stop(); await sleep(0); //ド
   speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
   speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
   speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
   speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ
   speaker.play(a); await sleep(sp16); speaker.stop(); await sleep(0); //ラ
   speaker.play(g); await sleep(sp16); speaker.stop(); await sleep(0); //ソ

   // Ctrl+C を打たなくても自動で終了
   exit();

サーボモータが動いている間に音楽を流したかったので、モータ起動のコード内に入れ込んでいる。

「オラはにんきもの」のパニックパニック、の部分を設定(脳筋なので、ループはしないで同じ部分を繰り返してコード記載)。
みんなが慌ててる~まで入れたかったが、どうにもリズムが崩れるので開き直ってパニックパニックのみに。赤ちゃんは不穏な音楽に合わせて右往左往していても可愛い。

実は前述のサーボモータのループ起動のままだとモータが止まらないのだが、音楽を追加したことで音楽が終了したらモータも停止するようにできた。

音楽の設定については、 こちらの記事を参考にさせていただいた。
【参考】ドアモニターがないだと?代わりを作ればいいじゃない。

問題点

  • 音楽が短い。長く設定すると、リズムが上手く取れなかったり、音が飛んでしまったりする。

まとめ

比較的短時間で作ったので、問題点は多いが楽しく作れた。
可愛いものは動くともっと可愛い。
新たな知見を得た。

9
4
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
9
4