10
2

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.

オブプラス|obnizを活用して、一人暮らしに彩りを与える

Last updated at Posted at 2021-10-20

6098C4AA-4DC6-4DA4-832F-AA368FEFBCD1_1_105_c.jpeg
解説が思いつきません。
タイトルと画像を見ればやりたいことがはっきりわかります。

今回のプロダクト

IMG_2347.JPG
会話はVS Codeのターミナル上で実施することとしました。
実際の挙動については後述します。
かわいいですね。

環境・デバイス

obniz Board 1Y
マイコン内蔵RGBLED 8mm PL9823-F8
マイクロサーボ 9g SG-90
高精度IC温度センサ LM60BIZ
超音波距離センサー HC-SR04
Node.js v16.10.0
Visual Studio Code 1.60.2

挨拶

気温に応じて、最初の一声を変えてくれます。
機械なので、どうしても暑さには弱いみたいです。
かわいい。

IMG_2366.PNG
常温のとき

IMG_2367.PNG
低温のとき

今回は撮影のため、コードを書き換えて色を変えています。
実際は温度条件で色、セリフを変えています。

恥ずかしがり屋

恥ずかしがり屋なので、あまり近づきすぎると照れてしまいます。 かわいい。

さよならのとき

別れ際には頭を撫でると、手を振ってバイバイしてくれます。 かわいい。

サンプルコード


const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID');

obniz.onconnect = async () => {
    obniz.display.clear();
    // led
    const rgbled = obniz.wired("WS2811", {gnd: 4, vcc: 5, din: 6}); 
    //温度センサー
    const tempsens = obniz.wired('LM60', { gnd: 7, output: 8, vcc: 9 });
    const temp = await tempsens.getWait();
    // 温度をコンソールに表示
    console.log(temp);
        // 赤: rgbled.rgb(255, 0, 0);
        // 緑: rgbled.rgb(0, 255, 0);
        // 青: rgbled.rgb(0, 0, 255);
    if(temp < 15.0) {
        rgbled.rgb(0, 0, 255);
        console.log(`今日は寒いね。${temp}度しかないよ。`)
        await obniz.wait(5000);
    } else if(temp < 30.0) {
        rgbled.rgb(0, 255, 0);
        console.log(`今日は${temp}度。過ごしやすいね!`)
        await obniz.wait(5000);
    } else {
        rgbled.rgb(255, 0, 0);
        console.log(`${temp}度。暑いねー。熱中症にならないように家の中でだらだらしないと!`)
        await obniz.wait(5000);
    } 
    //距離センサー
    var hcsr04 = obniz.wired("HC-SR04", {gnd:0, echo:1, trigger:2, vcc:3});
    obniz.onloop = async function () {
        hcsr04.measure(function( distance ){
        //console.log("distance " + distance + " mm");
        if (distance > 200) {
            rgbled.rgb(0, 255, 0);
            } else {
            rgbled.rgb(255, 20, 50);
            console.log('近いって/// 恥ずかしいじゃん///');
            }
        });
        await new Promise((resolve) => { setTimeout(resolve, 3000) });    
    }; 
    //サーボモーター
    const servo = obniz.wired('ServoMotor', { signal: 11});
    let degrees = 90.0;
    // スイッチの反応を常時監視
    // 「スイッチ状態が変化した瞬間に1回だけ実行される」
    obniz.switch.onchange = async function (state) {
        if (state === 'right') {
            console.log('pushed');
            degrees = 180.0;
            servo.angle(degrees);
            await obniz.wait(400);
            degrees = 90.0;
            servo.angle(degrees);
            await obniz.wait(400);
            degrees = 180.0;
            servo.angle(degrees);
            await obniz.wait(400);
            degrees = 90.0;
            servo.angle(degrees);
            await obniz.wait(400);
        }else {
            // スイッチが押されていない状態
            degrees = 90.0;
            console.log('released');
        }
    }
}

距離センサーでLEDの色を変えるところは、setTimeoutでプログラムのみ停止、サーボモーターはawait obniz.wait(400)で止めてあげると、ちょうど良い挙動でした。

配線

必要に応じて参照ください。

IMG_2362.JPG

距離センサーは0~3に接続
コードにもありますが配線の順番に注意してください。


    const rgbled = obniz.wired("WS2811", {gnd: 4, vcc: 5, din: 6}); 
    //温度センサー
    const tempsens = obniz.wired('LM60', { gnd: 7, output: 8, vcc: 9 });

LED,温度センサーは配線を間違えると、破損や怪我につながるので、慎重に確認してください。

