2
Help us understand the problem. What are the problem?

posted at

夜集中して、寝ないで頑張れる環境をつくり、疲れたらLINEで癒しの曲を!

Obniz X LINE Botで勉強を頑張れる「環境づくり」にチャレンジ!

最近仕事が特に忙しく、プログラミングスクールとの両立に苦労していました。辛酸をなめる状況が続き、まとまった時間を捻出するのが難しい環境だからこそ、よなよな勉強を頑張れる環境を整えたい。

特に、仕事後の夜の勉強時間を増やし、質も向上させたい。そのために今回は、IoTの力を利用して、3つの課題解決に取り組んでみました。

① 妻が部屋に入ってきて話し込んでしまう → 集中モードの時は赤いLEDを点灯させる
② 眠くなってくると、寝てしまう → ベッドに寝ようとするとき、警報を鳴らす
③ 休憩すると、長くなってしまう → 疲れたよ!と送ると、自動的に癒しの音楽が流れ、その間だけ休憩する

今回のイメージ動画をご覧ください。

課題① 妻が入ってきて、話し込んでじゃうので集中モードの時間を見える化したい

その日の出来事など妻と色々話すのはかけがえのない時間です。一方で勉強に集中するには、心を鬼にして時間を決めて集中することも必要です。時には、ついつい一緒になって、はいワイン一杯、二杯、、なんてこともあるから!妻にも協力いただき、集中モードをLEDライトの色で知らせ、赤が点灯している時は、入室を控えてもらうことにしました。

集中モード!の時は、部屋の入口の壁に赤いLED照明を点灯する

集中する時間だから入室しないでね → LEDを赤く点灯

red LED.jpg

集中モード終わって、入室OK の時 → LEDを青く点灯 

Blue LED.jpg

今日から使おう!と妻にも気に入ってもらえた

集中したいとき時が一目瞭然で、話しかけるタイミングを見計らうことができて助かると意外にも好評。忙しい時には、話をしててもうわの空のことが多いみたいだし(反省)、お互い気持ちよく話せるようになり、夫婦円満につながるといいですね!

課題② 眠いけど、寝てしまうのを阻止する

ちょっと5分が致命的に!勉強の合間に、ちょっとだけ休憩とベッドに横になると、気づいたら朝だったという経験ありませんか?私はこれ結構やってしまうんです。朝起きて時計をみて、しまった!うぅーとなるわけです。。。これを解決するために、今回作ったのがアイマスクをとろうとした時に鳴る警報です。
(アイマスクとる時じゃなくて、そのままベッドに設置したらよいのではと思われているいるかもしれません。。私も正直同じことを考え実装しようとしたところ、センサが過敏に反応して警報が鳴りやまなくなってしまい、軌道修正した経緯があります 涙)

冒頭の動画は切り抜きのみだったので、youtubeにアップした動画をご紹介します。
(私の変な声が入ってますが、、ご容赦ください)

警報がうるさいので、ベッドに横になるのをあきらめる

Obnizに取り付けたスピーカー結構大きい音がなるんですよ。
さすがに、警報うるさい!となり、効果てきめんですね。そうなると、癒しの音楽が聴きたーい!となるわけです。ということで課題➂の解決に進みたいと思います!

課題➂ 休憩すると、長くなってしまうのを解決する

休憩する時は、好きな音楽をかけたい。そして休憩時間を管理して、おもいっきりリラックスしたい!そんな私の願いを叶えてくれるのが、エリククラプトンの「Wonderful Tonight」が流れる癒しのLINE Botです。余談ですが、この曲は結婚式で妻と連弾した思い出の一曲で、当時始めたばかりのギターを、めちゃめちゃ緊張して演奏したのを思い出します。

Step 1: ピアノで音にしたい曲を演奏して、ドレミでノートに記録する

↓ 下手くそな演奏で恐縮ですが、、まずピアノを弾いて、ドレミをひろっていきました。

Step 2: 早見表を使い音階のヘルツに変換していき、LINE Botを制作する

音階の周波数の早見表

事前準備と実装方法

Obnizの設定を行う

今回の3つの課題解決ものづくりには、全てObnizのIoT技術を活用しました。設定方法はこちらをご参照ください。初めてのIoT体験ですが、このObniz1Yの設定がその第一歩となりました。

Obnizの設定方法

実行環境

実行環境
VScode (v1.65.2)
node.js(v17.6.0)
npm(v8.5.1)

コード

LED照明

点灯させたい色のLEDを設置し、どちらか1つを実行します。
(色を変えたいときは、もう一方のコードを実行します)

