LoginSignup
5
3

More than 5 years have passed since last update.

お片付け応援システムを作る

Last updated at Posted at 2017-12-03

はじめに

ものの配置が決まっている場合、使ったら戻すというルールになっていることが多いです。
しかし、ついつい戻すのを忘れたり、面倒だったりするわけです。
そこで、誰かに背中を押してもらえたら、片付けへの意欲がわくんじゃないかという発想で考えてみました。
基本的には子供のお片付けを想定しています。

作りたいもの

特定の時間に定位置にものがないと判断された場合、「片付けよう」と応援してくれるシステム

用意するもの

-距離センサGP2Y0E03
-ESP-WROOM32(ESP32-DevKitC)
-RaspberryPi
-スピーカー

やり方

⒈ESP-WROOM-32に距離センサを接続し、特定の時間に片付け場所から物体までの距離を測定する。
⒉距離が閾値を超えている場合、片付けられていないと判断し、RaspberryPiにHTTP POSTする。
⒊RaspberryPiはHTTP POSTを受けて、「片付けよう」としゃべる。

完成イメージ

86CC6E27-C772-470F-966E-CE2FA51CD35F.png

作る

ESP-WROOM-32の処理

ソースコード全体はgithubに置いてあります。
ビルドにはESP-IDFが必要になります。

センサから距離を取得する

ソースコードはsensor.cです。
距離センサをESP-WROOM-32に接続して、距離の測定を行います。
以前に書いた距離センサで防犯システムをDIYと同じ接続です。

RaspberryPiに通知する

ソースコードはhttp_request.cです。
距離センサで片付けられていない状態を検出した場合、ESP-WROOM-32からRaspebrryPiに対してHTTP POSTを行います。

片付け状態を確認する

片付け状態は毎日20時に確認を開始します。距離センサから30cm以内に物体がない場合を片付けられていない状態とします。
片付けが行われない場合、1分毎に片付け応援メッセージが流れます。

#include "http_request.h"
#include "sensor.h"
#include "nvs_flash.h"
#include <time.h>
#include <sys/time.h>
#include "esp_log.h"
#include "esp_sleep.h"
#include "esp_wifi.h"
#include "ntptime.h"

#define EMPTY_DISTANCE  30
#define CHECK_HOUR      20

static const char *TAG = "main";

esp_err_t monitor(bool *need_check)
{
    esp_err_t ret;

    ret = reset_sensor();
    if(ret != ESP_OK){
        ESP_LOGI(TAG, "Sensor reset failed!");
        return ret;
    }

    int distance;
    ret = read_distance(&distance);
    if (ret != ESP_OK) {
        ESP_LOGI(TAG, "data_l:No ack, sensor not connected...skip...");
        return ret;
    }

    if(distance >  EMPTY_DISTANCE){
        ESP_LOGI(TAG, "not declutter...");
        http_post_task();
    }else{
        ESP_LOGI(TAG, "decluttered");
        *need_check = false;
    }

    return ESP_OK;
}

void app_main()
{
    ESP_ERROR_CHECK( nvs_flash_init() );
    init_sensor();
    initialise_wifi();

    time_t now;
    struct tm timeinfo;
    char strftime_buf[64];

    ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
    obtain_time();
    // update 'now' variable with current time
    time(&now);

    time_t t = now + (3600 * 9);
    localtime_r(&t, &timeinfo);
    strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
    ESP_LOGI(TAG, "The current date/time in JST-2 is: %s", strftime_buf);

    bool need_check = false;
    int check_start_hour = CHECK_HOUR;
    int check_start_day = timeinfo.tm_mday;

    while(true){
         //get time
        time(&now);
        t = now + (3600 * 9);
        localtime_r(&t, &timeinfo);
        strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
        ESP_LOGI(TAG, "The current date/time in JST-2 is: %s", strftime_buf);

        if(timeinfo.tm_mday == check_start_day && timeinfo.tm_hour >= check_start_hour){ 
            need_check = true;
            check_start_day++;
        }

        if(need_check==true){
            esp_err_t ret = monitor(&need_check);
            if(ret != ESP_OK){
                ESP_LOGI(TAG, "Device error occured!!");
                return;
            }
        }

        //sleep 1 minute
        esp_sleep_enable_timer_wakeup(1000000LL * 60);
        esp_light_sleep_start();
    }
}

ソースコードはmain.cにもあります。
monitor関数で片付け状態を検出し、片付けられていない場合、RaspberryPiに通知を行います。
main関数ではPowerOn直後にNTPから時刻を取得し、日本時間で毎日20時に片付け状態確認を行います。
省電力のため、デバイスをsleepさせながら、1分ごとに時刻を更新しています。
省電力を考えるなら、ここは毎日20時に起きるようにタイマーを仕掛けたほうがいいと後から思いました。
NTP時刻の取得処理はntptime.cです。

RaspberryPiの処理

通知を受け取り、喋る処理を実行する

ソースコードはindex.phpです。
PHPでHTTP POSTメッセージを処理し、喋る処理を実行します。
上記は関係ない処理が入っているため、ここでの処理を抜き出すと以下のようになります。

index.php
<?php
function func_cheer(){
    exec('/home/pi/work/jtalk.sh "そろそろ片付けの時間だよ。頑張って片付けよう。"');
    return;
}

if($_POST['text'] == "decluttering"):
    func_cheer();
endif;
?>

RaspberryPiに喋らせる

音声出力はOpen JTalkを使用します。
JERRY WAREを参考に、インストールと設定を行いました。
スクリプトを実行することでRaspberryPiが喋るようにしておきます。

jtalk.sh
#!/bin/bash                                                                                                                         
tempfile=`tempfile`                                                                                                                 
option="-m /usr/share/hts-voice/mei/mei_normal.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow $tempfile"                  

echo "$1" | open_jtalk $option                                                                                                      
aplay -q $tempfile                                                                                                                  
rm $tempfile  

上記の参考サイトと同じです。
デフォルトの男性の声だと体育会系になってしまったので、女性の声に変えました。

注意点

実験でPHPから実行してみましたが、音が鳴りませんでした。
調べたところ、/dev/snd/のパーミッションが許可されていないようなので、
Apache2をAudioグループに入れておきます。(セキュリティ面はあまり考えていません)

sudo vi /etc/group
group
...
audio:x:29:pi,pulse,www-data
...

のようにします。私の環境ではApache2のユーザー名はwww-dataでした。
これでPHPで音声が出力されるようになりました。

テスト

ESP-WROOM-32 + 距離センサです。
572EA474-F44A-4737-B22A-77AFA8E6ECFE.jpeg

RaspberryPi + スピーカーです。
BB48B4B4-B683-4D85-BC9B-AAF0E2EB6260.jpeg

まず、片付けられていない状態で確認開始時間を迎えます。(時間はテスト用に変えています)
15756033-1777-4CEB-8F4E-B2E06FCCC5D9.png

するとRaspberryPiが応援してくれました。
E21A6BB6-7CB8-4F24-8425-B6D32B327007.png

よし、片付けだ。人形を元の場所に片付そう。
DB15D495-A7F4-416F-888A-41F40264DD64.png

何も言わなくなった。
8F8357AD-84B8-46F9-BF65-47A298395734.png
ちょっと寂しいので、褒めメッセージを仕込んだ方がいいと思いました。
時間があれば追加します。

おわりに

何かものを置いておけば、黙ってしまうのが欠点です。

5
3
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
5
3