今後の展望|LINEbotとの連携

現状では、こちらの声をobnizに届けることができておりませんので、LINE Messaging APIと連携し、L INE上で会話できるようにしたいと考えました。
現状実装できていないため、折り畳みとさせていただきますが、興味ある方はお読みいただければ幸いです。

サンプルコード
// ########################################
//          obniz処理部分
//  Obniz_ID:自分のobniz ID(XXXX-XXXX)
// ########################################
const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID');
// obnizと接続確立したとき
obniz.onconnect = async () => {
    const rgbled = obniz.wired("WS2811", {gnd: 4, vcc: 5, din: 6}); // io0 is connected to anode, io1 is cathode 
    const getObnizTemp = async () => {
    const tempsens = obniz.wired('LM60', { gnd: 7, output: 8, vcc: 9 });
    const temp = await tempsens.getWait();
        if(temp < 15.0) {
            rgbled.rgb(0, 0, 255);
            console.log(`今日は寒いね。${temp}度しかないよ。`)
            await obniz.wait(5000);
        } else if(temp < 20.0) {
            rgbled.rgb(0, 255, 0);
            console.log(`今日${temp}度。過ごしやすいね!`)
            await obniz.wait(5000);
        } else {
            rgbled.rgb(255, 0, 0);
            console.log(`${temp}度。暑いねー。熱中症にならないように家の中でだらだらしないと!`)
            await obniz.wait(5000);
        }  
        return temp;
    }     
}
// ########################################
//          LINEBot イベント処理部分
//  channelSecret:LINE Developers → チャネル基本設定 → チャネルシークレット
//  channelAccessToken:LINE Developers → Messaging API設定 → チャネルアクセストークン(長期)
//  ターミナルで `ngrok http 3000` 実行後、発行されたURLをWebhook URLとして設定するのを忘れずに
//  「検証」ボタンをクリックするとターミナルにエラーが出ますがここでは問題ありません(検証イベントのハンドリングをしていないため)
// ########################################
const config = {
    channelSecret: 'channelSecret',
    channelAccessToken: 'channelAccessToken'    
};
const line = require('@line/bot-sdk');
const client = new line.Client(config);
// ExpressからMessaging APIイベントを渡されて処理するところ
const handleEvent = async (event) => {
    // テキストメッセージ以外を受信したときは何も行わずresolveを返す
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // テキストメッセージを受信したとき
    if (event.message.text === '温度教えて') {
        // 待ってねというメッセージを「リプライ」で先に返す
        await client.replyMessage(event.replyToken, {
            type: 'text',
            text: '.oO(ちょっと調べてきますねー。)'
        });
        // obnizの温度センサから値をとってくる(ブロッキング・時間のかかる処理で一旦ここで止まる)
        const temp = await getObnizTemp();
        // tempが取得できたらそれを含めたメッセージを「プッシュ」で送信する
        client.pushMessage(event.source.userId, {
            type: 'text',
            text: '今の温度は' + temp + '度ですねー。',
        });
    } else {
        // メッセージの中身が「温度教えて」以外だったとき
        client.replyMessage(event.replyToken, {
            type: 'text',
            text: '「温度教えて」と話しかけてね!'
        });
    }
    // resolveを返す
    return Promise.resolve(null);
}



// ########################################
//          Expressサーバー部分
// ########################################
const express = require('express');
const PORT = process.env.PORT || 3000;
const app = express();
// 「(サーバーURL)/webhook」にアクセス(LINEサーバーからのWebhook)があったとき
app.post('/webhook', line.middleware(config), (req, res) => {
    // 受信したイベントをターミナルに表示
    console.log(req.body.events);
    // イベントをhandleEventに渡して1つずつ処理
    Promise.all(
        req.body.events.map(handleEvent)
    ).then(
        result => res.json(result)
    );
});
// PORT番号のポートでサーバーを開始
app.listen(PORT);
console.log('express runnning: PORT =', PORT);

本文中にありました、センサーでの温度取得+LED点灯に加えて、Line上で温度を尋ねると、そのデータを返してくれるように作成しておりましたが、実装できておりません。
温度を取得する関数として定義しているgetObnizTempが、obniz.onconnectの中でしか動かず、Line上で参照しようとしても参照できず、一方で、obniz.onconnectの外に出すと、データの取得はできるのですが、LEDの点灯などが実行されないというジレンマに陥っています。

以上、読んでみて少しでも面白いと思っていただければ幸いです。
10
2
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
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?