LEDライト(赤色)点灯用
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 6, vcc: 7, din: 8 });

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離が5cm以上かどうかの判定
        if (distance > 50) { // 50mm = 5cm 以上の場合
            ///光る
            rgbled.rgb(255, 0, 0);
            
            }else {
                rgbled.rgb(0, 0, 0);
              }


    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}
LEDライト(青色)点灯用
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 6, vcc: 7, din: 8 });

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離が5cm以上かどうかの判定
        if (distance > 50) { // 50mm = 5cm 以上の場合
            ///光る
            rgbled.rgb(255, 0, 0);
            
            }else {
                rgbled.rgb(0, 0, 0);
              }


    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}
寝かせないブー(警報)
寝かせないブー
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 6, vcc: 7, din: 8 });
    // スピーカーを利用
    const speaker = obniz.wired('Speaker', { signal: 10, gnd: 11 });

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離が5cm以上かどうかの判定
        if (distance > 50) { // 50mm = 5cm 以上の場合
            ///光る
            rgbled.rgb(255, 0, 0);
            // 528Hz で音を鳴らす
            speaker.play(528);
            }else {
                rgbled.rgb(0, 0, 0);
                speaker.stop();
              }


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

LINE Botで癒しの曲

LINE Botで癒しの曲を流す
'use strict';

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

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelAccessToken: 'XXXXXXXXX',
    channelSecret: 'XXXXXXXXXXXX'
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

// obniz接続
obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print("obniz meets LINE Bot!");
}

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = ''
  if(event.message.text === '疲れたよ!'){
    mes = '癒しの音楽送るよ♪'; //待ってねってメッセージだけ先に処理
    getAskObnizSpeaker(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getAskObnizSpeaker = async (userId) => {
 // スピーカーを呼び出す
 const speaker = obniz.wired("Speaker", {signal:0, gnd:1});
 console.log("Speaker")
 await client.pushMessage(userId, {
  type: 'text',
  text: "頑張っているあなたが好き❤ だから寝ないで💜",
});

 // 音階とhzの参考サイト https://tomari.org/main/java/oto.html
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1479.978); // F#6 ファ#
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1479.978); // F#6 ファ#
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1108.731); // C#6 ド#
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1318.510); // E6 ミ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1318.510); // E6 ミ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1108.731); // C#6 ド#
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(200);
 await speaker.play(987.767); // B5 シ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1567.982); // G6 ソ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1567.982); // G6 ソ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(987.767); // B5 シ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(2217.461); // C#7 ド#
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(2637.020); // E7 ミ
 await obniz.wait(700);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(2637.020); // E7 ミ
 await obniz.wait(50);
 await speaker.stop();
 await obniz.wait(20);
 await speaker.play(2349.318); // D8 レ
 await obniz.wait(800);
 
 speaker.stop();
}

参考記事

これらの先輩方の記事があったからこそ、今回実装することができました!ありがとうございました!

https://qiita.com/naokiuc/items/7aecf478e8893d41f16f
https://qiita.com/dsvvpxgcseldie/items/c72c822946221849e790
https://qiita.com/Naru0607/items/b523cf9f67fa18bcf7d7

今後チャレンジしたいこと

Alexaに話しかければ、LEDライトを遠隔で赤く点灯できるようにしたい

LEDを赤く点灯させる時に、Node.jsで毎回実行するのではなく、Amazonエコーを使いはなしかけることで全自動にしたい!

下のObnizの説明ブログも参考にさせていただき、IFTTTとの連携も行い、あと少しのところまできたと思うのですが、断念しました。結構頑張ったのに、今回は残念。これが出来ると更に便利になりそうなので、またチャレンジしたいです。

ご参考までに、設定方法のページ等お伝えします。

●Obniz公式(参考にしたサイト)
https://obniz.com/ja/products/obnizboard#areapdctSpec

Obnizの説明ブログ→設定の仕方が詳しくでています
(Youtube動画でサービスの内容もご確認いただけます)
https://blog.obniz.com/make/obniz-alexa-ifttt

●Obnizサンプルコード(Alexaとの連携についても知った)
https://obniz.com/ja/doc/sample-codes

●IFTTTとの連携用
https://ifttt.com/onboarding

最後に

最後までお読みいただき、ありがとうございました!

今回は、IoTでobnizに触れることは、とても楽しかったです。ものづくりの幅が広がるなーと実感しました。また何か作ってみたいです!

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
2
Help us understand the problem. What are the problem?